Java 启动屏幕顺序错误

Java 启动屏幕顺序错误,java,swing,joptionpane,Java,Swing,Joptionpane,我正在努力完成此计划,以便: 第一:请求用户在JOptionPane窗口中输入手机号码 第二:显示消息“单击“确定”以跟踪的GPS坐标(输入) 第三:用户单击“确定”后,应弹出启动屏幕。 第四:启动屏幕应该完全完成,然后JOptionPane窗口应该显示消息“位于GPS坐标内的地址是:”加上我输入的任何虚假地址 现在,启动屏幕在其他所有操作中运行,并且所有操作都出现故障。我希望启动屏幕在单击“确定”后执行,然后完成并继续执行最后的JOptionPane消息。非常感谢您提供的任何帮助!!仅供参考,

我正在努力完成此计划,以便: 第一:请求用户在JOptionPane窗口中输入手机号码 第二:显示消息“单击“确定”以跟踪的GPS坐标(输入) 第三:用户单击“确定”后,应弹出启动屏幕。 第四:启动屏幕应该完全完成,然后JOptionPane窗口应该显示消息“位于GPS坐标内的地址是:”加上我输入的任何虚假地址

现在,启动屏幕在其他所有操作中运行,并且所有操作都出现故障。我希望启动屏幕在单击“确定”后执行,然后完成并继续执行最后的JOptionPane消息。非常感谢您提供的任何帮助!!仅供参考,此程序是一个虚假的恶作剧

  public class SplashScreen extends JWindow {

    static boolean isRegistered;
    private static JProgressBar progressBar = new JProgressBar();
    private static SplashScreen execute;
    private static int count;
    private static Timer timer1;

    public SplashScreen() {

        Container container = getContentPane();
        container.setLayout(null);

        JPanel panel = new JPanel();
        panel.setBorder(new javax.swing.border.EtchedBorder());
        panel.setBackground(Color.green);
        panel.setBounds(10, 10, 348, 150);
        panel.setLayout(null);
        container.add(panel);

        JLabel label = new JLabel("Tracking target GPS coordinates...");
        label.setFont(new Font("Verdana", Font.BOLD, 14));
        label.setBounds(15, 25, 280, 30);
        panel.add(label);

        progressBar.setMaximum(50);
        progressBar.setBounds(55, 180, 250, 15);
        container.add(progressBar);
        loadProgressBar();
        setSize(370, 215);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void loadProgressBar() {
        ActionListener al = new ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                count++;

                progressBar.setValue(count);

                System.out.println(count);

                if (count == 300) {

                    createFrame();

                    execute.setVisible(false);

                    timer1.stop();
                }

            }

            private void createFrame() throws HeadlessException {
                JFrame frame = new JFrame();
                frame.setSize(500, 500);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        };
        timer1 = new Timer(50, al);
        timer1.start();
    }

    public static void main(String[] args) {
        execute = new SplashScreen();

        String targetCell = JOptionPane.showInputDialog(null, "Enter "
                + "target cellphone number: ");
        JOptionPane.showMessageDialog(null, "Click OK to "
                + "track the GPS coordinates of " + targetCell + "...");
        JOptionPane.showMessageDialog(null, "The address located within "
                + "GPS coordinates is: " /** + "random fake address") **/); 

    }
};

你已经清楚地说出了你想要的,那么为什么不直接去做呢?:)

我猜您必须先显示2个JOptionPanes,将单元格编号保存在全局变量中,或者将其交给Splashscreen实例。 在您的splashscreen完成后,显示带有您保存的手机号码的第三个任务窗格

因此,您应该编辑actionPefromed方法,如下所示:

public void actionPerformed(java.awt.event.ActionEvent evt) {
                count++;

                progressBar.setValue(count);

                System.out.println(count);

                if (count == 300) {
                    execute.setVisible(false);
                    timer1.stop();
                      //splash screen finished so show JoptionPane here
                    JOptionPane.showMessageDialog(null, "The address located within "
            + "GPS coordinates is: " + targetCell)


                }

            }

你做事的顺序非常重要。如果你看你的代码,
SplashScreen
会使窗口在创建时可见,这是一个坏主意,你突然发现了

首先,你需要改变做事的顺序,例如

String targetCell = JOptionPane.showInputDialog(null, "Enter "
        + "target cellphone number: ");
JOptionPane.showMessageDialog(null, "Click OK to "
        + "track the GPS coordinates of " + targetCell + "...");
