我想问一下,如果我可以运行Thread,如果发生某些事件,发送信号和一些摆动组件将捕获信号。 像这样:
public class MyThread extends Thread {
String today = "???";
@Override
public void run() {
if (today.equals("monday")) {
// send signal
}
}
}
public class MyPanel extends JPanel {
// catching signals and if signal is catched change background color
}
编辑: 我试过这个,但它不起作用。
public class MyThread extends Thread {
@Override
public void run() {
SwingWorker worker = new SwingWorker<String, String>() {
@Override
protected String doInBackground() throws Exception {
System.out.println("doInBackground");
publish("doInBackgroundPublish");
firePropertyChange("firePropertyChange1", "oldValue1", "newValue1");
return "doInBackground return";
}
@Override
protected void process(List<String> chunks) {
super.process(chunks);
firePropertyChange("firePropertyChange2", "oldValue2", "newValue2");
}
};
worker.execute();
}
}
public class MyPanel extends JPanel {
public class SWListen implements PropertyChangeListener, Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("SWListen update");
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("SWListen propertyChange");
}
}
public MyPanel {
addPropertyChangeListener(new SWListen());
}
}
答案 0 :(得分:2)
SwingWorker
是一个自包含的“线程”(为了论证),这意味着它将创建并启动它自己的Thread
,doInBackground
将被调用。
doInBackground
应“做某事”并使用中间值调用publish
(假设您希望在结尾处生成一个整体值,否则,它只会生成一个值)
将来某个时候会调用process
。在EDT的上下文中调用此方法,从而可以安全地从内部更新UI。
您可以通过多种方式“通知”更改的UI,大多数都属于“观察者模式”的类别。
例如......
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JLabel label = new JLabel("...");
add(label);
TickerWorker worker = new TickerWorker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt.getPropertyName());
if ("counter".equals(evt.getPropertyName())) {
long value = (long) evt.getNewValue();
label.setText(Long.toString(value));
}
}
});
worker.execute();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class TickerWorker extends SwingWorker<Void, Long> {
@Override
protected Void doInBackground() throws Exception {
long counter = 0;
while (true) {
Thread.sleep(1000);
publish(++counter);
}
}
@Override
protected void process(List<Long> chunks) {
// Since we're in the EDT, it's probably pointless do announce ALL the
// values, we're probably only interested in the last one
for (long value : chunks) {
firePropertyChange("counter", value - 1, value);
}
}
}
}
现在,这会通知单个组件,如果您需要通知多个组件,那么它就会变得更加困难。
你可以让每个组件创建它自己的SwingWorker
,它监视一些全局监视器锁,允许“主”工作者触发notifyAll
,然后允许“组件工作者”发布一些结果...但你怎么得到价值!?
此时我可能只考虑使用某种event bus