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

问题描述 投票:-1回答:1

我正在尝试将图像重新绘制到现有的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)大小。如何解决这个问题?

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

java image jpanel repaint
1个回答
1
投票

根据您的问题和您的意见,我可以说您不想使用除JPanel之外的任何其他类来显示您的图像。让我们解释一下有关利用JPanel来降低你对ImagePanel的担忧。

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

您在互联网上找到的ImagePanel类正在完成您需要做的事情,因为当我们想要覆盖JPanel的方法时,唯一的方法是扩展JPanel,这就是ImagePanel所做的。所以我不明白你想避免使用ImagePanel的原因是什么,因为它只是一个JPanel与覆盖方法paintComponent。因此,为了使您的代码有效,您应该像这样更改它:

private void initComponents() {

    Image123 = new ImagePanel();

    // ... your other codes ...
}

但如果你坚持不命名它ImagePanel,你可以通过内联方式覆盖它来做到这一点。因此,在您实例化initComponents()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中使用的相同代码,这里唯一改变的是名称,我可以告诉你有一个命名类来完成这项工作比上面的内联实现更优雅。现在你可以选择哪一款。

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

希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.