简体   繁体   English

如何防止jscrollpane滚动到底部?

[英]how to prevent jscrollpane from scrolling to the bottom?

I have JTextPane (log) inside JScrollPane (logScrollPane) element. 我在JScrollPane(logScrollPane)元素中有JTextPane(日志)。 Log's content is set to "text/html". 日志的内容设置为“ text / html”。

I created a method that appends this log which looks like this: 我创建了一个添加此日志的方法,如下所示:

public void appendLog(String someHTMLText)
  {
    HTMLDocument doc = (HTMLDocument) log.getDocument();
    HTMLEditorKit editorKit = (HTMLEditorKit) log.getEditorKit();
    try
      {
        editorKit.insertHTML(doc, doc.getLength(), someHTMLText, 0, 0, null);
      }
    catch (BadLocationException | IOException ex)
      {
        // handle exceptions
      }
  }

I want to improve this method and force logScrollPane's VerticalScrollBar to move_to_the_bottom/stay_at_it's_position depending on additional boolean argument. 我想改进此方法,并根据其他布尔参数将logScrollPane的VerticalScrollBar强制移动到move_to_the_bottom / stay_at_it's__position。 Final method should look like this: 最终方法应如下所示:

public void appendLog(String someHTMLText, boolean scroll)
  {
    if(scroll)
     {
        /* 
         * append log and set VerticalScrollBar to the bottom by
         * log.setCaretPosition(log.getDocument().getLength());
        */
     }
     else
     {
        // append log BUT make VerticalScrollBar stay at it's previous position
     }
  }

Any suggestions? 有什么建议么? :) :)

Here is something similar to what I did when I wanted to achieve this. 这与我想要实现此目标时所做的类似。 The key is to alter the behavior of scrollRectToVisible . 关键是要更改scrollRectToVisible的行为。

public class Docker extends JFrame {

    boolean dockScrollbar = true;
    MYTextPane textPane = new MYTextPane();
    JScrollPane sp = new JScrollPane(textPane);

    Docker() {

        JCheckBox scrollbarDockCB = new JCheckBox("Dock scrollbar");
        scrollbarDockCB.addItemListener(new DockScrollbarListener());
        scrollbarDockCB.setSelected(true);

        JButton insertText = new JButton("Insert text");
        insertText.addActionListener(new TextInserter());

        getContentPane().add(insertText, BorderLayout.PAGE_START);
        getContentPane().add(sp);
        getContentPane().add(scrollbarDockCB, BorderLayout.PAGE_END);

        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    class MYTextPane extends JTextPane {

        MYTextPane() {

            setEditorKit(new HTMLEditorKit());
        }

        @Override
        public void scrollRectToVisible(Rectangle aRect) {

            if (dockScrollbar)
                super.scrollRectToVisible(aRect);
        }

        void insertText(String msg) {

            HTMLEditorKit kit = (HTMLEditorKit) getEditorKit();
            HTMLDocument doc = (HTMLDocument) getDocument();
            try {
                kit.insertHTML(doc, doc.getLength(), msg, 0, 0, null);
            } catch (BadLocationException | IOException e1) {
                e1.printStackTrace();
            }
            setCaretPosition(doc.getLength());
        }
    }

    class TextInserter implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            textPane.insertText("AAA\n");
        }
    }

    class DockScrollbarListener implements ItemListener {

        @Override
        public void itemStateChanged(ItemEvent e) {

            if (e.getStateChange() == ItemEvent.SELECTED) {
                dockScrollbar = true;
                JScrollBar sb = sp.getVerticalScrollBar();
                sb.setValue(sb.getMaximum());
            }
            else if (e.getStateChange() == ItemEvent.DESELECTED)
                dockScrollbar = false;
        }
    }

    public static void main(String[] args) {

        new Docker();
    }
}

Notes : 注意事项

  • I made the docking set to false when you manually scroll in my code, you can add it here too. 当您手动滚动代码时,我将对接设置为false,也可以在此处添加对接。 by adding a mouse listener to the vertical scrollbar. 通过将鼠标侦听器添加到垂直滚动条。
  • I have boolean dockScrollbar as a field of the text pane because I have more than one. 我有boolean dockScrollbar作为文本窗格的一个字段,因为我有多个。
  • I don't have a field for the JScrollPane , I get it through the text pane. 我没有JScrollPane的字段,而是通过文本窗格获取的。

I've never tried it on a JEditorPane but you should be able to use the caret update policy to control this. 我从未在JEditorPane上尝试过它,但是您应该能够使用caret update policy来控制它。

Check out Text Area Scrolling for more information. 请查看文本区域滚动以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM