2011-09-05 150 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幾乎不響應。 –