3

在以下代码中,我在 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);
}

}
4

2 回答 2

4

这可能是 Swing 并发问题。但更重要的是,您永远不应该从paint 或paintComponent 方法中加载图像。在构造函数或其他地方阅读它,但paint/paintComponent 需要精简且速度极快。

要解决您的问题,请考虑在 SwingWorker 对象中读取图像。如果您从 SwingWorker 的 doInBackground 方法中调用 JOptionPane,请务必在 Swing 事件线程(EDT)上使用 SwingUtilities.invokeLater(Runnable) 调用它。

此外,除非您正在处理绘制边框和子项,否则您几乎不会想要使用 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;
   }

}
于 2011-09-05T19:41:14.203 回答
4

我真的不知道,但也许您用作 JOptionPane 父级的面板(通过传递this)是不可见的,或者还有其他问题。尝试pack();在 JOptionPaneErrorShowing 构造函数的末尾添加。

我所知道的是,当我为我的 GPU 使用旧的 Ubuntu 和旧的 Nvidia 驱动程序时,当打开桌面效果(今​​天的 Compiz Fusion。我不知道它是否已经被称为 Compiz 时,我遇到了这个问题,很久以前)。


啊哈!我找到了,您在重绘方法中显示错误。永远不要那样做!在 MyBoardPanel 类的构造函数中加载您的图像并在那里显示错误消息。

于 2011-09-05T19:43:10.867 回答