java JOptionPane.showMessageDialog() 显示但没有任何消息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7312102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JOptionPane.showMessageDialog() shows but without any message?
提问by loloof64
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 ?
在以下代码中,我在 try/catch 块内调用 JOptionPane.showMessageDialog。但是当错误被捕获时,我的 JOptionPane 是可见的但没有任何消息!!!有人知道为什么以及如何解决问题吗?
Regards
问候
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);
}
}
回答by Hovercraft Full Of Eels
It's likely a Swing concurrency issue. But more importantly, you should neverload 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.
这很可能是 Swing 并发问题。但更重要的是,永远不要从paint 或paintComponent 方法中加载图像。在构造函数或其他地方读取它,但paint/paintComponent 需要精简且极快。
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).
要解决您的问题,请考虑读取 SwingWorker 对象中的图像。但是,如果您从 SwingWorker 的 doInBackground 方法中调用 JOptionPane,请务必使用 SwingUtilities.invokeLater(Runnable) 在 Swing 事件线程 EDT 上调用它。
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.
此外,除非您负责绘制边框和子项,否则您几乎不会想使用 JPanel 的绘制方法进行绘制。而是在paintComponent 方法中绘制,并且不要忘记在该paintComponent 覆盖中调用super.paintComponent(g) 方法。您需要阅读 Swing 图形教程,因为这里有详细说明。
For example:
例如:
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;
}
}
回答by Martijn Courteaux
I don't really know, but maybe your panel you use as parent of the JOptionPane (by passing this
) is invisible or there is something else wrong. Try adding pack();
at the end of your JOptionPaneErrorShowing constructor.
我真的不知道,但也许您用作 JOptionPane 父级的面板(通过传递this
)是不可见的,或者还有其他问题。尝试pack();
在 JOptionPaneErrorShowing 构造函数的末尾添加。
What I know is that I had this problem when I was using an old Ubuntu and old Nvidia driver for my GPU, when the desktop effects were turned on (the Compiz Fusion of today. I don't know if it was already called Compiz, that long ago).
我所知道的是,当我在 GPU 上使用旧的 Ubuntu 和旧的 Nvidia 驱动程序时,当打开桌面效果(今天的 Compiz Fusion。我不知道它是否已经被称为 Compiz,很久以前)。
Aha! I found it, you are displaying the error inside the repaint method. Never do that! Load your image inside the constructor of the MyBoardPanel class and show error messages over there.
啊哈!我找到了,您在 repaint 方法中显示了错误。永远不要那样做!在 MyBoardPanel 类的构造函数中加载您的图像并在那里显示错误消息。