java - 单击绘制的对象

标签 java swing graphics jpanel paintcomponent

我有一个名为 Shape 的类,它继承自 JPanel。

许多子类依次扩展 Shape 类,每个子类对应一种形状。

每个形状都有自己覆盖的 paint() 方法,该方法绘制相应的形状。

我希望能够点击任何形状,现在我正在尝试实现这个逻辑。请注意,每个形状都已添加到 arrayList。

但是,contains 语句总是返回 false,即使我已经明确地在形状内部单击也是如此。

有什么想法吗?

最佳答案

永远不要覆盖 JPanel 中的 paint() 而不是 paintComponent(..)

我不太确定我是否理解,但是我举了一个简短的例子,希望对您有所帮助。 基本上它是一个简单的 JFrame 和一个 DrawingPanel(我自己的扩展 JPanel 的类,并在上面绘制形状)。此面板将创建形状(只有 2 个用于测试)将它们添加到 ArrayList 并通过 paintComponent(..) 将它们绘制到 JPanel 和一个 for 循环,它还有一个 MouseAdapter 来检查 JPanel 上的用户 mouseClicked(..) evnets .单击时,我们遍历 ArrayList 中的每个 Shape 并检查 Shape 是否包含该点,如果包含则打印其类名并使用 instance of 检查单击的是什么类型的 Shape 并打印适当的消息:

enter image description here

输出(点击两个形状后):

Clicked a java.awt.geom.Rectangle2D$Double

Clicked a rectangle

Clicked a java.awt.geom.Ellipse2D$Double

Clicked a circle

ShapeClicker.java:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ShapeClicker {

    public ShapeClicker() {
        JFrame frame = new JFrame();
        frame.setTitle("Shape Clicker");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);

        initComponents(frame);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        //create frame and components on EDT
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ShapeClicker();
            }
        });
    }

    private void initComponents(JFrame frame) {
        frame.add(new ShapePanel());
    }
}

//custom panel
class ShapePanel extends JPanel {

    private Shape rect = new Rectangle2D.Double(50, 100, 200, 100);
    private Shape cirlce = new Ellipse2D.Double(260, 100, 100, 100);
    private Dimension dim = new Dimension(450, 300);
    private final ArrayList<Shape> shapes;

    public ShapePanel() {
        shapes = new ArrayList<>();
        shapes.add(rect);
        shapes.add(cirlce);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                super.mouseClicked(me);
                for (Shape s : shapes) {
                    
                    if (s.contains(me.getPoint())) {//check if mouse is clicked within shape
                        
                        //we can either just print out the object class name
                        System.out.println("Clicked a "+s.getClass().getName());
                        
                        //or check the shape class we are dealing with using instance of with nested if
                        if (s instanceof Rectangle2D) {
                            System.out.println("Clicked a rectangle");
                        } else if (s instanceof Ellipse2D) {
                            System.out.println("Clicked a circle");
                        }
                        
                    }
                }
            }
        });
    }

    @Override
    protected void paintComponent(Graphics grphcs) {
        super.paintComponent(grphcs);
        Graphics2D g2d = (Graphics2D) grphcs;
        for (Shape s : shapes) {
            g2d.draw(s);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return dim;
    }
}

关于java - 单击绘制的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12933592/

相关文章:

java - 避免数据库命中

java 128位结构位操作

java - RGB 创建时没有语句错误

java - 将项目放入带有网格布局的面板中

java - 为什么 Netbeans 不能正确显示波斯语字符

Java Programming for the Absolute Beginner 中列出的 Java 挑战

java - 韩文字符在 JTextField 上显示为空框

java - 在 JTable 中查找并选择

c++ - 为每一帧分配一个新缓冲区以防止屏幕撕裂

java - 简单的音乐可视化工具