简体   繁体   English

java使用计时器更改JOptionPane中JTextArea的内容

[英]java Change content of JTextArea in JOptionPane with Timer

The result looks like this question: reading a log file and displaying it in jtextarea 结果看起来像这样的问题: 读取日志文件并将其显示在jtextarea中

but the different is I use JOptionPane . 但不同的是我使用JOptionPane

My process is like that: 我的过程是这样的:

User click the 'Update' button, 用户点击“更新”按钮,

then it will show a JOptionPane with JTextArea , 然后它将显示带有JTextAreaJOptionPane

and I should use Timer to get the status of updating from server( just like polling). 我应该使用Timer从服务器获取更新状态(就像轮询一样)。

The problem is, it just change the content of the JTextArea after I close the JOptionPane , so I guess I can't use JOptionPane or I should change my code to reach my goal. 问题是,它仅在关闭JOptionPane之后才更改JTextArea的内容,所以我想我不能使用JOptionPane否则我应该更改代码以实现自己的目标。

The code so far is: 到目前为止的代码是:

In main.java: 在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);
    }

In UpdateAction.java: 在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);

Should I use other component to take replace JTextArea ? 我应该使用其他组件代替JTextArea吗?

Or should I user other container stead of JOptionPane ? 还是应该使用其他容器代替JOptionPane

I do this process in C# perfectly by using Window.ShowDialog(); 我使用Window.ShowDialog();在C#中完美地完成了此过程Window.ShowDialog();

Should I use another JFrame as another pop up window? 我应该使用另一个JFrame作为另一个弹出窗口吗?

Any advice will be appreciated. 任何建议将被认真考虑。

A JOptionPane uses a modal dialog, meaning that it will block the execution of your code until it is dismissed, that's kind of the point. JOptionPane使用模式对话框,这意味着它将阻塞代码的执行,直到被解雇为止。

Three things you could do... 您可以做的三件事...

  1. Use a Swing javax.swing.Timer instead of a java.util.Timer . 使用Swing javax.swing.Timer而不是java.util.Timer A Swing Timer will execute it's tick notifications within the context of the Event Dispatching Thread, making it safe to use to modify the UI. Swing Timer将在事件调度线程的上下文中执行其滴答通知,从而可以安全地使用它来修改UI。 Swing is single threaded and not thread safe. 摆动是单线程的,不是线程安全的。 See Concurrency in Swing and How to use Swing Timers for more details 有关更多详细信息,请参见Swing中的并发如何使用Swing计时器
  2. Use a SwingWorker instead of a java.util.Timer , this allows you to run long running or potentially blocking code out side of the EDT, but provides easier to use methods of synching updates to the EDT. 使用SwingWorker而不是java.util.Timer ,这使您可以在EDT外部运行长时间运行的代码或可能阻塞代码,但提供了更简便的将更新同步到EDT的方法。 See Worker Threads and SwingWorker for more details 有关更多详细信息,请参见工作线程和SwingWorker
  3. Regardless of which of the previous two options you choose, you should display the JOptionPane AFTER you have started either of the two previous choices... 无论您选择前两个选项中的哪个选项,都应在启动前两个选项中的一个之后显示JOptionPane ...

You must call this function ta.append(""+test) on UI thread by using SwingUtilities.invokelater . 您必须使用SwingUtilities.invokelater在UI线程上调用此函数ta.append(""+test) In your case try this: 在您的情况下,请尝试以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM