【问题标题】:Splash Screen order is wrong启动画面顺序错误
【发布时间】:2016-03-20 13:57:29
【问题描述】:

我正在尝试完成此程序以: 第一种:要求用户在 JOptionPane 窗口中输入手机号码 2nd:显示消息“单击确定跟踪(输入)的GPS坐标 第三:用户点击确定后,启动画面应该弹出。 第 4 步:启动画面应该完全完成,然后 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") **/); 

    }
};

【问题讨论】:

  • 所以,在您真正需要之前不要创建SplashScreen 的实例。还要记住,Swing 不是线程安全的,而是单线程的。这意味着 1- 你应该只在事件调度线程的上下文中更新 UI 和 2- 你不应该用长时间运行的任务阻塞 EDT

标签: java swing splash-screen joptionpane


【解决方案1】:

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

我猜您必须先显示 2 个 JOptionPanes,将单元格编号保存在全局变量中或将其交给 Splashscreen 实例。 并且在您的启动画面完成后,显示第三个 JOPtion 窗格,其中包含您保存的 cellNumber。

所以你应该编辑你的 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)


                }

            }

【讨论】:

    【解决方案2】:

    你做事的顺序很重要。如果您查看您的代码,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") *
     */
    );
    

    您还需要以某种方式让您的初始屏幕提供关于何时完成任务的事件通知,因为JWindow 不会阻塞。

    一个更简单的解决方案是在模式JDialog 中显示启动画面,这会在启动画面可见时阻止代码的执行,让您“等待”直到它完成。

    作为一般的经验法则,您应该避免从像 JWindow 这样的顶级容器扩展,而是更喜欢像 JPanel 这样的东西,这为您提供了在您想要的任何容器中显示组件的灵活性。

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

    例如...

    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 布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多