Java 跳转到JEditorPane中的内部锚点

Java 跳转到JEditorPane中的内部锚点,java,html,swing,hyperlink,jeditorpane,Java,Html,Swing,Hyperlink,Jeditorpane,我有一个问题:我想使用一些内部锚文本; 最终绝地窗格ep=新绝地窗格(); ep.setContentType(“文本/html”); ep.setText(文本); ep.setEditable(假); ep.addHyperlinkListener(新的HyperlinkListener(){ @覆盖公共无效hyperlinkUpdate(最终HyperlinkEvent pE){ 如果(HyperlinkEvent.EventType.ACTIVATED==pE.getEventType(

我有一个问题:我想使用一些内部锚
文本








































; 最终绝地窗格ep=新绝地窗格(); ep.setContentType(“文本/html”); ep.setText(文本); ep.setEditable(假); ep.addHyperlinkListener(新的HyperlinkListener(){ @覆盖公共无效hyperlinkUpdate(最终HyperlinkEvent pE){ 如果(HyperlinkEvent.EventType.ACTIVATED==pE.getEventType()) System.out.println(“ep链接点击:+pE.getURL()); } }); 最终JScrollPane sp=新JScrollPane(ep); f、 添加(sp); f、 立根(200200400400); f、 setVisible(真); }
您可以这样做:

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);
    }
  }
}
导入java.awt.Point;
导入java.util.logging.Logger;
导入javax.swing.JEditorPane;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JViewport;
导入javax.swing.SwingUtilities;
导入javax.swing.event.HyperlinkEvent;
导入javax.swing.event.HyperlinkListener;
公共类窗格滚动{
私有静态最终字符串文本=
""
+ ""
+ ""
+ ""
+“

” + "" + ""; 私有静态最终字符串TOP=“#TOP”; 公共静态void main(字符串[]args){ SwingUtilities.invokeLater(新的Runnable(){ @凌驾 公开募捐{ JFrame frame=新的PaneWithScrollFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } 私有静态类PaneWithScrollFrame扩展了JFrame{ 私有PaneWithScrollFrame(){ super.setName(“带卷轴的窗格”); 这是addComponents(); 超级设置大小(640480); } 私有void addComponents(){ JEditorPane editorPane=新的JEditorPane(); setContentType(“text/html”); editorPane.setEditable(false); editorPane.setText(文本); 最终JScrollPane滚动窗格=新JScrollPane(editorPane); addHyperlinkListener(新的HyperlinkListener(){ @凌驾 公共无效hyperlinkUpdate(HyperlinkEvent e){ if(HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())){ String description=e.getDescription(); if(顶部等于(说明)){ JViewport viewport=scrollpane.getViewport(); viewport.setViewPosition(新点(0,0)); } } } }); super.add(滚动窗格); } } }
好的,我终于解决了这个问题

我一直在使用
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><a name='link1'>test</a>some text<br /><a href='#thisisbottom'>down</a><br /><br /><br /><br /><br /><br /><br /><br /><br /><a name='mid1'></a>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>] <br /> or jump to <a name='thisisbottom' href='#mid1'>center</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("JEditorPane link click: url='" + pE.getURL() + "' description='" + pE.getDescription() + "'");
                String reference = pE.getDescription();
                if (reference != null && reference.startsWith("#")) { // link must start with # to be internal reference
                    reference = reference.substring(1);
                    ep.scrollToReference(reference);
                }
            }
        }
    });

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

    f.setBounds(200, 200, 400, 400);
    f.setVisible(true);
}
publicstaticvoidmain(最终字符串[]args){
最终JFrame f=新JFrame();
f、 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f、 setTitle(“绝地窗格试验”);
最终字符串文本=“











]
或跳转到”; 最终绝地窗格ep=新绝地窗格(); ep.setContentType(“文本/html”); ep.setText(文本); ep.setEditable(假); ep.addHyperlinkListener(新的HyperlinkListener(){ @覆盖公共无效hyperlinkUpdate(最终HyperlinkEvent pE){ 如果(HyperlinkEvent.EventType.ACTIVATED==pE.getEventType()){ System.out.println(“JEditorPane链接点击:url='”+pE.getURL()+“'description='”+pE.getDescription()+”); 字符串引用=pE.getDescription(); 如果(reference!=null&&reference.startsWith(“#”){//链接必须以#开头才能作为内部引用 reference=reference.substring(1); ep.滚动参考(参考); } } } }); 最终JScrollPane sp=新JScrollPane(ep); f、 添加(sp); f、 立根(200200400400); f、 setVisible(真); }
非常感谢您的输入,它已经起到了一点作用。但我正在寻找一个更通用的解决方案。Thanx到您的帖子,我实际上找到了一个,将在下面发布。不要求转到顶部,但指向任何锚链接哦,是的,这并不明显,但JEditorPane控制了它的排序JScrollPane以进行滚动。顺便问一下,有什么方法可以将此标记为已解决?而不是手动编辑标题?是,选择您自己的答案作为已接受(或解决问题的答案),这是在StackOverflow中标记为已解决的方式。我这边的快速评论:由于某种原因,旧代码似乎不再包含滚动代码。我现在使用多个链接和滚动更新了答案。我遇到了一个问题,单击链接后光标无法从手上恢复。添加行
setCursor(editorKit.getDefaultCursor());
修复了它。
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 /><a href='#thisisbottom'>down</a><br /><br /><br /><br /><br /><br /><br /><br /><br /><a name='mid1'></a>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>] <br /> or jump to <a name='thisisbottom' href='#mid1'>center</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("JEditorPane link click: url='" + pE.getURL() + "' description='" + pE.getDescription() + "'");
                String reference = pE.getDescription();
                if (reference != null && reference.startsWith("#")) { // link must start with # to be internal reference
                    reference = reference.substring(1);
                    ep.scrollToReference(reference);
                }
            }
        }
    });

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

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