在下面的代码中,我在try / catch块中调用JOptionPane.showMessageDialog。但是当错误被捕获时,我的JOptionPane是可见的,但没有任何消息!有人知道为什么以及如何纠正这个问题?
此致
MyBoardJPannel.java
package experimentations.gui;
import java.awt.Graphics;
import java.awt.Image;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MyBoardPannel extends JPanel {
@Override
public void paint(Graphics grahics) {
if (imageToShow == null)
imageToShow = loadImage("sampleImage");
}
/**
* In fact, there are not any image in project => will go to catch clause.
* @param imageName
*/
private void loadImage(String imageName) {
InputStream imageStream = getClass().getResourceAsStream("/"+imageName+".png");
try {
imageToShow = ImageIO.read(imageStream);
}
catch (Exception e) {
String errorMessage = "Failed to load image "+imageName;
System.err.println(errorMessage);
JOptionPane.showMessageDialog(this, errorMessage,
"Image loading error", JOptionPane.ERROR_MESSAGE);
imageToShow = null;
System.exit(1);
}
}
private Image imageToShow;
}
JOptionPaneErrorShowing.java
package experimentations.gui;
import javax.swing.JFrame;
public class JOptionPaneErrorShowing extends JFrame {
public JOptionPaneErrorShowing(){
setTitle("JOptionPane experimentation");
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
add(new MyBoardPannel());
}
/**
* @param args
*/
public static void main(String[] args) {
new JOptionPaneErrorShowing().setVisible(true);
}
}
答案 0 :(得分:4)
这可能是Swing并发问题。但更重要的是,你应该从不从paint或paintComponent方法中加载图像。在构造函数或其他地方读取它,但paint / paintComponent需要精简且非常快。
要解决您的问题,请考虑在SwingWorker对象中读取图像。如果从SwingWorker的doInBackground方法中调用JOptionPane,请务必使用SwingUtilities.invokeLater(Runnable)在Swing事件线程EDT上调用它。
此外,除非您正在处理绘画边框和儿童,否则您几乎不想绘制JPanel的绘画方法。而是在paintComponent方法中绘制,并且不要忘记在该paintComponent覆盖中调用super.paintComponent(g)方法。你会想要阅读Swing图形教程,因为这些都是拼写出来的。
例如:
import java.awt.Graphics;
import java.awt.Image;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MyBoardPannel extends JPanel {
protected static final String SAMPLE_IMAGE = "sampleImage";
Image imageToShow = null;
public MyBoardPannel() {
SwingWorker<Image, Void> mySW = new SwingWorker<Image, Void>() {
@Override
protected Image doInBackground() throws Exception {
return loadImage(SAMPLE_IMAGE);
}
@Override
protected void done() {
try {
imageToShow = get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
};
mySW.execute();
}
@Override
public void paintComponent(Graphics grahics) {
super.paintComponent(grahics);
if (imageToShow != null) {
grahics.drawImage(imageToShow, 0, 0, null);
}
}
private Image loadImage(String imageName) {
InputStream imageStream = getClass().getResourceAsStream(
"/" + imageName + ".png");
try {
return ImageIO.read(imageStream);
} catch (Exception e) {
final String errorMessage = "Failed to load image " + imageName;
System.err.println(errorMessage);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(MyBoardPannel.this, errorMessage,
"Image loading error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
});
}
return null;
}
}
答案 1 :(得分:4)
我真的不知道,但也许您作为JOptionPane的父级使用的面板(通过传递this
)是不可见的,或者还有其他错误。尝试在JOptionPaneErrorShowing构造函数的末尾添加pack();
。
我所知道的是当我使用旧的Ubuntu和旧的Nvidia驱动程序为我的GPU时,当桌面效果打开时(今天的Compiz Fusion)我遇到了这个问题。我不知道它是否已经存在很久以前叫做Compiz。
啊哈!我发现它,你在重绘方法中显示错误。永远不要那样做!将您的图像加载到MyBoardPanel类的构造函数中,并在那里显示错误消息。