简体   繁体   中英

java Change content of JTextArea in JOptionPane with Timer

The result looks like this question: reading a log file and displaying it in jtextarea

but the different is I use JOptionPane .

My process is like that:

User click the 'Update' button,

then it will show a JOptionPane with JTextArea ,

and I should use Timer to get the status of updating from server( just like polling).

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.

The code so far is:

In 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:

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 ?

Or should I user other container stead of JOptionPane ?

I do this process in C# perfectly by using Window.ShowDialog();

Should I use another JFrame as another pop up window?

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.

Three things you could do...

  1. Use a Swing javax.swing.Timer instead of a 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 is single threaded and not thread safe. See Concurrency in Swing and How to use Swing Timers for more details
  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. See Worker Threads and SwingWorker for more details
  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...

You must call this function ta.append(""+test) on UI thread by using SwingUtilities.invokelater . 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);
        }
    })
}}; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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