【发布时间】:2016-01-10 02:31:09
【问题描述】:
我的项目包含两个部分:一个逻辑模块和一个 gui 界面。 两者都将他们的引用发送给其他人。
当用户发送消息时,我有一个 Key Listener。在这个监听器中,我在逻辑之前调用相同的 gui 更改,在逻辑之后调用相同的更改。 问题是这两个更改将在执行结束时同时显示。
如何强制实时更新GUI?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main {
// Init DecisionEngine and GUIApplication
private static final Logic _logic = new Logic();
private static final GUI _gui = new GUI();
public static void main(String[] args) {
// Set DecisionEngine reference in GUIApplication and viceversa
_gui.setLogicReference(_logic);
_logic.setGUIRefecence(_gui);
// User send a message
_gui.textInput.addKeyListener(new KeyListener(){
@Override public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
_gui.somethingChaged1();// CHANGE 1 GUI
_logic.thinking();// LOGIC PROCESSING (3sec)
_gui.somethingChaged2();// CHANGE 2 GUI
e.consume();// Stopping adding an Enter after message
}
}
@Override public void keyTyped(KeyEvent e) {}
@Override public void keyReleased(KeyEvent e) {}
});
}
private static class Logic {
GUI gui_ref;
public Logic() {}
private void setGUIRefecence(GUI _gui) {gui_ref = _gui;}
private void thinking() {
try {Thread.sleep(3000);} catch (InterruptedException ex) {}
}
}
private static class GUI {
Logic logic_ref;
private JFrame frame;
public JTextArea textInput;
private JLabel isTyping;
public GUI() {
frame = new JFrame();
textInput = new javax.swing.JTextArea(5, 20);
isTyping = new JLabel("Normal mode");
frame.setSize(new Dimension(200,300));
frame.add(textInput, BorderLayout.PAGE_START);
frame.add(isTyping, BorderLayout.CENTER);
frame.revalidate();
frame.repaint();
frame.setVisible(true);
}
private void setLogicReference(Logic _logic) {logic_ref = _logic;}
private void somethingChaged1() {isTyping.setText("loading...");System.out.println("status changed in 'loading...'");}
private void somethingChaged2() {isTyping.setText("is done.");System.out.println("status changed in 'is done.'");}
}
}
【问题讨论】:
-
发布MCVE。请务必将您的代码复制粘贴到新项目,并确保在将其发布到此处之前编译并运行。
-
private static final logic _logic = new Logic();不会编译。此外,不要在 Java 中的变量名中使用下划线。 -
@Adrian user1803551 完全正确,因为你的代码中第一行的大小写不一致,这不会编译。据我所知,您的程序有效;这是你的全部代码吗?
-
作为一般规则,避免使用
KeyListener,而是使用Key Bindings API。听起来你几乎屏蔽了 EDT -
try {Thread.sleep(3000);} catch (InterruptedException ex) {}..你想知道为什么它会冻结?!? @MadProgrammer 是对的。不要阻塞 EDT(事件调度线程)。发生这种情况时,GUI 将“冻结”。有关详细信息和修复,请参阅 Concurrency in Swing。
标签: java multithreading swing