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を呼び出す場合は、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;
   }

}
于 2011-09-05T19:41:14.203 に答える
4

よくわかりませんが、JOptionPaneの親として(を渡すことでthis)使用しているパネルが表示されていないか、何か問題があります。pack();JOptionPaneErrorShowingコンストラクターの最後に追加してみてください。

私が知っているのは、GPUに古いUbuntuと古いNvidiaドライバーを使用していて、デスクトップエフェクトがオンになっているときにこの問題が発生したことです(今日のCompiz Fusion。すでにCompizと呼ばれていたかどうかはわかりませんが、そのずっと前)。


あはは!私はそれを見つけました、あなたはrepaintメソッドの中にエラーを表示しています。絶対にしないでください!MyBoardPanelクラスのコンストラクター内に画像をロードし、そこにエラーメッセージを表示します。

于 2011-09-05T19:43:10.867 に答える