java 使用定时器更改 JOptionPane 中 JTextArea 的内容
java Change content of JTextArea in JOptionPane with Timer
结果看起来像这个问题:
reading a log file and displaying it in jtextarea
但不同的是我使用 JOptionPane
.
我的流程是这样的:
用户点击'Update'按钮,
然后它将显示 JOptionPane
和 JTextArea
,
我应该使用 Timer
从服务器获取更新状态(就像轮询一样)。
问题是,它只是在我关闭 JOptionPane
后更改 JTextArea
的内容,所以我想我不能使用 JOptionPane
或者我应该更改我的代码实现我的目标。
目前的代码是:
在main.java中:
static JFrame demo = new JFrame();
static JPanel myPanel=new JPanel();
static JScrollPane pane = new JScrollPane(myPanel); // Just use to have scrollbar
public static void main(String[] args) {
// TODO Auto-generated method stub
demo.setSize(560, 300);
demo.setTitle("avaControlFinder");
demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myPanel.setLayout(new GridBagLayout());
JButton updt=new JButton("Update");
updt.addActionListener(new UpdateAction());
GridBagConstraints c2 = new GridBagConstraints();
c2.gridx = 1;
c2.gridy = (listA.size()-1)*2+1;
c2.gridwidth = 1;
c2.gridheight = 1;
c2.weightx = 0;
c2.weighty = 0;
c2.fill = GridBagConstraints.NONE;
c2.anchor = GridBagConstraints.WEST;
c2.insets = new Insets(10,10,0,0); //top padding
myPanel.add(updt,c2);
myPanel.validate();
myPanel.repaint();
demo.getContentPane().add(pane);
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
在UpdateAction.java中:
JPanel plWait = new JPanel();
plWait.setLayout(new GridBagLayout());
final JTextArea ta=new JTextArea(10,20);
ta.setEditable(false); // just want to show a content of log, so I don't let user edit it.
GridBagConstraints c4 = new GridBagConstraints();
c4.gridx = 0;
c4.gridy = 0;
c4.gridwidth = 1;
c4.gridheight = 1;
c4.weightx = 0;
c4.weighty = 0;
c4.fill = GridBagConstraints.NONE;
c4.anchor = GridBagConstraints.NORTHEAST ;
plWait.add(ta,c4);
JOptionPane.showOptionDialog(null, plWait,
"title", JOptionPane.NO_OPTION,
JOptionPane.PLAIN_MESSAGE, null, new Object[] {},
null);
Timer timer= new Timer();
TimerTask showtime= new TimerTask(){
int test=0;
@Override
public void run() {
// TODO Auto-generated method stub
test++;
ta.append(""+test); // test for change content of JTextArea, I even use System.out.println(""+test); and it only be changed after I close the JOptionPane.
}
};
timer.schedule(showtime, 1000, 1000);
我是否应该使用其他组件来替换 JTextArea
?
或者我应该使用其他容器而不是 JOptionPane
?
我通过使用 Window.ShowDialog();
在 C# 中完美地完成了这个过程
我应该使用另一个 JFrame
作为另一个弹出窗口 window 吗?
如有任何建议,我们将不胜感激。
您必须使用 SwingUtilities.invokelater
在 UI 线程上调用此函数 ta.append(""+test)
。
在你的情况下试试这个:
TimerTask showtime= new TimerTask(){
int test=0;
@Override
public void run() {
// TODO Auto-generated method stub
test++;
SwingUtilities.invokelater(new Runnable(){
public void run(){
ta.append(""+test);
}
})
}};
A JOptionPane
使用模态对话框,这意味着它将阻止代码的执行,直到它被关闭,这就是重点。
您可以做三件事...
- 使用 Swing
javax.swing.Timer
而不是 java.util.Timer
。 Swing Timer
将在事件调度线程的上下文中执行它的滴答通知,使其可以安全地用于修改 UI。 Swing 是单线程的,不是线程安全的。有关详细信息,请参阅 Concurrency in Swing and How to use Swing Timers
- 使用
SwingWorker
而不是 java.util.Timer
,这允许您 运行 长 运行ning 或可能阻止 EDT 之外的代码,但提供更容易使用同步更新到 EDT 的方法。有关详细信息,请参阅 Worker Threads and SwingWorker
- 无论您选择前两个选项中的哪一个,您都应该在开始前两个选项中的任何一个后显示
JOptionPane
...
结果看起来像这个问题: reading a log file and displaying it in jtextarea
但不同的是我使用 JOptionPane
.
我的流程是这样的:
用户点击'Update'按钮,
然后它将显示 JOptionPane
和 JTextArea
,
我应该使用 Timer
从服务器获取更新状态(就像轮询一样)。
问题是,它只是在我关闭 JOptionPane
后更改 JTextArea
的内容,所以我想我不能使用 JOptionPane
或者我应该更改我的代码实现我的目标。
目前的代码是:
在main.java中:
static JFrame demo = new JFrame();
static JPanel myPanel=new JPanel();
static JScrollPane pane = new JScrollPane(myPanel); // Just use to have scrollbar
public static void main(String[] args) {
// TODO Auto-generated method stub
demo.setSize(560, 300);
demo.setTitle("avaControlFinder");
demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myPanel.setLayout(new GridBagLayout());
JButton updt=new JButton("Update");
updt.addActionListener(new UpdateAction());
GridBagConstraints c2 = new GridBagConstraints();
c2.gridx = 1;
c2.gridy = (listA.size()-1)*2+1;
c2.gridwidth = 1;
c2.gridheight = 1;
c2.weightx = 0;
c2.weighty = 0;
c2.fill = GridBagConstraints.NONE;
c2.anchor = GridBagConstraints.WEST;
c2.insets = new Insets(10,10,0,0); //top padding
myPanel.add(updt,c2);
myPanel.validate();
myPanel.repaint();
demo.getContentPane().add(pane);
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
在UpdateAction.java中:
JPanel plWait = new JPanel();
plWait.setLayout(new GridBagLayout());
final JTextArea ta=new JTextArea(10,20);
ta.setEditable(false); // just want to show a content of log, so I don't let user edit it.
GridBagConstraints c4 = new GridBagConstraints();
c4.gridx = 0;
c4.gridy = 0;
c4.gridwidth = 1;
c4.gridheight = 1;
c4.weightx = 0;
c4.weighty = 0;
c4.fill = GridBagConstraints.NONE;
c4.anchor = GridBagConstraints.NORTHEAST ;
plWait.add(ta,c4);
JOptionPane.showOptionDialog(null, plWait,
"title", JOptionPane.NO_OPTION,
JOptionPane.PLAIN_MESSAGE, null, new Object[] {},
null);
Timer timer= new Timer();
TimerTask showtime= new TimerTask(){
int test=0;
@Override
public void run() {
// TODO Auto-generated method stub
test++;
ta.append(""+test); // test for change content of JTextArea, I even use System.out.println(""+test); and it only be changed after I close the JOptionPane.
}
};
timer.schedule(showtime, 1000, 1000);
我是否应该使用其他组件来替换 JTextArea
?
或者我应该使用其他容器而不是 JOptionPane
?
我通过使用 Window.ShowDialog();
我应该使用另一个 JFrame
作为另一个弹出窗口 window 吗?
如有任何建议,我们将不胜感激。
您必须使用 SwingUtilities.invokelater
在 UI 线程上调用此函数 ta.append(""+test)
。
在你的情况下试试这个:
TimerTask showtime= new TimerTask(){
int test=0;
@Override
public void run() {
// TODO Auto-generated method stub
test++;
SwingUtilities.invokelater(new Runnable(){
public void run(){
ta.append(""+test);
}
})
}};
A JOptionPane
使用模态对话框,这意味着它将阻止代码的执行,直到它被关闭,这就是重点。
您可以做三件事...
- 使用 Swing
javax.swing.Timer
而不是java.util.Timer
。 SwingTimer
将在事件调度线程的上下文中执行它的滴答通知,使其可以安全地用于修改 UI。 Swing 是单线程的,不是线程安全的。有关详细信息,请参阅 Concurrency in Swing and How to use Swing Timers - 使用
SwingWorker
而不是java.util.Timer
,这允许您 运行 长 运行ning 或可能阻止 EDT 之外的代码,但提供更容易使用同步更新到 EDT 的方法。有关详细信息,请参阅 Worker Threads and SwingWorker - 无论您选择前两个选项中的哪一个,您都应该在开始前两个选项中的任何一个后显示
JOptionPane
...