2011-09-05 2 views
3

다음 코드에서 JOptionPane.showMessageDialog를 try/catch 블록 내부에서 호출합니다. 하지만 오류가 잡히면 내 JOptionPane은 표시되지만 메시지가 표시되지 않습니다. 누군가가 왜 그리고 어떻게 문제를 해결할 수 있는지 알고 있습니까?JOptionPane.showMessageDialog()에 메시지가 표시되지 않고 표시됩니까?

감사

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

그것은 가능성이 스윙의 동시성 문제의

MyBoardJPannel.java. 더 중요한 것은 절대 페인트 또는 paintComponent 메서드 내에서 이미지를로드해야한다는 것입니다. 생성자 나 다른 곳에서 그것을 읽지 만 paint/paintComponent는 가늘고 빨라야합니다.

문제를 해결하려면 SwingWorker 개체의 이미지를 읽는 것이 좋습니다. SwingWorker의 doInBackground 메소드 내에서 JOptionPane을 호출하는 경우 SwingUtilities.invokeLater (Runnable)를 사용하여 Swing 이벤트 스레드 인 EDT에서 호출해야합니다.

또한 페인트 테두리와 자식을 돌보지 않는 한 JPanel의 페인트 방법을 그리는 일이 거의 필요하지 않습니다. 대신에 paintComponent 메소드를 페인트 해, paintComponent의 super.paintComponent (g) 메소드를 호출하는 것을 잊지 말아주세요. 스윙 그래픽 자습서는 모두 읽어보기를 원할 것입니다.

예를 들어

:

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

정말 모르겠지만, 어쩌면 당신의 패널은 (this를 전달하여)을위한 JOptionPane의 부모로 사용은 눈에 보이지 않는 또는 다른 뭔가 문제가있다. JOptionPaneErrorShowing 생성자 끝에 pack();을 추가하십시오.

내가 아는 것은 데스크탑 문제가 켜졌을 때 GPU 용으로 오래된 Ubuntu 및 이전 NVIDIA 드라이버를 사용할 때이 문제가 발생했다는 것입니다 (오늘의 Compiz Fusion). 오래전에 컴 피즈 (Compiz)라고 불렀다.


아하! 내가 찾은, 당신은 repaint 메서드 내부에 오류가 표시됩니다. 그러지 마! 이미지를 MyBoardPanel 클래스의 생성자 안에로드하고 거기에 오류 메시지를 표시하십시오.

+0

대단히 감사합니다. :) 몰랐습니다. 그런 스윙 문제에 대해 – loloof64

+0

스윙 문제가 아닙니다. 그것은 단순히 당신이 할 수없는 것입니다. 그것을하는 것은 완전히 잘못되었습니다. Java 및 Swing 프로그래밍을 시작하면 이해할 수 있습니다. : D –

+0

실제로 paint 또는 paintComponent 메소드 내부에서 이미지를 다운로드 할 수 있습니다. GUI의 드로잉 속도가 느려지고 GUI가 거의 응답하지 않게되므로 매우 나쁜 아이디어 일뿐입니다. –