Java 灰色闪屏,因为没有重新喷漆
我正在为我的应用程序制作一个启动屏幕。它只是由Graphics2D绘制的静态缓冲区图像,在JFrame中,没有任何装饰。我的问题是:窗口有时画得不好,这意味着它并不总是包含我的图像,有时只是灰色的。我已经试过在第二个线程中创建闪屏,但没用。我可以调用splashScreen.repaint()每一行,但这是胡说八道。。。这是我的密码:Java 灰色闪屏,因为没有重新喷漆,java,image,swing,splash-screen,graphics2d,Java,Image,Swing,Splash Screen,Graphics2d,我正在为我的应用程序制作一个启动屏幕。它只是由Graphics2D绘制的静态缓冲区图像,在JFrame中,没有任何装饰。我的问题是:窗口有时画得不好,这意味着它并不总是包含我的图像,有时只是灰色的。我已经试过在第二个线程中创建闪屏,但没用。我可以调用splashScreen.repaint()每一行,但这是胡说八道。。。这是我的密码: package SeriousSteve.MapEditor; import java.awt.Graphics2D; import java.awt.imag
package SeriousSteve.MapEditor;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
/**
* Simple splash screen, contains only the image.
*
* @author m4tx3
*/
public class SplashScreen extends JFrame {
private BufferedImage image;
/**
* Constructor. Creates a window with splash screen, loads an image at the
* URL specified in imageURL, and finally displays this image.
*
* @param imageURL URL to the image that you want to put on the splash
* screen.
*/
public SplashScreen() {
super("Splash screen");
}
public void createSplashScreen(final URL imageURL) {
try {
image = ImageIO.read(imageURL);
} catch (IOException ex) {
Logger.getLogger(SplashScreen.class.getName()).
log(Level.SEVERE, null, ex);
}
setUndecorated(true);
setSize(image.getWidth(), image.getHeight());
setLocationRelativeTo(null);
setVisible(true);
createGraphics();
repaint();
}
/**
* Creates a graphics context and draws a splash screen.
*/
private void createGraphics() {
Graphics2D g = (Graphics2D) getGraphics();
g.drawImage(image, 0, 0, null);
}
/**
* Closes the splash screen and frees the memory taken by the image.
*
* Call this function when the loading is complete.
*/
public void close() {
setVisible(false);
image = null;
dispose();
}
}
以及:
顺便说一句,我正在创建自己的闪屏类,因为我在一个jar中有两个应用程序(游戏和地图编辑器)。。。我只想在地图编辑器中显示初始屏幕,所以我不能修改清单文件
注意覆盖
绘制
方法,而不是创建自己的图形
@Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, null);
}
每次调用
repaint
,它都会依次调用此方法。默认情况下,此方法将用背景色(灰色)填充JFrame
。使用JLabel
。直接在画框上画画是个坏主意
看这个,它每次都有效:
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
/**
* Simple splash screen, contains only the image.
*
* @author m4tx3
*/
public class SplashScreen extends JFrame {
/**
* Constructor. Creates a window with splash screen, loads an image at the URL specified in imageURL, and finally displays this image.
*
* @param imageURL
* URL to the image that you want to put on the splash screen.
*/
public SplashScreen() {
super("Splash screen");
}
public void createSplashScreen(final URL imageURL) {
JLabel splashLabel = new JLabel(new ImageIcon(imageURL));
add(splashLabel);
setSize(splashLabel.getPreferredSize());
setUndecorated(true);
setLocationRelativeTo(null);
setVisible(true);
repaint();
}
/**
* Closes the splash screen and frees the memory taken by the image.
*
* Call this function when the loading is complete.
*/
public void close() {
setVisible(false);
dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new SplashScreen().createSplashScreen(new URL(
"http://art.gnome.org/download/themes/splash_screens/1334/Splash-GnomeDarkSplashScreen.png"));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
1) g.drawImage(image,0,0,null)代码>
应该是
g2d.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), SplashScreen.this);
2) 我建议使用JWindow
或未修饰的JDialog
而不是@m4tx:您不应该直接在JFrame上绘制。纪尧姆得到了一个更好的答案,1+给他,虽然最好还是使用Java附带的。@HovercraftFullOfEels他不能使用SplashScreen
类,因为他用一个罐子包装了两个应用程序,他只想让其中一个应用程序显示SplashScreen。@Jeffrey:我想这可以通过将SplashScreen行从清单中删除来解决,而是指定他运行jar文件时是否在命令行上使用splashscreen。@气垫船装满鳗鱼是的,我知道我可以这样做。。。但是,哪个普通(读作:非极客)用户会知道他必须通过命令行运行那个应用程序呢?(特别是在Windows上)我不想创建启动脚本。我自己的类不限制我。@ M4TX:考虑1)使用单独的JAR文件,或者2)使用一个安装程序,为你创建正确的JAR文件的快捷方式。YUP也是有效的。关于使用JWindow或JDialog的好建议。尽管有一件事我喜欢JFrame:任务栏上有一个图标。@Guillaume Polet Aaach对于基本教程建议使用JFrame,+1我不得不添加drawComponents(getGraphics())代码>,但现在它可以工作了!非常感谢:)
g2d.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), SplashScreen.this);
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JWindow;
public class SplashScreen extends JWindow {
private JProgressBar bar;
private JLabel label;
public SplashScreen(final BufferedImage img) {
JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(img, 0, 0, img.getWidth(), img.getHeight(),
SplashScreen.this);
}
};
panel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
Container content = getContentPane();
content.setLayout(new BorderLayout());
content.add(panel, BorderLayout.NORTH);
content.add(label = new JLabel(), BorderLayout.CENTER);
content.add(bar = new JProgressBar(), BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
}
public void setMessage(String msg) {
label.setText(msg);
pack();
}
public void setProgress(int prog) {
bar.setValue(prog);
}
public void setIndeterminateProgress(boolean value){
bar.setIndeterminate(value);
}
}