使用JFrame中的Button将图像重新绘制到现有的JPanel?

时间:2018-03-05 11:32:32

标签: java image jpanel repaint

我正在尝试将图像重新渲染到现有的JPanel,当按下该按钮时,我通过拖放在JFrame中创建该图像。

以下是代码:

package photo;


import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.ActionListener;


import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;


public class ImageFrame extends javax.swing.JFrame {

  public ImageFrame() {

      initComponents();

   }

public class ImagePanel extends JPanel{

    public BufferedImage image;

    public ImagePanel() {
       try {                
         image = ImageIO.read(new File("Vampire-full.jpg"));
       } catch (IOException ex) {
            // handle exception...
       }
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null);      
    }

}      


    @Override
    public Component add(Component cmpnt) {
        return super.add(cmpnt); //To change body of generated methods, choose Tools | Templates.
    }



    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        Image123 = new javax.swing.JPanel();
        Import = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout Image123Layout = new javax.swing.GroupLayout(Image123);
        Image123.setLayout(Image123Layout);
        Image123Layout.setHorizontalGroup(
            Image123Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 473, Short.MAX_VALUE)
        );
        Image123Layout.setVerticalGroup(
            Image123Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 327, Short.MAX_VALUE)
        );

        Import.setText("Import");
        Import.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ImportActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(Image123, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(85, 85, 85)
                .addComponent(Import)
                .addGap(0, 24, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(Image123, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(Import)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void ImportActionPerformed(java.awt.event.ActionEvent evt) {                                       
       Image123.repaint();

    }                                      


    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ImageFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ImageFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ImageFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ImageFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
               // new ImageFrame().setVisible(true);
                new ImageFrame().setVisible(true);

            }

        });
    }





    // Variables declaration - do not modify                     
    private javax.swing.JPanel Image123;
    private javax.swing.JButton Import;
    // End of variables declaration                   



}

但是当我点击按钮时,JPanel不显示任何内容。 我已经用鼠标拖动它创建了JPanel(Image123)大小。 如何解决这个问题?

对不起,如果问题看起来很愚蠢。我只是想学习并需要指导如何去做。

1 个答案:

答案 0 :(得分:1)

根据您的问题和您的意见,我可以说您不想使用除JPanel之外的任何其他课程来展示您的形象。让我们解释一下如何利用JPanel来降低对ImagePanel的担忧。

据我所知,当您想要在JPanel中显示图像时,您的选择并不多,您应该在面板上绘制该图像。为此,您应该获取Graphics的{​​{1}}对象,以便能够在该面板上绘制图像或文本等。然后通过阅读JPanel的方法签名,您可以看到某些方法将图形对象作为其输入参数,其中一个是JPanel。正如你可以从它的名字推断它,它负责绘制将在面板上显示的任何内容。因此,通过覆盖它并使用void paintComponent(Graphics g)对象绘制我们的自定义图像,我们可以实现目标。

您在互联网上找到的graphics课程正是您需要做的事情,因为当我们想要覆盖ImagePanel的方法时,唯一的方法是扩展JPanel那就是JPanel的作用。因此,我无法了解您希望避免使用ImagePanel的原因,因为它只是ImagePanel,而且覆盖方法JPanel。因此,要使代码正常工作,您应该像这样更改它:

paintComponent

但如果你坚持不命名private void initComponents() { Image123 = new ImagePanel(); // ... your other codes ... } ,你可以通过内联方式覆盖它来实现。因此,在您ImagePanel实例化initComponents()的{​​{1}}中,您应该以这种方式进行更改:

Image123 = new JPanel();

正如您所看到的,这些代码与您在private void initComponents() { Image123 = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // Let the panel do whatever it was doing before. BufferedImage image = null; try { image = ImageIO.read(new File("Vampire-full.jpg")); } catch (IOException ex) { // handle exception... } g.drawImage(image, 0, 0, null); } }; // ... your other codes ... } 中使用的代码相同,这里唯一更改的是名称,我可以告诉您有一个命名类来完成这项工作比上面的内联实现更优雅。现在您可以选择选择哪一个。

一旦你明白了,你应该知道ImagePanel是一个在第一次创建面板时被调用很多次的方法,每次你调整框架大小,iconify / deiconify等阶段和加载paintComponent内的图片不好。因此,您应该在paintComponent中完成,或者将该图像加载到仅加载一次的位置。

希望这会有所帮助。