// Show and wait for splash screen to complete
JOptionPane.showMessageDialog(null, "The address located within "
        + "GPS coordinates is: " /**
 * + "random fake address") *
 */
);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                String targetCell = JOptionPane.showInputDialog(null, "Enter "
                        + "target cellphone number: ");
                JOptionPane.showMessageDialog(null, "Click OK to "
                        + "track the GPS coordinates of " + targetCell + "...");
                SplashPane.showSplashScreen();
                JOptionPane.showMessageDialog(null, "The address located within "
                        + "GPS coordinates is: " /**
                 * + "random fake address") *
                 */
                );
            }
        });
    }

    public static class SplashPane extends JPanel {

        private JProgressBar progressBar = new JProgressBar();
        private Timer timer1;

        public SplashPane() {
            setLayout(new BorderLayout(0, 4));
            setBorder(new EmptyBorder(10, 10, 10, 10));

            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(new CompoundBorder(
                    new javax.swing.border.EtchedBorder(),
                    new EmptyBorder(30, 20, 30, 20)));
            panel.setBackground(Color.green);
            JLabel label = new JLabel("Tracking target GPS coordinates...");
            label.setFont(new Font("Verdana", Font.BOLD, 14));
            panel.add(label);
            add(panel);

            add(progressBar, BorderLayout.SOUTH);

            loadProgressBar();
        }

        private void loadProgressBar() {
            ActionListener al = new ActionListener() {
                private int count;

                @Override
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    count = Math.min(100, ++count);
                    progressBar.setValue(count);

                    System.out.println(count);
                    if (count == 100) {
                        SwingUtilities.windowForComponent(SplashPane.this).dispose();
                        timer1.stop();
                    }
                }
            };
            timer1 = new Timer(150, al);
            timer1.start();
        }

        public static void showSplashScreen() {
            JDialog frame = new JDialog();
            frame.setModal(true);
            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
            frame.setUndecorated(true);
            frame.add(new SplashPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

    }
}
您还需要某种方式让您的启动屏幕在完成任务时提供事件通知,因为
JWindow
是无阻塞的

一个更简单的解决方案是在模式
JDialog
中显示启动屏幕,这将在启动屏幕可见时阻止代码的执行,从而允许您“等待”直到完成

一般来说,您应该避免从顶级容器(如
JWindow
)进行扩展,而应该选择
JPanel
),这为您提供了在任何容器中显示组件的灵活性

启动下一个窗口也不是启动屏幕的责任,它唯一的责任是显示其活动的进度(并可能返回其计算结果)

例如

String targetCell = JOptionPane.showInputDialog(null, "Enter "
        + "target cellphone number: ");
JOptionPane.showMessageDialog(null, "Click OK to "
        + "track the GPS coordinates of " + targetCell + "...");
// Show and wait for splash screen to complete
JOptionPane.showMessageDialog(null, "The address located within "
        + "GPS coordinates is: " /**
 * + "random fake address") *
 */
);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                String targetCell = JOptionPane.showInputDialog(null, "Enter "
                        + "target cellphone number: ");
                JOptionPane.showMessageDialog(null, "Click OK to "
                        + "track the GPS coordinates of " + targetCell + "...");
                SplashPane.showSplashScreen();
                JOptionPane.showMessageDialog(null, "The address located within "
                        + "GPS coordinates is: " /**
                 * + "random fake address") *
                 */
                );
            }
        });
    }

    public static class SplashPane extends JPanel {

        private JProgressBar progressBar = new JProgressBar();
        private Timer timer1;

        public SplashPane() {
            setLayout(new BorderLayout(0, 4));
            setBorder(new EmptyBorder(10, 10, 10, 10));

            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(new CompoundBorder(
                    new javax.swing.border.EtchedBorder(),
                    new EmptyBorder(30, 20, 30, 20)));
            panel.setBackground(Color.green);
            JLabel label = new JLabel("Tracking target GPS coordinates...");
            label.setFont(new Font("Verdana", Font.BOLD, 14));
            panel.add(label);
            add(panel);

            add(progressBar, BorderLayout.SOUTH);

            loadProgressBar();
        }

        private void loadProgressBar() {
            ActionListener al = new ActionListener() {
                private int count;

                @Override
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    count = Math.min(100, ++count);
                    progressBar.setValue(count);

                    System.out.println(count);
                    if (count == 100) {
                        SwingUtilities.windowForComponent(SplashPane.this).dispose();
                        timer1.stop();
                    }
                }
            };
            timer1 = new Timer(150, al);
            timer1.start();
        }

        public static void showSplashScreen() {
            JDialog frame = new JDialog();
            frame.setModal(true);
            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
            frame.setUndecorated(true);
            frame.add(new SplashPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

    }
}

避免使用
null
layouts,像素完美的布局在现代ui设计中是一种幻觉。有太多的因素会影响组件的单个大小,而这些因素都是您无法控制的。Swing的设计目的是与核心的布局管理器配合使用,丢弃这些布局将导致无休止的问题和问题,您将无法解决结束越来越多的时间尝试纠正

,因此,在实际需要之前不要创建
SplashScreen
的实例。还要记住,Swing不是线程安全的,是单线程的。这意味着1-您应该只从事件调度线程的上下文中更新UI,2-您不应该使用lo阻止EDT正在运行的任务