2015-10-08 93 views
0

讓我的JScrollPane自動更新並在動作偵聽器中滾動有點麻煩。有一個字母出現在Thread.sleep()類型的動畫中,但是一旦滾動條需要滾動(它在動作監聽器之後滾動)就不起作用。我想知道是否有人可以幫助我在評論//需要JSP(JScrollPane的)即時更新如何手動更新和滾動JScrollPane

謝謝,真的很感激一些幫助

public class MainGUI { 

public String appName = "Chat Assistant v1.3.3"; 
public MainGUI mainGUI; 
public JPanel mainPanel; 
public JScrollPane jsp; 
public JFrame newFrame = new JFrame(appName); 
public JButton sendMessage; 
public JTextField messageBox = new JTextField(30); 
public JTextArea chatBox; 
String username = "Evan"; 
public Random rand = new Random(); 
public Calendar cal= Calendar.getInstance(); 

//public MainEngine me = new MainEngine(); 

public String temp = ""; 
public String tempL = ""; 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      MainGUI mainGUI = new MainGUI(); 
      mainGUI.display(); 
     } 
    }); 
} 

public void display() { 
    mainPanel = new JPanel(); 
    mainPanel.setLayout(new BorderLayout()); 

    JPanel southPanel = new JPanel(); 
    southPanel.setBackground(Color.BLUE); 
    southPanel.setLayout(new GridBagLayout()); 

    messageBox.requestFocusInWindow(); 

    sendMessage = new JButton("Send Message"); 
    sendMessage.addActionListener(new sendMessageButtonListener()); 
    chatBox = new JTextArea(); 
    chatBox.setEditable(false); 
    chatBox.setFont(new Font("Arial", Font.PLAIN, 18)); 
    chatBox.setLineWrap(true); 
    jsp = new JScrollPane(chatBox); 
    jsp.setBorder(new LineBorder(Color.white, 7)); 

    mainPanel.add(jsp, BorderLayout.CENTER); 

    GridBagConstraints left = new GridBagConstraints(); 
    left.anchor = GridBagConstraints.LINE_START; 
    left.fill = GridBagConstraints.HORIZONTAL; 
    left.weightx = 512.0D; 
    left.weighty = 1.0D; 

    GridBagConstraints right = new GridBagConstraints(); 
    right.insets = new Insets(0, 10, 0, 0); 
    right.anchor = GridBagConstraints.LINE_END; 
    right.fill = GridBagConstraints.NONE; 
    right.weightx = 1.0D; 
    right.weighty = 1.0D; 

    southPanel.add(messageBox, left); 
    southPanel.add(sendMessage, right); 

    mainPanel.add(BorderLayout.SOUTH, southPanel); 

    newFrame.add(mainPanel); 
    newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    newFrame.setSize(720, 480); 
    newFrame.setVisible(true); 
    newFrame.setResizable(false); 
    newFrame.setLocationRelativeTo(null); 
    messageBox.requestFocusInWindow(); 
    messageBox.addKeyListener(new KeyListener()); 

    startup(); 
} 

public void startup() { 
    int h = cal.get(Calendar.HOUR_OF_DAY); 
    int n = rand.nextInt(2) + 1; 
    String message = ""; 
    chatBox.append("AIBot: "); 
    if (n == 1) 
     message = "Welcome back sir!"; 
    else if (n == 2) { 
     if ((h > 4) && (h < 11)) 
      message = "Good Morning sir, I hope you have a great day."; 
     else if ((h >= 11) && (h < 17)) 
      message = "Good Afternoon sir"; 
     else if ((h >= 17) && (h < 25)) 
      message = "Good Evening sir, how was your day?"; 
     else 
      message = "It's quite late, you should get some rest sir"; 
    } 
    try { 
     Runtime.getRuntime().exec(new String[] { "say" , "" + message }) ; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    messageBox.paintImmediately(messageBox.getBounds()); 
    sendMessage.paintImmediately(sendMessage.getBounds()); 
    messageBox.requestFocusInWindow(); 
    for (int i = 0; i < message.length(); i++) { //Appends 1 letter at a time, "animation", voice is already executed 
     try {Thread.sleep(35);} catch (InterruptedException e) {e.printStackTrace();} 
     chatBox.append(message.substring(i, i+1)); 
     chatBox.setCaretPosition(chatBox.getDocument().getLength()); 
     chatBox.paintImmediately(chatBox.getBounds()); 
    } 
    chatBox.append("\n\n"); 
    messageBox.setText(""); 
} 

public class KeyListener extends KeyAdapter { 
    @Override 
     public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_ENTER) { 
      sendMessage.doClick(); 
     } 
    } 
} 

public class sendMessageButtonListener implements ActionListener { 
    public void actionPerformed(ActionEvent event) { 
     if (messageBox.getText().length() < 1) { 
      // do nothing 
     } else if (messageBox.getText().equals(".clear")) { 
      chatBox.setText("Cleared all messages\n"); 
      messageBox.setText(""); 
     } else { 
      chatBox.append("" + username + ": "); 
      chatBox.append(messageBox.getText() + "\n\n"); 
      temp = messageBox.getText(); 
      tempL = temp.toLowerCase(); 
      messageBox.setText(""); 
      chatBox.setCaretPosition(chatBox.getDocument().getLength()); 
      chatBox.paintImmediately(chatBox.getBounds()); 
     } 
     messageBox.requestFocusInWindow(); 
     chatBox.append("AIBot: "); 
     //String message = me.disperse(tempL) + " "; 
     String message = "TEST................"; 
     if (message.contains("username")) { 
      String[] t = message.split("username"); 
      message = t[0] + username + t[1]; 
     } 
     chatBox.setCaretPosition(chatBox.getDocument().getLength()); 
     chatBox.paintImmediately(chatBox.getBounds()); 
     //Need jsp (JScrollPane) to instantly update 
     message += ""; 
     try { 
      Runtime.getRuntime().exec(new String[] { "say" , "" + message }) ; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     for (int i = 0; i < message.length(); i++) { //Appends 1 letter at a time, "animation", voice is already executed 
      try {Thread.sleep(35);} catch (InterruptedException e) {e.printStackTrace();} 
      chatBox.append(message.substring(i, i+1)); 
      chatBox.paintImmediately(chatBox.getBounds()); 
      chatBox.setCaretPosition(chatBox.getDocument().getLength()); 
     } 
     chatBox.append("\n\n"); 

     chatBox.setCaretPosition(chatBox.getDocument().getLength()); 
    } 
} 
} 

回答

1

不要使用Thread.sleep(...)。這導致事件調度線程(EDT)進入休眠狀態,這意味着直到所有代碼執行完畢,GUI才能重新進行自我刷新。有關更多信息,請參閱Concurrency in Swing的Swing教程部分。

相反,您可以使用SwingTimer來安排動畫。

或者如果您不想使用計時器,您可以使用SwingWorker,正如在併發教程中討論的那樣。

另外:

  1. 不要使用KeyListener的文本字段來處理Enter鍵。您可以將一個ActionListener添加到文本字段。當按下Enter鍵時,監聽器將自動被調用。

  2. 請勿立即使用paint。一旦你擺脫了Thread.sleep(),GUI將正常重繪自己。

+0

謝謝!這真的很有用:)現在,動畫除了第一次迭代之外都適用於所有內容,但我可以自己調試! – EcstaticException