Jpanel重新粉刷 [英] Jpanel resize on repaint

查看:74
本文介绍了Jpanel重新粉刷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码执行缩放操作。表单中的两个滑块是用于缩放仿射变换的X和Y参数。我在这里问的是,当我更改滑块时图像被缩放,我该如何动态调整我的jpanel,其中这个图像被绘制。

i am having a scaling operation performed in the below code. The two sliders in the form are X and Y parameters for an scaling affine transformation. My ask here is when i change the slider the image is getting scaled, how do i dynamically resize my jpanel in which this image is getting painted.

/*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package newpackage;

    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.geom.AffineTransform;
    import java.awt.image.AffineTransformOp;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;

    /**
     *
     * @author ABC
     */
    public class Swon extends javax.swing.JFrame {

        final BufferedImage img;
        /**
         * Creates new form Swon
         */
        public Swon() throws IOException{
           BufferedImage im=ImageIO.read(new File("C:/Users/ABC/Desktop/I-RIX2012_Final_logo_out.jpg"));
           this.img=new BufferedImage(im.getWidth(),im.getWidth(),BufferedImage.TYPE_BYTE_GRAY);
           this.img.getGraphics().drawImage(im, 0, 0, null);
            initComponents();
        }

        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {

            jPanel1 = new javax.swing.JPanel(){

                // @Override

                //    public void paint(Graphics g)
                //    {
                    //        super.paint(g);
                    //        g.drawImage(img.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_FAST),0,0,null);
                    //    }

            };
            jSlider1 = new javax.swing.JSlider();
            jSlider2 = new javax.swing.JSlider();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            jPanel1.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
            jPanel1.addComponentListener(new java.awt.event.ComponentAdapter() {
                public void componentResized(java.awt.event.ComponentEvent evt) {
                    jPanel1ComponentResized(evt);
                }
            });

            javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
            jPanel1.setLayout(jPanel1Layout);
            jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 268, Short.MAX_VALUE)
            );
            jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 209, Short.MAX_VALUE)
            );

            jSlider1.setMaximum(5);
            jSlider1.setValue(1);
            jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    jSlider1StateChanged(evt);
                }
            });

            jSlider2.setMaximum(5);
            jSlider2.setValue(1);
            jSlider2.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    jSlider2StateChanged(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()
                    .addGap(45, 45, 45)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addContainerGap(242, Short.MAX_VALUE))
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(36, 36, 36)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGap(33, 33, 33)
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(38, Short.MAX_VALUE))
            );

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

        private void jPanel1ComponentResized(java.awt.event.ComponentEvent evt) {
            // TODO add your handling code here:
          //  AffineTransform f=new AffineTransform();

        }

        private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {
            // TODO add your handling code here:

                        AffineTransform scale = AffineTransform.getScaleInstance(jSlider1.getValue(),jSlider2.getValue());       
                    AffineTransformOp op3 = new AffineTransformOp(scale, AffineTransformOp.TYPE_BILINEAR);
                    BufferedImage scaling = new BufferedImage(this.img.getHeight(), this.img.getWidth(), this.img.getType());
                    BufferedImage img1=op3.filter(this.img, scaling);
                    jPanel1.getGraphics().drawImage(img1.getScaledInstance(jPanel1.getWidth(), jPanel1.getHeight(), Image.SCALE_FAST), 0, 0, null);
        }

        private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt) {
            // TODO add your handling code here:
             AffineTransform scale = AffineTransform.getScaleInstance(jSlider1.getValue(),jSlider2.getValue());       
                    AffineTransformOp op3 = new AffineTransformOp(scale, AffineTransformOp.TYPE_BILINEAR);
                    BufferedImage scaling = new BufferedImage(this.img.getHeight(), this.img.getWidth(), this.img.getType());
                    BufferedImage img1=op3.filter(this.img, scaling);
                    jPanel1.getGraphics().drawImage(img1.getScaledInstance(jPanel1.getWidth(), jPanel1.getHeight(), Image.SCALE_FAST), 0, 0, null);
        }

        /**
         * @param args the command line arguments
         */
        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(Swon.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(Swon.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(Swon.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(Swon.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() {
                    try {
                        new Swon().setVisible(true);
                    } catch (IOException ex) {
                        Logger.getLogger(Swon.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
        // Variables declaration - do not modify
        public javax.swing.JPanel jPanel1;
        private javax.swing.JSlider jSlider1;
        private javax.swing.JSlider jSlider2;
        // End of variables declaration
    }


推荐答案

好吧,首先,当重新绘制面板时,不要执行 this.img.getGraphics()。drawImage(im,0,0,null),图像不会更新。您需要覆盖 JComponent paintComponent 方法(更喜欢 JPanel )并以适当的比例重新绘制图像。

Alright, firstly, don't do this.img.getGraphics().drawImage(im, 0, 0, null), when the panel is repainted, the image would not be updated. You need to override the paintComponent method of a JComponent (prefer JPanel) and repaint the image at the appropriate scale.

其次,您需要将图像面板放置在能够实际关注大小的布局上面板(例如 GridBagLayout )。为此,请覆盖 getPreferredSize 方法并返回缩放图像的大小...

Secondly, you need to place the image panel onto a layout that is capable of actually caring about the size of the panel (such as GridBagLayout). To do this, override the getPreferredSize method and return the size of the scaled image...

public class ResizableImagePane {

    public static void main(String[] args) {
        new ResizableImagePane();
    }

    public ResizableImagePane() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ScalerPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class ScalerPane extends JPanel {
        private JSlider slider;
        private ImagePane imagePane;
        public ScalerPane() {

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            gbc.gridx = 0;
            gbc.gridy = 0;

            imagePane = new ImagePane();

            add(imagePane, gbc);

            gbc.gridy = 1;
            gbc.weightx = 0;
            gbc.weighty = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            slider = new JSlider();
            slider.setMinimum(1);
            slider.setMaximum(100);
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.SOUTH;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(slider, gbc);

            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent ce) {
                    imagePane.setZoom(slider.getValue() / 100f);
                }
            });
            slider.setValue(100);
        }
    }

    protected class ImagePane extends JPanel {
        private BufferedImage background;
        private Image scaled;
        private float zoom;
        public ImagePane() {
            try {
                background = ImageIO.read(new File("path/to/your/image"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setZoom(1f);
            setBorder(new LineBorder(Color.RED));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(scaled.getWidth(this), scaled.getHeight(this));
        }

        public void setZoom(float zoom) {
            this.zoom = zoom;
            int width = Math.round(background.getWidth() * zoom);
            scaled = background.getScaledInstance(width, -1, Image.SCALE_SMOOTH);

            invalidate();
            revalidate();
            repaint();
        }

        public float getZoom() {
            return zoom;
        }

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

            int x = (getWidth() - scaled.getWidth(this)) / 2;
            int y = (getHeight() - scaled.getHeight(this)) / 2;

            grphcs.drawImage(scaled, x, y, this);
        }
    }
}

这篇关于Jpanel重新粉刷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