JOptionPane.showMessageDialog () показывает, но без какого-либо сообщения? - PullRequest
3 голосов
/ 05 сентября 2011

В следующем коде я вызываю JOptionPane.showMessageDialog внутри блока try / catch.Но когда ошибка обнаружена, мой 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);
}

}

Ответы [ 2 ]

4 голосов
/ 05 сентября 2011

Я действительно не знаю, но, возможно, ваша панель, которую вы используете в качестве родителя для JOptionPane (путем передачи this), невидима или есть что-то еще не так. Попробуйте добавить pack(); в конце вашего конструктора JOptionPaneErrorShowing.

Что я знаю, так это то, что у меня была эта проблема, когда я использовал старый Ubuntu и старый драйвер Nvidia для своего графического процессора, когда были включены эффекты рабочего стола (Compiz Fusion сегодня. Я не знаю, была ли это уже называется Compiz, что давно).


Aha! Я нашел это, вы отображаете ошибку внутри метода перекраски. Никогда не делай этого! Загрузите ваше изображение в конструктор класса MyBoardPanel и покажите там сообщения об ошибках.

4 голосов
/ 05 сентября 2011

Вероятно, это проблема параллелизма Swing.Но что более важно, вы никогда не должны никогда загружать изображение из метода paint или paintComponent.Прочитайте его в конструкторе или в другом месте, но paint / paintComponent должен быть скудным и невероятно быстрым.

Чтобы решить вашу проблему, рассмотрите возможность чтения на изображении в объекте SwingWorker.Однако если вы вызываете JOptionPane из метода doInBackground SwingWorker, обязательно вызовите его в потоке событий Swing, EDT, используя SwingUtilities.invokeLater (Runnable).

Кроме того, вы вряд ли когда-нибудь захотите нарисоватьв методе рисования JPanel, если вы не заботитесь о рисовании границ и детей.Вместо этого рисуйте в методе paintComponent и не забудьте вызвать метод super.paintComponent (g) в этом переопределении paintComponent.Возможно, вы захотите прочитать учебные пособия по 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;
   }

}
...