当我调整大小时,JPanel大小问题

时间:2013-04-21 05:29:13

标签: java image swing resize jpanel

我有以下代码来显示和绘制带有缓冲图像的JPanel

我将其大小设置为缓冲图像的大小,但实际上并没有设置。

当我调整大小时显示滚动条,但当我调整大小JFrame大于面板大小或BufferedImage时,当我点击面板大小之外时,我仍然会收到鼠标事件。

我省略了额外的代码。

    public class PaintFrame extends JFrame{    
        private JScrollPane paintScrollPane;
        private Painter painter;
        private JPanel paintPanel;
        private BufferedImage paintImage;
        private Color forgroundColor;

        public PaintFrame(){
            super("Paint");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setPreferredSize(new Dimension(800, 600));
            setLocationByPlatform(true);
            getContentPane().setBackground(Color.black);

            paintImage = new BufferedImage(700, 500, BufferedImage.TYPE_3BYTE_BGR);

            paintPanel = new JPanel(){
                @Override
                public void paint(Graphics g){
                    if(paintImage != null){
                        g.drawImage(paintImage, 0, 0, paintImage.getWidth(), paintImage.getHeight(), null);
                    }
                }
            };
            paintPanel.setBackground(Color.white);
            paintPanel.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent me){
                    mouseClickedOnPaint(me);
                }
            });
            paintPanel.setPreferredSize(new Dimension(paintImage.getWidth(), paintImage.getHeight()));
            paintScrollPane = new JScrollPane(paintPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

            getContentPane().add(paintScrollPane);

            pack();
        }
}

1 个答案:

答案 0 :(得分:2)

正如Quirlom所指出的那样,LayoutManager可以选择根据实现的需要忽略getPreferredSize

如果你担心的只是鼠标事件,你可以通过确定是否在图像中点击鼠标事件来过滤它们。

否则,您需要找到一个更符合您需求的布局管理器......

以下示例仅确定鼠标事件是否属于图像范围...

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClickImage {

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

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

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

    public class ImagePane extends JPanel {

        private BufferedImage background;
        private List<Point> goodPoints;
        private List<Point> badPoints;

        public ImagePane() {
            try {
                background = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/url.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            goodPoints = new ArrayList<>(5);
            badPoints = new ArrayList<>(5);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (getImageBounds().contains(e.getPoint())) {
                        goodPoints.add(e.getPoint());
                    } else {
                        badPoints.add(e.getPoint());
                    }
                    repaint();
                }
            });
        }

        @Override
        public void invalidate() {
            goodPoints.clear();
            badPoints.clear();
            super.invalidate();
        }

        public Rectangle getImageBounds() {
            Rectangle bounds = new Rectangle();
            if (background != null) {
                bounds.x = (getWidth() - background.getWidth()) / 2;
                bounds.y = (getHeight() - background.getHeight()) / 2;
                bounds.width = background.getWidth();
                bounds.height = background.getHeight();
            }

            return bounds;            
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? super.getPreferredSize() : getImageBounds().getSize();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                Rectangle bounds = getImageBounds();
                g2d.drawImage(background, bounds.x, bounds.y, this);

                g2d.setColor(Color.GREEN);
                drawPoints(g2d, goodPoints);
                g2d.setColor(Color.RED);
                drawPoints(g2d, badPoints);

                g2d.dispose();
            }
        }

        protected void drawPoints(Graphics2D g2d, List<Point> points) {
            for (Point p : points) {
                g2d.drawLine(p.x - 4, p.y - 4, p.x + 4, p.y + 4);
                g2d.drawLine(p.x + 4, p.y - 4, p.x - 4, p.y + 4);
            }
        }
    }
}

您可能还想查看A Visual Guide to Layout Managers