проблема с добавлением изображения в JFrame

У меня проблемы с добавлением картинки в JFrame, видимо чего-то не хватает или написано неправильно. вот классы:

основной класс:

public class Tester

    {
        public static void main(String args[])
        {
            BorderLayoutFrame borderLayoutFrame = new BorderLayoutFrame();
            borderLayoutFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            borderLayoutFrame.setSize(600,600);
            borderLayoutFrame.setVisible(true);
        }
    }

public class BorderLayoutFrame extends JFrame implements ActionListener 
 {
     private JButton buttons[]; // array of buttons to hide portions
     private final String names[] = { "North", "South", "East", "West", "Center" };
     private BorderLayout layout; // borderlayout object
     private PicPanel picture = new PicPanel();

     // set up GUI and event handling

     public BorderLayoutFrame()
     {
         super( "Philosofic Problem" );
         layout = new BorderLayout( 5, 5 ); // 5 pixel gaps
         setLayout( layout ); // set frame layout
         buttons = new JButton[ names.length ]; // set size of array

         // create JButtons and register listeners for them

         for ( int count = 0; count < names.length; count++ ) 
         {
             buttons[ count ] = new JButton( names[ count ] );
             buttons[ count ].addActionListener( this );
         }
         add( buttons[ 0 ], BorderLayout.NORTH ); // add button to north
         add( buttons[ 1 ], BorderLayout.SOUTH ); // add button to south
         add( buttons[ 2 ], BorderLayout.EAST ); // add button to east
         add( buttons[ 3 ], BorderLayout.WEST ); // add button to west
         add( picture, BorderLayout.CENTER ); // add button to center
    }

    // handle button events

    public void actionPerformed( ActionEvent event )
    {

    } 

  }

Я попытался добавить изображение в центр макета.

вот класс изображения:

public class PicPanel extends JPanel
{
    Image img;
    private int width = 0;
    private int height = 0;

    public PicPanel()
    {
        super();
        img = Toolkit.getDefaultToolkit().getImage("table.jpg");
    }
    public void paintComponent(Graphics g)
    {
         super.paintComponents(g);
         if ((width <= 0) || (height <= 0))
         {
             width = img.getWidth(this);
             height = img.getHeight(this);
         }
         g.drawImage(img,0,0,width,height,this);
    }
}

Пожалуйста, помогите, в чем проблема? Спасибо

Кстати: я использую eclipse, в каком каталоге должно быть изображение?


person firestruq    schedule 09.06.2010    source источник
comment
хороший вопрос - в чем именно является проблема? ;-)   -  person Andreas Dolk    schedule 09.06.2010
comment
Вы пытались просто добавить панель изображений в пустой JFrame? Что произойдет, если вы сделаете это?   -  person jjnguy    schedule 09.06.2010


Ответы (2)


Есть несколько проблем с кодом, который вы опубликовали:

  • Вы должны использовать getContentPane().add() вместо простого add() в своем классе BorderLayoutFrame.
  • Вы действительно должны использовать SwingUtilities.invokeLater() для запуска вашего JFrame из класса тестера. Что-то вроде этого:

 SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        System.setProperty("DEBUG_UI", "true");

        BorderLayoutFrame blf = new BorderLayoutFrame();
        blf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        blf.setSize(600,600);
        blf.setVisible(true);
    }
});
  • Не используйте Toolkit для загрузки изображений! В следующем коде, если «Table.jpg» находится в том же пакете, что и PicPanel, изображение загрузится правильно.

public PicPanel() {
    super();
    try {
        rUrl = getClass().getResource("Table.jpg");
        if (rUrl != null) {
            img = ImageIO.read(rUrl);
        }
    } catch (IOException ex) {
        Logger.getLogger(PicPanel.class.getName()).log(Level.SEVERE, null, ex);
    }
}
  • В PicPanel.PaintComponent() вы называете super.paintComponents() буквой "s" является typeo?
  • В PicPanel.PaintComponent() вам не нужны все параметры ширины/высоты, просто сделайте следующее:

    g.drawImage(img, 0, 0, getWidth(), getHeight(), this);

И избегайте вызова super.paintComponent вместе, потому что вы рисуете изображение, почему вы хотите, чтобы панель вообще рисовала?

Моя окончательная реализация ваших вещей:

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                System.setProperty("DEBUG_UI", "true");

                BorderLayoutFrame blf = new BorderLayoutFrame();
                blf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                blf.setSize(600,600);
                blf.setVisible(true);
            }
        });
    }

}

class BorderLayoutFrame extends JFrame implements ActionListener
{
    private final BorderLayout layout;
    private final JButton[] buttons;
    private final String names[] = {"North", "South", "East", "West", "Center"};

    public BorderLayoutFrame() {
        super( "Philosofic Problem" );
        layout = new BorderLayout( 5, 5 );
        getContentPane().setLayout( layout );
        buttons = new JButton[ names.length ];

        for (int i=0; i<names.length; i++)
        {
            buttons[i] = new JButton(names[i]);
            buttons[i].addActionListener(this);
        }

        getContentPane().add(buttons[0], BorderLayout.NORTH);
        getContentPane().add(buttons[1], BorderLayout.SOUTH);
        getContentPane().add(buttons[2], BorderLayout.EAST);
        getContentPane().add(buttons[3], BorderLayout.WEST);
        getContentPane().add(new PicPanel(), BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent e) {
        // ignore
    }

}

class PicPanel extends JPanel
{
    private URL rUrl;
    private BufferedImage img;



    public PicPanel() {
        super();
        try {
            rUrl = getClass().getResource("UtilBtn.png");
            if (rUrl != null) {
                img = ImageIO.read(rUrl);
            }
        } catch (IOException ex) {
            Logger.getLogger(PicPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        //super.paintComponent(g);

        g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
    }

}
person Mike Caron    schedule 09.06.2010

В Eclipse, если вы используете путь "table.jpg", вам нужно, чтобы это изображение находилось на верхнем уровне проекта.

Дополнительную информацию о структуре проекта Eclipse см. в этом вопросе о переполнении стека.

Вы можете попробовать использовать ImageIcon для отображения изображения вместо его рисования на панели.

Следующий код создаст файл ImageIcon, который вы можете просто добавить в файл JPanel.

ImageIcon pic = new ImageIcon(getClass().getResource("myimage.jpeg");

Это использует причудливый способ загрузки изображения, чтобы оно работало при помещении в файл Jar.

person jjnguy    schedule 09.06.2010
comment
Пробовал, ошибок нет, но на рамке ничего не появляется кроме кнопок. - person firestruq; 09.06.2010
comment
@firestruq, я добавил кое-что еще, что вы можете попробовать, к моему ответу. - person jjnguy; 09.06.2010
comment
ImageIcon будет работать так же, как код ImageIO, который я разместил в своем ответе. - person Mike Caron; 09.06.2010