Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Управление положением скроллбара на JScrollPane


Автор: bjbj 11.12.2007, 09:21
Мне требуется некий визуальный компонент, предназначенный для вывода лога. События возникают в отдельном потоке и оставляют свои сообщения в этом компоненте. При этом, естественно, логи растут и нужна вертикальная полоса прокрутки. Проблема заключается в том, как заставить полосу прокрутки находится все время в самом нижнем положении, чтобы было видно последнее сообщение лога. Я использую JScrollEditor для непосредственного вывода лога (требуются средства HTML-разметки) и JScrollPane для создания прокрутки.
По идее надо использовать метод JScrollPane.getViewport().setViewPosition(...). Но почему-то это приводит к странному и неустойчивому поведению (полоса прокрутки занимает различные положения, но не всегда самое нижнее). Вот примерный код:

Код

import java.awt.Point;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;

public class Test {

    public static void main(String[] args) {
        TestFrame frame = new TestFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

class TestFrame extends JFrame {

    private JEditorPane logArea;
    private JScrollPane logScrollPane;
    
    public TestFrame() {
        setSize(200, 150);

        logScrollPane = new JScrollPane();
        logScrollPane.setBounds(0, 0, 200, 150);
        
        logArea = new JEditorPane();
        logArea.setContentType("text/html");
        
        logScrollPane.setViewportView(logArea);
        
        getContentPane().add(logScrollPane);
        
        new Thread(new LotLoader()).start();
    }
    
    class LotLoader implements Runnable {

        private String logString = "<html>";
        
        public void run() {
            int i = 0;
            while (!Thread.currentThread().isInterrupted() && i < 20) {
                i++;
                logString += i + "<br>";
                logArea.setText(logString);
                
                logScrollPane.getViewport().setViewPosition(
                        new Point(0, logArea.getHeight() - 150));
                
                try {
                    Thread.currentThread().sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
        
    }

}


Автор: dorogoyIV 11.12.2007, 13:47
Код

                logScrollPane.getViewport().setViewPosition(
                        new Point(0, logArea.getHeight() - 150));

замени на
Код

                logScrollPane.getViewport().setViewPosition(
                        new Point(0, logArea.getHeight() + 150));

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)