有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的swing Splashscreen

我需要找出在这段代码中我需要调整它的位置,以移动“启动屏幕!!!”放在屏幕中间,并可能使其更大。我不确定这在代码中的位置,这让我抓狂

import java.awt.*;
import javax.swing.*;

public class SplashScreen extends JWindow {

private int duration;

public SplashScreen(int d) {
    duration = d;
}

// A simple little method to show a title screen in the center
// of the screen for the amount of time given in the constructor
public void showSplash() {

    JPanel content = (JPanel)getContentPane();
    content.setBackground(Color.blue);

    // Set the window's bounds, centering the window
    int width = 700;
    int height = 450;
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (screen.width-width)/2;
    int y = (screen.height-height)/2;
    setBounds(x,y,width,height);

    // Build the splash screen
    JLabel label = new JLabel(new ImageIcon("java-tip.gif"));
    JLabel copyrt = new JLabel
        ("Splash Screen!!!", JLabel.CENTER);
    copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
    content.add(label, BorderLayout.CENTER);
    content.add(copyrt, BorderLayout.SOUTH);
    Color oraRed = new Color(200, 50, 20, 255);
    content.setBorder(BorderFactory.createLineBorder(oraRed, 10));

    // Display it
    setVisible(true);

    // Wait a little while, maybe while loading resources
    try { Thread.sleep(duration); } catch (Exception e) {}

    setVisible(false);
}
public void showSplashAndExit() {
    showSplash();
    System.exit(0);

}

public static void main(String[] args) {

    // Throw a nice little title page up on the screen first
    SplashScreen splash = new SplashScreen(10000);

    // Normally, we'd call splash.showSplash() and get on
    // with the program. But, since this is only a test...
    splash.showSplashAndExit();
}
}

我不知道为什么,但这个论坛的“添加代码”功能总是让它看起来很奇怪,而且没有正确缩进


共 (2) 个答案

  1. # 1 楼答案

    有几种方法可以做到这一点,但让我们保持简单

    基本上,这就是将label(背景)图像添加到内容窗格的中心位置。然后将BorderLayout应用于label,并将copyrt添加到label的中心位置

    public void showSplash() {
    
        JPanel content = (JPanel) getContentPane();
        content.setBackground(Color.blue);
    
        // Set the window's bounds, centering the window
        int width = 700;
        int height = 450;
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screen.width - width) / 2;
        int y = (screen.height - height) / 2;
        setBounds(x, y, width, height);
    
        // Build the splash screen
        JLabel label = new JLabel(new ImageIcon("java-tip.gif"));
        JLabel copyrt = new JLabel("Splash Screen!!!", JLabel.CENTER);
    
        content.add(label, BorderLayout.CENTER);
    
        // Fun starts here...    
    //        copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
    //        content.add(copyrt, BorderLayout.SOUTH);
    
        label.setLayout(new BorderLayout());
        Font font = copyrt.getFont();
        copyrt.setFont(font.deriveFont(Font.BOLD, 24f));
        label.add(copyrt);
    
        Color oraRed = new Color(200, 50, 20, 255);
        content.setBorder(BorderFactory.createLineBorder(oraRed, 10));
    
        // Display it
        setVisible(true);
    
        // Don't do this, as it will cause the EDT to be stopped.  Instead
        // setup some kind of callback that can tell when the resources are 
        // loaded and start the rest of the application from there...
        // Wait a little while, maybe while loading resources
        //try {
        //    Thread.sleep(duration);
        //} catch (Exception e) {
        //}
    
        //setVisible(false);
    }
    

    在EDT的上下文中做任何可能阻止它处理进一步事件的事情,比如使用sleep或长时间运行/无限循环,也是一个坏主意

    所有UI交互都应该在EDT的上下文中执行,所有长时间运行或可能阻塞的任务都应该在单独的线程上运行

    更多细节请看Concurrency in Swing

    更新

    如果我试着运行您的示例,启动屏幕永远不会出现,因为Thread.sleep会阻止在屏幕上显示。您“可能”让它工作的事实实际上是一种侥幸,因为您可能是从“主”线程而不是EDT调用showSplash方法

    相反,如果我用SwingWorker替换Thread.sleep,我不仅可以显示初始屏幕,而且还可以控制进度更新和处理初始屏幕的计划

    例如

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Toolkit;
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JWindow;
    import javax.swing.SwingWorker;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class SplashDemo extends JWindow {
    
        public static void main(String[] args) {
            new SplashDemo();
        }
    
        public SplashDemo() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    showSplash();
    
                }
            });
        }
    
        public void showSplash() {
    
            JPanel content = (JPanel) getContentPane();
            content.setBackground(Color.blue);
    
            // Set the window's bounds, centering the window
            int width = 700;
            int height = 450;
            Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (screen.width - width) / 2;
            int y = (screen.height - height) / 2;
            setBounds(x, y, width, height);
    
            // Build the splash screen
            JLabel label = new JLabel(new ImageIcon(getClass().getResource("/java_animated.gif")));
            JLabel copyrt = new JLabel("Splash Screen!!!", JLabel.CENTER);
    
            content.add(label, BorderLayout.CENTER);
    
            label.setLayout(new GridBagLayout());
            Font font = copyrt.getFont();
            copyrt.setFont(font.deriveFont(Font.BOLD, 24f));
    
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            label.add(copyrt, gbc);
    
            ImageIcon wait = new ImageIcon(getClass().getResource("/wait.gif"));
            label.add(new JLabel(wait), gbc);
    
            Color oraRed = new Color(200, 50, 20, 255);
            content.setBorder(BorderFactory.createLineBorder(oraRed, 10));
    
            // Display it
            setVisible(true);
            toFront();
    
            new ResourceLoader().execute();
        }
    
        public class ResourceLoader extends SwingWorker<Object, Object> {
    
            @Override
            protected Object doInBackground() throws Exception {
    
                // Wait a little while, maybe while loading resources
                try {
                    Thread.sleep(5000);
                } catch (Exception e) {
                }
    
                return null;
    
            }
    
            @Override
            protected void done() {
                setVisible(false);
            }
    
    
        }
    
    }
    

    如果你喜欢,我用了以下图片

    enter image description hereenter image description here

  2. # 2 楼答案

    您使用的是BorderLayout,这意味着您的容器分为东、西、北、南和中。你正在南方添加“闪屏”。这就是为什么它没有居中:

    content.add(copyrt, BorderLayout.SOUTH);
    

    您需要将布局管理器更改为其中一个网格布局。或者,创建多个面板并将内容添加到其中,然后添加到父容器中