使用Timer更改JOptionPane中JTextArea的内容

时间:2015-01-26 10:13:34

标签: java swing timer jtextarea joptionpane

结果看起来像这个问题: reading a log file and displaying it in jtextarea

但不同的是我使用JOptionPane

我的过程是这样的:

用户点击“更新”'按钮,

然后它会显示JOptionPane JTextArea

我应该使用Timer来获取服务器更新的状态(就像轮询一样)。

问题是,它只是在我关闭JTextArea后更改JOptionPane的内容,所以我想我不能使用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作为另一个弹出窗口吗?

任何建议都将受到赞赏。

2 个答案:

答案 0 :(得分:4)

JOptionPane使用模态对话框,这意味着它会阻止代码的执行,直到它被解除为止,这就是重点。

你可以做三件事......

  1. 使用Swing javax.swing.Timer代替java.util.Timer。 Swing Timer将在事件调度线程的上下文中执行它的滴答通知,从而可以安全地用于修改UI。 Swing是单线程的,不是线程安全的。有关详细信息,请参阅Concurrency in SwingHow to use Swing Timers
  2. 使用SwingWorker代替java.util.Timer,这允许您在EDT外部运行长时间运行或可能阻止的代码,但提供了更易于使用的同步更新到EDT的方法。有关详细信息,请参阅Worker Threads and SwingWorker
  3. 无论您选择前两个选项中的哪一个,您都应该在之前两个选项之一中显示JOptionPane ...

答案 1 :(得分:1)

您必须使用ta.append(""+test)在UI线程上调用此函数SwingUtilities.invokelater。 在你的情况下试试这个:

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);
        }
    })
}};