将MouseListener添加到绘制的组件

时间:2015-08-09 09:32:58

标签: java jframe jlabel

我有以下课程:

import javax.swing.*;
import java.awt.*;

public class Frame extends JFrame {

    public Frame() {

        // This label draws two black rectangles to the screen.
        JLabel label = new JLabel() {
            @Override
            public void paintComponent(Graphics g) {
                g.clearRect(0, 0, getWidth(), getHeight()); // clears the screen
                g.fillRect(50, 50, 50, 75); // draws first rect
                g.fillRect(150, 50, 50, 75); // draws second rect
            }
        };

        // adds the label to the frame
        add(label);

        // frame properties
        setSize(250, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}

此类绘制到屏幕的矩形。一切都很好。但是我想在两个矩形中添加一个MouseListener,所以我知道用户何时点击两个矩形中的一个。这只是一个例子。也可能有二十个或更多个矩形,而不仅仅是两个。如何将MouseListener添加到我绘制的每个矩形中?使用mouseClicked()方法(由MouseListener实现),然后我想得到被点击的矩形。我怎么能这样做?

3 个答案:

答案 0 :(得分:0)

您可以为此标签添加鼠标侦听器。

import javax.swing.*;
import java.awt.*;

public class MyFrame extends JFrame {
    public MyFrame() {

        // This label draws two black rectangles to the screen.
        JLabel label = new JLabel() {

            @Override
            public void paintComponent(Graphics g) {
                g.clearRect(0, 0, getWidth(), getHeight()); // clears the screen
                g.fillRect(50, 50, 50, 75); // draws first rect
                g.fillRect(150, 50, 50, 75); // draws second rect
            }
        };

        // adds the label to the frame
        add(label);

        label.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseClicked(java.awt.event.MouseEvent evt) {
                int x = evt.getX();
                int y = evt.getY();

                if (x >= 50 && x < 100 && y >= 50 && y <= 125) {
                    rectangleClicked(1);
                } 
                else if (x >= 150 && x < 200 && y >= 50 && y <= 125) {
                    rectangleClicked(2);
                }

            }
        });
        // frame properties
        setSize(250, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void rectangleClicked(int r) {
        System.out.println("Rectangle " + r + " clicked.");
    }

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}

由于您将此应用于多个矩形,因此您可能必须使用变量和一些公式来代替修复值以获得灵活性。

答案 1 :(得分:0)

首先,我建议使用javafx,图形场景对于这种情况是个好主意。

对于挥杆,你可以创建一个awt.Component并自己处理布局/位置。

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;

/**
 *  Created by matt on 8/9/15.
 */
public class ClickableTest {

    public static void main(String[] args){

        JFrame frame = new JFrame("painting example");

        JPanel panel = new JPanel();

        Component panelB = new JPanel(){
            Shape circle = new Ellipse2D.Double(0,0,100, 100);
            public boolean contains(int x, int y){
                return circle.contains(x,y);
            }

            @Override
            public void paintComponent(Graphics g){
                g.setColor(Color.BLUE);
                ((Graphics2D)g).fill(circle);
            }
        };
        panelB.addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent evt){
                System.out.println("clicked");
            }
        });

        //now swing will not modify the size of panel be.
        panel.setLayout(null);
        panel.add(panelB);

        panelB.setBounds(300, 300, 100, 100);
        frame.setContentPane(panel);
        frame.setSize(600, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

}

这当然可以改善。

答案 2 :(得分:0)

  1. 不要扩展JLabel进行自定义绘画。您可以延长JPanelJComponent

  2. 不要在paintComponent()方法中对矩形的绘制进行硬编码。

  3. 在执行自定义绘制的类的构造函数中,您需要创建一个ArrayList来保存要绘制的Rectangles。类似的东西:

    public RectanglePanel extends JPanel
    {
        List<Rectangles> rectangles = new ArrayList<Rectangles>();
    
        public RectanglePanel()
        {
            rectangles.add( new Rectangle(50, 50, 50, 75) );
            rectangles.add( new Rectangle(150, 50, 50, 75) );
        }
    }
    

    现在,在自定义绘制代码中,您遍历List并绘制了所有Rectangles

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g); // this will clear the background for you
    
        for (Rectangle r: rectangles)
        {
            g.fillRect(r.x, r.y, r.width, r.height);
        }
    }
    

    现在在MouseListener中,您可以使用contains(...)的{​​{1}}方法查看点击的Rectangle

    Rectangle

    这是一个更加灵活的解决方案,允许您使用一行代码添加更多矩形。