JOptionPane.showMessageDialog()显示但没有任何消息吗? [英] JOptionPane.showMessageDialog() shows but without any message?
问题描述
在下面的代码中,我在try/catch块内调用JOptionPane.showMessageDialog.但是当发现错误时,我的JOptionPane可见,但没有任何消息!!!有人知道为什么以及如何解决这个问题吗?
In the following code, I call JOptionPane.showMessageDialog, inside a try/catch block. But when the error is caught, my JOptionPane is visible but without any message !!! Does someone knows why and how I can correct the problem ?
致谢
MyBoardJPannel.java
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
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);
}
}
推荐答案
很可能是Swing并发问题.但更重要的是,您应该从不永远从paint或paintComponent方法中加载图像.在构造函数中或其他地方读取它,但是paint/paintComponent需要精简且快速.
It's likely a Swing concurrency issue. But more importantly, you should never load an image from within a paint or paintComponent method, ever. Read it in the constructor or elsewhere but paint/paintComponent need to be lean and blazingly fast.
要解决您的问题,请考虑阅读SwingWorker对象中的图像.但是,如果您从SwingWorker的doInBackground方法中调用JOptionPane,请确保使用SwingUtilities.invokeLater(Runnable)在Swing事件线程EDT上调用它.
To solve your issue, consider reading in the image in SwingWorker object. If you call a JOptionPane from within the SwingWorker's doInBackground method though, be sure to call it on the Swing event thread, the EDT, using SwingUtilities.invokeLater(Runnable).
此外,除非您要画边框和孩子,否则您几乎不会想要使用JPanel的绘画方法.而是使用paintComponent方法绘画,并且不要忘记在该paintComponent重写中调用super.paintComponent(g)方法.您将要阅读Swing图形教程,因为它们全都写在那里.
Also, you will hardly ever want to draw in a JPanel's paint method unless you are taking care of painting borders and children. Instead paint in a paintComponent method, and don't forget to call the super.paintComponent(g) method in that paintComponent override. You'll want to read the Swing graphics tutorials as this is all spelled out there.
例如:
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;
}
}
这篇关于JOptionPane.showMessageDialog()显示但没有任何消息吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!