Как запустить два фрейма одновременно в java

Я пытаюсь создать экран загрузки для своей программы, чтобы он отображал экран загрузки при загрузке главного экрана или при выполнении определенной задачи. Я пытался использовать JDialog в качестве экрана загрузки, но по какой-то причине, как только открывается диалоговое окно экрана загрузки, он не позволяет основной программе выполнять свою собственную работу. Как заставить их работать одновременно?

Вот код моего экрана загрузки:

public class FrmLoading extends JDialog {

  private static FrmLoading loading;

  public FrmLoading(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();
    this.setLocationRelativeTo(null);
  }

  public static void startAnimation(){
    loading = new frmLoading(null, true);
    loading.setVisible(true);
  }

  public static void stopAnimation(){
    loading.dispose();
  }

  private void initComponents(){
    //build the Dialog
  }
}

вот как я его использую:

private void login(){
    FrmLoading.startAnimation();
    //open main program
}

...

private void mainStart(){
    //load contents
    FrmLoading.stopAnimation();
}

Я знаю, что есть экран загрузки по умолчанию для Java Swing, но я не хочу его использовать, мне нужна анимация, которую я сделал.


person John    schedule 27.11.2012    source источник
comment
Я бы предположил, что modal = false поможет. Тем не менее, SplashScreen по умолчанию может многое.   -  person Joop Eggen    schedule 27.11.2012
comment
Я уже пробовал это, но мой экран загрузки не отображался   -  person John    schedule 27.11.2012


Ответы (3)


Используйте SwingWorker.

SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
    @Override
    protected Void doInBackground() {
        //do your stuff in background
        return null;
    }

    @Override
    protected void done() {
        frmMain.setVisible(true);
        loading.dispose();
        disposeThis(); //a method that calls this.dispose();
    }
};
worker.execute();
loading.setVisible(true);
person eSuarez    schedule 27.11.2012
comment
где я должен разместить это? в классе FrmLoading или в основном классе? - person John; 27.11.2012
comment
Используйте его в своем суперклассе. Когда рабочий выполняется, вы делаете свой диалог видимым. В методе doInBackground поместите все, что вы хотите сделать. Когда это будет завершено, в done() вы просто сделаете его невидимым или вызовете dispose() для диалога загрузки. - person eSuarez; 27.11.2012
comment
проблема в том, что когда моя программа запускается, она переходит в класс FrmLogin. Оттуда, как только пользователь нажмет кнопку входа в систему, он запустит FrmLoading. FrmLogin откроет FrmMain, где FrmMain загрузит все его содержимое, и после этого остановит FrmLoading. Итак, в фрагменте, который вы предоставили, как мне это сделать? кстати спасибо за помощь. - person John; 27.11.2012
comment
Поместите загрузку вашего FrmMain в тот же воркер. Поскольку вы используете FrmLoading только для презентации, вы можете загружать все из своего FrmLogin, пока отображается ваш FrmLoading. Когда загрузка будет завершена, откройте созданный основной экземпляр и удалите экземпляры входа и загрузки. - person eSuarez; 27.11.2012

Зачем вообще использовать JFrame для экрана загрузки. Рассмотрите возможность использования чего-то вроде JWindow:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.JWindow;

public class LoadingScreenDemo extends JWindow{
    Panel panel = new Panel();


    public LoadingScreenDemo() {
        addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent e){
                if(e.getClickCount() == 2){
                    dispose();
                }
            }
        });
        panel.setBackground(Color.YELLOW);
        add(panel);
    }


    public static void main(String[] args) {
        LoadingScreenDemo m = new LoadingScreenDemo();
        m.setSize(640,480);
        m.setLocationRelativeTo(null);
        m.setVisible(true);
    }

    class Panel extends JPanel{

        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setFont(new Font("Verdana",Font.BOLD,24));
            g.drawString("Loading...", 270, 210);

            g.setFont(new Font("Verdana",Font.PLAIN,14));
            g.drawString("OS: "+System.getProperty("os.name"), 10,400);
            g.drawString("OS version"+System.getProperty("os.version"), 10,420);
            g.drawString("Java vendor: "+System.getProperty("java.vendor"), 10,440);
            g.drawString("Java version: "+System.getProperty("java.version"), 10,460);
        }
    }

}

введите здесь описание изображения

person Branislav Lazic    schedule 27.11.2012
comment
Вы имитируете SplashScreen - person mKorbel; 27.11.2012
comment
@trashgod Подойдет. Спасибо за совет! :) - person Branislav Lazic; 27.11.2012

Вместо использования логического модального аргумента в конструкторе JDialog вы можете использовать конструктор JDialog с модальностью и передать перечисление MODELESS.

Это может предотвратить блокировку главного окна.

person Jose    schedule 27.11.2012