【问题标题】:Splashscreen in JavaJava中的闪屏
【发布时间】:2014-01-10 02:16:25
【问题描述】:

我需要弄清楚这段代码中我需要调整它以移动“启动画面!!!”这一行到屏幕的中间,并可能使其更大。我不确定这是在代码中的哪个位置,这让我发疯了。

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();
}
}

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

【问题讨论】:

  • 小便!伙计,你必须让我的帖子很快出现,哈哈
  • 我不完全确定如何添加摆动计时器。启动画面编译并运行得非常好。我想做的完全是装饰性的。
  • @Opjeezzeey 它“看起来”运行良好,但相信我们,它不会......
  • 非常感谢你们!

标签: java swing text splash-screen


【解决方案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 方法。

相反,如果我将Thread.sleep 替换为SwingWorker,我不仅可以显示初始屏幕,而且还可以获得额外的好处,例如能够控制进度更新和安排处理启动画面...

例如...

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);
        }


    }

}

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

【讨论】:

  • 我真的只需要启动画面。因此,从头开始应用程序根本不用担心。但是,所以我只是删除了评论栏以使您的添加生效?
  • 如果您使用Thread.sleep,您的应用程序将“挂起”,因为您阻塞了 EDT。更好的方法是启动应用程序并使用SwingWorker 之类的东西来进行资源加载。一旦调用了done(在SwingWorker 上),您就可以关闭初始屏幕并打开主应用程序窗口。
【解决方案2】:

您正在使用 BorderLayout,这意味着您的容器分为 EAST、WEST NORTH、SOUTH 和 CENTER。您正在向南添加“启动画面”。这就是它不居中的原因:

content.add(copyrt, BorderLayout.SOUTH);

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

【讨论】:

    猜你喜欢
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 2023-03-22
    • 2013-02-10
    • 1970-01-01
    相关资源
    最近更新 更多