2017-06-01 8 views
1

JScrollPaneにはJTextAreaがあります。このメッセージにはdisplay.append()というメッセージが追加されています。テキストを追加した後、スクロールバーの値を最大値に設定して自動的にスクロールさせようとしています。ただし、行が追加された直後にはgetVerticalScrollBar().getMaximum()の値は更新されません。 revalidate()repaint()updateUI()で強制的に更新を試みましたが、適切な機能が見つからないようです。Java Swing JScrollBarのサイズはいつ更新されますか?

MWE:

import java.awt.BorderLayout; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JScrollBar; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 

public class MessageDisplayPane extends JScrollPane { 
    private static final long serialVersionUID = 2025745714938834689L; 

    public static final int NUM_LINES = 5; 

    private JTextArea display; 
    private JScrollBar vertical = getVerticalScrollBar(); 

    public MessageDisplayPane() { 
     display = createTextArea(); 
     setViewportView(display); 
    } 

    private JTextArea createTextArea() { 
     JTextArea ta = new JTextArea(NUM_LINES, 0); 
     ta.setEditable(false); 
     ta.setLineWrap(true); 
     ta.setWrapStyleWord(true); 
     ta.setFont(new Font("Arial", Font.PLAIN, 12)); 
     ta.setBorder(BorderFactory.createEtchedBorder()); 
     return ta; 
    } 

    class EventListener implements ActionListener { 
     public void actionPerformed(ActionEvent e) { 
      new Thread() { 
       @Override 
       public void run() { 
        System.out.println(vertical.getMaximum()); 

        display.append("test\r\n"); 
        revalidate(); 
        repaint(); 
        updateUI(); 

        System.out.println(vertical.getMaximum()); 
        System.out.println(); 

        //vertical.setValue(vertical.getMaximum()); 
       } 
      }.start(); 
      } 
     } 

    public static void main(String[] args) { 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       MessageDisplayPane messagePane = new MessageDisplayPane(); 
       JButton button = new JButton("Display another line"); 

       frame.setSize(800, 300); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.getContentPane().add(button, BorderLayout.CENTER); 
       frame.getContentPane().add(messagePane, BorderLayout.SOUTH); 

       button.addActionListener(messagePane.new EventListener()); 

       frame.setVisible(true); 
      } 
     }); 
    } 

} 
+1

実行可能な例([SSCCE](http://sscce.org))を提供して問題を理解し、再現できるようにしてください。 –

+0

例を作成する過程で、デフォルトでは、テキストを追加するときにウィンドウがスクロールすることがわかりました。問題は、別のスレッドからテキストを追加するときに発生しないということです。 – Dimpl

答えて

1

可能な解決策は、あなたのテキストの最後(または最初)に何かキャレット位置を設定することができます。

textArea.setCaretPosition (textArea.getText().length()); // to scroll to the bottom 
textArea.setCaretPosition (0); // to scroll to the top 

を、私は同様の命令を使用キャレットの位置を0に設定し、スクロールバーが自動的に上にスクロールしたので、うまくいくはずです。

+0

私は前にこの解決策を見たと思います。私はeditableをfalseに設定していたのでうまくいかないと思っていましたが、そのトリックをするようです! – Dimpl

関連する問題