0

I have an application that after successfull login (on a JFrame), starts to create the main frame (class MainUI that extends from JFrame). That MainUI class contains a JTabbedPane (which each tab is a class that extends from JPanel) and, on setVisible method, creates and shows each tab.

I want to add on the login form, after successfull login, a Spinner image to indicate that the MainUI is being created.

After display the Spinner image, I invoke the creation of the MainUI and call the setVisible method on EventQueue.invokeLater(); but the Spinner image is not updated. If I use new Thread(runner).start(); is updated, but I get a lot of Component creation must be done on Event Dispatch Thread

Some code of Login.java:

buttonLogin.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
       login();
   }
});

private void login()
{
   //check DB and permissions
   //if all is ok
   lMsj.setIcon(spinner);
   new Thread(new Runnable() {
      public void run() {
          showMainUI(usr);
      }
   }).start();
}
private void showMainUI(final Usuario usr)
{
    Runnable runner = new Runnable() {
        public void run() {
            final MainUI mui = new MainUI();
            mui.setVisible(true);

            dispose();
        }
    };
    EventQueue.invokeLater(runner);
}

and some code of MainUI.java

public MainUI()
{
    SwingUtilities.invokeLater(new Runnable() {
        @Override public void run() {
            setMinimumSize(new Dimension(1280, 960));

            createComponents();
        }
    });
}
private void initComponents()
{
   //..
   // menuItem = new ...
    // ...
}

@Override
public void setVisible(boolean value)
{
   //..
   if (Security.get().isAllowed("tab1")){
     addTab1();
   }
   //..
}

private void addTab1(){
   //..
   getTabbedPane().addTab("Tab1", new Tab1());
   //..
}

How I can fix this, so that the image is updated and the user interface is created in the "background"?

jotapdiez
  • 1,456
  • 13
  • 28
  • 1
    You have a problem. Swing is not thread safe, which means you should never create or update the UI from outside the Event Dispatching Thread. Instead, you should create the models/data that the views will rely on in a separate thread and then present the view and data within the EDT – MadProgrammer Oct 29 '14 at 02:44
  • 1
    `EventQueue.invokeLater` will execute the `Runnable` at some time in the future WITHIN the context of the EDT, where the spinner label is also operating, meaning that the two will be updated together... – MadProgrammer Oct 29 '14 at 02:45
  • 1
    I've already asked the same question. See [here](http://stackoverflow.com/questions/23912610/initialization-of-application-and-splash-screen-with-progress-bar-swing). There is no good solution for this problem, but probably some of possibilities (workarounds) in discussion will help you to solve your problem. Note: if you only need an animated splash screen, you can use the [standard approach](http://docs.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html) provided by Oracle – Sergiy Medvynskyy Oct 29 '14 at 07:22

0 Answers0