2017-06-01 82 views
1

我有一個JTextAreaJScrollPane,我附加郵件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

我想我以前見過這個解決方案。我認爲這是行不通的,因爲我已經將可編輯設置爲假,但它似乎有訣竅! – Dimpl