【发布时间】:2015-11-16 00:36:47
【问题描述】:
我为了开发一个摇摆应用程序,我使用的是 MVC 模式的简化版本,其中控制器在两个方向上都介于视图和模型之间:
- 当用户与摇摆控件交互时,如果此交互需要访问模型,那么摇摆控件引发的事件将调用适当的控制器方法;
- 当在模型更新后应该更新视图时,控制器会调用视图的一个或多个公共方法。
一个复杂的应用程序可能会请求不同的线程运行:例如,如果你必须在磁盘上写入一个文件,你可以启动一个后台线程,在文件写入结束时,这个线程应该发送一个通知来查看通过控制器。在这种情况下,可能会发生多个线程想要刷新视图,所以我认为应该以某种方式处理这个问题。
我从this answer获得灵感,为了写出下面SSCCE的方法appendText和updateLastText。
public class NewJFrame extends javax.swing.JFrame {
private volatile String lastText;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new JScrollPane();
jTextArea1 = new JTextArea();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jTextArea1.setEditable(false);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
getContentPane().add(jScrollPane1, BorderLayout.CENTER);
pack();
}// </editor-fold>
// Variables declaration - do not modify
private JScrollPane jScrollPane1;
private JTextArea jTextArea1;
// End of variables declaration
/**
*
* @param text
*/
public void appendText(final String text) {
updateLastText(text);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jTextArea1.append(String.format("%s\n", lastText));
}
});
}
/**
*
* @param text
*/
private synchronized void updateLastText(String text) {
lastText = text;
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
final NewJFrame frame = new NewJFrame();
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame.setVisible(true);
}
});
Thread counter = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
frame.appendText((new Date()).toString());
}
}
};
counter.start();
}
}
上述解决方案似乎工作正常,那么我应该使用相同的技术来更新 UI 的其他摆动组件吗?还是有更紧凑的解决方案?
【问题讨论】:
标签: java multithreading swing model-view-controller