Java 中的启动画面
我需要弄清楚在这段代码中我需要调整它的哪个位置以移动Splash Screen!!!"行到屏幕的中间,并可能使它更大.我不确定这是在代码中的哪个位置,这让我发疯.
I need to figure out where in this code I need to adjust it to move the line "Splash Screen!!!" to the middle of the screen and possibly make it bigger. I am not sure where in the code this is and it is driving me nuts.
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();
}
}
我不知道为什么,但是这个论坛中的添加代码功能总是让它看起来很奇怪而且缩进不正确.
I am not sure why but the add code feature in this forum always makes it look weird and not indented properly.
有几种方法可以做到这一点,但让我们保持简单.
There's a few ways this might be done, but lets keep it simple.
基本上,这样做是将 label
(背景)图像添加到内容窗格的中心位置.然后将 BorderLayout
应用到 label
并将 copyrt
添加到 label
的中心位置...
Basically, what this does is add the label
(background) image to the center position of the content pane. It then applies a BorderLayout
to label
and adds copyrt
to the center position of 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
或长时间运行/无限循环.
It's also a bad idea to do anything within the context of the EDT that may prevent it from processing further events, like using sleep
or long running/infinite loops.
所有 UI 交互都应该在 EDT 的上下文中执行,所有长时间运行或可能阻塞的任务都应该在单独的线程上运行.
All UI interactions should executed from within the context of the EDT and all long running or potentially blocking tasks should run on a separate thread.
查看Swing 中的并发了解更多详情
更新
如果我尝试运行您的示例,则永远不会出现启动画面,因为 Thread.sleep
阻止显示在屏幕上.您可能"让它工作的事实实际上是侥幸,因为您可能是从主"线程而不是 EDT 调用 showSplash
方法.
If I try to run your example, the splash screen never appears, because Thread.sleep
is preventing to from being show on the screen. The fact that you "might" get it working is actually a fluke, as you are probably calling the showSplash
method from the "main" thread and not the EDT.
相反,如果我将 Thread.sleep
替换为 SwingWorker
,我不仅会显示启动画面,而且还能获得额外的好处控制诸如进度更新和处理启动画面的计划......
Instead, if I replace Thread.sleep
with a SwingWorker
, I not only get the splash screen to show up, but I also get the added benefit of being able to control things like, progress updates and scheduling for disposing of the splash screen...
例如...
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);
}
}
}
如果您愿意,我使用了以下图片...
If you like, I used the following images...