Domanda

I have written following code.I have not shown full source but psudo code.

class UI extends JFrame
{
    //created UI with one Button
    onButtonclick()
    {
       //did some operation before set icon to button
       //say opened fileopen dialog and get file
       button.setText("");
       ImageIcon progressbar =  new     
           ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif"));
            buttonExport.setIcon(progressbar);

      // did some database operations
      //again removed icon from button
      button.setIcon(null);
      button.setText("click");
    }
}

When I click on button It opens file open dialog and and button text get set to empty. But It doesn't set Icon to button.When all Database operation are done which are performed after Icon set to button that time Icon is appeared on button. Why this behavior is? How to set Icon to button and do some Database operations and again remove it? Thank you. :)

È stato utile?

Soluzione

The GUI system can only do one thing at a time, like most code (except for code that uses threads). Calling your listener is a thing. The GUI system cannot do anything else while your listener is running.

Your database operation needs to run on another thread (which you can create) and then update the GUI when it's done. Something like this:

void onButtonPressed() {
    // The code to open the file dialog goes here

    button.setText("");
    ImageIcon progressbar = new     
        ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif"));
        buttonExport.setIcon(progressbar);

    new Thread() {
        @Override
        public void run() {
            // do some database operations here

            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    //again remove icon from button
                    button.setIcon(null);
                    button.setText("click");
                }
            });
        }
    }.start();
}

Code in different threads runs at the same time. This is convenient but dangerous. Be extremely careful when accessing data from the new thread - if one thread changes a field and the other thread reads it, the results might not be what you expect. The simplest thing to do is to make sure the main thread doesn't change any variables used by the new thread while it's running.

When your database operations are finished, you can't set the button back to normal by just calling setText. Only the main thread is allowed to affect the GUI - what if the main thread was drawing the button on the screen at the same time the database operation thread was changing the text? The button might be drawn incorrectly. So you need to call EventQueue.invokeLater which tells the GUI system to run your code in the near future when it's not busy. The code inside new Runnable() {} is like the code in the button listener - no other GUI-related code will run while it does.

Altri suggerimenti

This should work:

Image progressbar= ImageIO.read(DatasetExporterUI.class.getResource("/progreassbar.gif")); 

buttonExport.setIcon(new ImageIcon(progressbar));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top