2012-12-27 60 views
3

我遇到了一个问题:我想在JEditorPane中使用内部锚点<a name="x">和链接<a href="#x">跳转到JEditorPane中的内部锚点

窗格的内容不是从资源加载的,而是作为字符串动态创建并可用的。

如何让我的JEditorPane滚动到正确的位置? (在示例中它应该滚动到顶部) 侦听器只捕获null,这会增加该问题。

这里是我的SSCCCE:

public static void main(final String[] args) { 
    final JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
    f.setTitle("JEditorPane Test"); 

    final String text = "<html><body><a name='link1'>test</a>some text<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />some more text<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />some more text<a href='#link1'>jump to top</a></body></html>"; 

    final JEditorPane ep = new JEditorPane(); 
    ep.setContentType("text/html"); 
    ep.setText(text); 
    ep.setEditable(false); 
    ep.addHyperlinkListener(new HyperlinkListener() { 
     @Override public void hyperlinkUpdate(final HyperlinkEvent pE) { 
      if (HyperlinkEvent.EventType.ACTIVATED == pE.getEventType()) 
       System.out.println("ep link click: " + pE.getURL()); 
     } 
    }); 

    final JScrollPane sp = new JScrollPane(ep); 
    f.add(sp); 

    f.setBounds(200, 200, 400, 400); 
    f.setVisible(true); 
} 

回答

6

好吧,我终于得到这个解决。

我一直在用scrollToReference()进行测试,但它以某种方式没有奏效。 然后,我玩HTML解析和锚点和插入和setCaretPosition()有时只有工作。 然后出于纯粹的巧合,我再次在我的代码中包含scrollToReference(),并且滚动突然发生了......并且仍然完美无缺!

这里的工作代码:

public static void main(final String[] args) { 
    final JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
    f.setTitle("JEditorPane Test"); 

    final String text = "<html><body>xyz<br /><br /><br />lol <a name='link1'>test</a>some text<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />some more text<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />some more text<a href='#link1'>jump to top</a></body></html>"; 

    final JEditorPane ep = new JEditorPane(); 
    ep.setContentType("text/html"); 
    ep.setText(text); 
    ep.setEditable(false); 
    ep.addHyperlinkListener(new HyperlinkListener() { 
     @Override public void hyperlinkUpdate(final HyperlinkEvent pE) { 
      if (HyperlinkEvent.EventType.ACTIVATED == pE.getEventType()) { 
       String desc = pE.getDescription(); 
       if (desc == null || !desc.startsWith("#")) return; 
       desc = desc.substring(1); 
       ep.scrollToReference(desc); 
      } 
     } 
    }); 

    final JScrollPane sp = new JScrollPane(ep); 
    f.add(sp); 
    f.setBounds(200, 200, 400, 400); 
    f.setVisible(true); 
} 
+0

哦,是的,这并不明显,但JEditorPane控制了它的绕圈JScrollPane进行滚动。 – JayC667

+0

顺便说一句,有没有什么办法可以标记为已解决?除了手动编辑标题? – JayC667

+1

是的,选择你自己的答案为接受(或解决问题的答案),这是如何标记为在StackOverflow中解决。 – PhoneixS

1

你可以做到这一点是这样的:

import java.awt.Point; 
import java.util.logging.Logger; 
import javax.swing.JEditorPane; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JViewport; 
import javax.swing.SwingUtilities; 
import javax.swing.event.HyperlinkEvent; 
import javax.swing.event.HyperlinkListener; 

public class PaneWithScroll { 
    private static final String TEXT = 
     "<html>" 
     + "<head>" 
     + "</head>" 
     + "<body>" 
      + "<p><a href=\"#top\">Go top</a></p>" 
     + "</body>" 
     + "</html>"; 
    private static final String TOP = "#top"; 

    public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame frame = new PaneWithScrollFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     } 
    }); 
    } 

    private static class PaneWithScrollFrame extends JFrame { 
    private PaneWithScrollFrame() { 
     super.setName("Pane With Scroll"); 
     this.addComponents(); 
     super.setSize(640, 480); 
    } 

    private void addComponents() { 
     JEditorPane editorPane = new JEditorPane(); 
     editorPane.setContentType("text/html"); 
     editorPane.setEditable(false); 
     editorPane.setText(TEXT); 

     final JScrollPane scrollpane = new JScrollPane(editorPane); 

     editorPane.addHyperlinkListener(new HyperlinkListener() { 
     @Override 
     public void hyperlinkUpdate(HyperlinkEvent e) { 
      if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) { 
      String description = e.getDescription(); 
      if (TOP.equals(description)) { 
       JViewport viewport = scrollpane.getViewport(); 
       viewport.setViewPosition(new Point(0, 0)); 
      } 
      } 
     } 
     }); 

     super.add(scrollpane); 
    } 
    } 
} 
+0

非常感谢您对这个输入,它已经帮助了一点。但我正在寻找更通用的解决方案。 感谢您的文章,我实际上找到了一个,会发布在下面。 – JayC667