来自JComponents的MouseEvents

时间:2016-01-09 15:01:29

标签: java swing mouseevent listener

我使用swing写了一个游戏,但我遇到鼠标事件的问题。

我有一个扩展JFrame的Panel,它添加了一个Board对象,其中包含" Paintable"列表中的对象。这些对象包含具有可绘制对象的其他列表,并且它一直调用子对象,直到它到达实际绘制它的最低对象。

public interface Paintable {
   void paint(Graphics2D g);
}

我写了一个小例子来说明我的意思:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

public class MainPanel extends JPanel {

    List<Patch> patches = new ArrayList<>();

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        MainPanel mainPanel = new MainPanel();
        mainPanel.addPatches();

        mainPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("out");

                // I want to access the clicked object here
            }
        });

        frame.add(mainPanel);
        frame.setSize(1000, 800);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void addPatches() {
        Random random = new Random();

        for (int i = 0; i < 100; i++) {
            patches.add(new Patch(random.nextInt(1000), random.nextInt(800), 30, 30));
        }
    }

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

        patches.forEach(patch -> patch.paintComponent(g));
    }
}

绘制对象的类:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Patch extends JComponent {

    int x;
    int y;
    int width;
    int height;

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

        g.fillRect(x, y, width, height);
    }

    public Patch(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("in");
            }
        });
    }
}

我想在mouseClicked事件中访问MainPanel中单击的Patch。我怎么能这样做?

我还尝试在Patch类中添加一个监听器,但这也不起作用。

1 个答案:

答案 0 :(得分:2)

如果您检查了Patch组件的大小,您可能会发现它们为0,0或1,1,无论它们是非常小的,因为它们的首选大小非常小。我建议不要让Patch扩展JComponent,而是让它成为一个逻辑非组件实体,并通过使用Shape派生对象,由MainPanel对象保存在集合(如ArrayList)中的对象,并给它鼠标单击属性,以及在添加到MainPanel的MouseListener中被通知可能的鼠标按下。

如,

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

@SuppressWarnings("serial")
public class MainPanel extends JPanel {
    private static final Color[] COLORS = { Color.red, Color.orange, Color.yellow, Color.blue,
            Color.green, Color.cyan, Color.magenta };
    private List<Patch> patches = new ArrayList<>();
    Random random = new Random();

    public MainPanel() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // use mousePressed not mouseClicked

                // go backwards for correct handling of overlaps
                for (int i = patches.size() - 1; i >= 0; i--) {
                    if (patches.get(i).contains(e.getPoint())) {
                        System.out.println("pressed");
                        e.consume();
                        return;
                    }
                }
                System.out.println("out");
            }
        });
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        MainPanel mainPanel = new MainPanel();
        mainPanel.addPatches();

        frame.add(mainPanel);
        frame.setSize(1000, 800);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void addPatches() {

        for (int i = 0; i < 100; i++) {
            Color c = COLORS[random.nextInt(COLORS.length)];
            patches.add(new Patch(random.nextInt(1000), random.nextInt(800), 30, 30, c));
        }
    }

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

        patches.forEach(patch -> patch.draw(g));
    }
}

class Patch {

    private int x;
    private int y;
    private int width;
    private int height;
    private Color color;
    private Rectangle rectangle;

    public Patch(int x, int y, int width, int height, Color color) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.color = color;
        rectangle = new Rectangle(x, y, width, height);
    }

    public boolean contains(Point p) {
        return rectangle.contains(p);
    }

    public void draw(Graphics g) {
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillRect(x, y, width, height);
        g.setColor(oldColor);
    }

}
相关问题