2015-10-08 3 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), что означает, что графический интерфейс не может перерисовываться до тех пор, пока весь код не завершит выполнение. Прочтите раздел из руководства Swing по телефону Concurrency in Swing для получения дополнительной информации.

Вместо этого вы можете использовать SwingTimer, чтобы запланировать анимацию.

Или, если вы не хотите использовать таймер, вы можете использовать SwingWorker, как описано в учебном пособии по параллелизму.

также:

  1. Не используйте KeyListener на текстовое поле для обработки клавиши Enter. Вы можете просто добавить ActionListener в текстовое поле. Слушатель автоматически вызывается при нажатии клавиши Enter.

  2. Не используйте paintImmediately. Как только вы избавитесь от Thread.sleep(), GUI будет перерисовываться как обычно.

+0

Спасибо! Это было действительно полезно :) Анимация теперь работает на всех, кроме первой итерации, но я смогу сама ее отладить! – EcstaticException

Смежные вопросы