2011-09-05 154 views
3

在下面的代码中,我调用了try/catch块内的JOptionPane.showMessageDialog。但是,当错误被捕获时,我的JOptionPane是可见的,但没有任何消息!有人知道为什么以及如何纠正这个问题吗?JOptionPane.showMessageDialog()显示但没有任何消息?

问候

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

@mKorbel:请停止将sscce标签添加到帖子中。这是一个元标记,所以没有必要。 –

回答

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; 
    } 

} 
+0

非常感谢:)这解决了我的问题:)我将在下次关心它:) – loloof64

+0

@Laurent:编辑以显示示例代码 –

+0

非常感谢:) – loloof64

4

我真的不知道,但也许你的面板,您作为JOptionPane的父母使用(通过传递this)不可见或还有别的东西错了。尝试在JOptionPaneErrorShowing构造函数的末尾添加pack();

我知道的是,当我使用旧的Ubuntu和旧的Nvidia驱动程序用于GPU时,出现了这个问题,当桌面效果打开时(Compiz Fusion的今天,我不知道它是否是早就叫Compiz了)。


啊哈!我发现它,你正在重绘方法中显示错误。永远不要这样做!将图像加载到MyBoardPanel类的构造函数中,并在那里显示错误消息。

+0

非常感谢你:)我不知道关于这种Swing问题 – loloof64

+0

这不是Swing问题。这仅仅是你不能做的。这是完全错误的。当你用Java和Swing进行编程时,你会明白。 :D –

+0

您实际上可以下载paint或paintComponent方法中的图像;这只是一个非常糟糕的主意,因为它会减慢GUI的抓取速度并导致GUI几乎不响应。 –