代码之家  ›  专栏  ›  技术社区  ›  Azmisov

自定义Java鼠标侦听器?

  •  4
  • Azmisov  · 技术社区  · 14 年前

    首先,我是作为一名网站程序员来到Java的。在JavaScript中,要添加mousemove、mouseover或click事件,只需调用addEventListener函数。根据我对Java的有限经验,您不能只从任何对象实现MouseListener接口。

    基本上,到目前为止,我所拥有的是一个JPanel,它绘制一些具有x/y/width/height值的形状(带有绘制方法的CustomShape对象)。我想向shape对象添加某种类型的鼠标侦听器,这样我就可以为shape触发move/roll/click事件。仅仅实现CustomShape对象的MouseListener接口是行不通的(我认为这是显而易见的原因)。我已经查找了如何设计自定义事件侦听器,但似乎不可能创建自定义鼠标侦听器。

    最后,我将鼠标侦听器添加到JPanel中,然后遍历所有的shape对象。如果shape对象附加了一个“listener”,并且鼠标坐标验证了鼠标事件的发生,则它会触发该方法。最初,它很好,但随着应用程序的进一步开发,它开始变得非常混乱。另外,如果不复制一堆代码,我将无法将形状对象/接口复制到另一个应用程序。

    举个简单的例子:(实际代码相当大)

    Interface CustomShape{
        int width, height, x, y;
        void paint(Graphics g);
    }
    
    public class StarShape implements CustomShape{
        int width, height, x, y;
        public StarShape(){
            width = 100;
            height = 100;
            x = 50;
            y = 50;
        }
        void paint(Graphics g){
            g.setColor(Color.black);
            g.draw(new Rectangle(x,y,width,height));
        }
    }
    
    public class Main extends JPanel{
        StarShape check = new StarShape();
        public Main(){  }
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            check.paint(g);
        }
    }
    

    所以,我想知道是否有一种干净的方法来实现某种类型的鼠标侦听器的“手绘”形状。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Mike Clark    14 年前

    我做你想做的事的方法。编译,运行,读取:-)

    Example01.java . 编译并运行它。)

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Example01 {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame jf = new JFrame();
                    MainPanel mainPanel = new MainPanel();
                    jf.add(mainPanel);
                    jf.setSize(640, 480);
                    jf.setLocationRelativeTo(null);
                    jf.setVisible(true);
                }
            });
        }
    }
    
    class MainPanel extends JPanel {
        StarShape check1 = new StarShape();
        StarShape check2 = new StarShape();
    
        public MainPanel() {
            check1.setName("check1");
            check2.setName("check2");
            check1.addMouseListener(new MyMouseListener(check1));
            check2.addMouseListener(new MyMouseListener(check2));
            this.add(check1);
            this.add(check2);
        }
    }
    
    class StarShape extends JComponent {
        public StarShape() {
            this.setPreferredSize(new Dimension(100, 100));
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.black);
            Graphics2D g2d = (Graphics2D) g;
            int x = 0;
            int y = 0;
            int width = this.getWidth() - 1;
            int height = this.getHeight() - 1;
            g2d.draw(new Rectangle(x, y, width, height));
        }
    }
    
    class MyMouseListener implements MouseListener {
        private final JComponent component;
    
        public MyMouseListener(JComponent component) {
            this.component = component;
        }
    
        public void mouseClicked(MouseEvent e) {
            System.out.println("mouseClicked: " + component.getName());
        }
    
        public void mouseEntered(MouseEvent e) {
            System.out.println("mouseEntered: " + component.getName());
            Dimension preferredSize = component.getPreferredSize();
            preferredSize.height += 20;
            preferredSize.width += 20;
            component.setPreferredSize(preferredSize);
            component.invalidate();
            SwingUtilities.getWindowAncestor(component).validate();
        }
    
        public void mouseExited(MouseEvent e) {
            System.out.println("mouseExited: " + component.getName());
            Dimension preferredSize = component.getPreferredSize();
            preferredSize.height -= 20;
            preferredSize.width -= 20;
            component.setPreferredSize(preferredSize);
            component.invalidate();
            SwingUtilities.getWindowAncestor(component).validate();
        }
    
        public void mousePressed(MouseEvent e) {
            System.out.println("mousePressed: " + component.getName());
        }
    
        public void mouseReleased(MouseEvent e) {
            System.out.println("mouseReleased: " + component.getName());
        }
    }
    
        2
  •  5
  •   vanza    14 年前

    为了能够接收事件,“Shape”对象应该扩展java.awt.Component(或javax.swing.JComponent)。然后,您可以将它们作为一个孩子添加到JPanel中,它们将接收事件,您可以直接向它们添加侦听器。

        3
  •  1
  •   Community CDub    8 年前

    你能做的就是把它的形状拉长 JPanel .

    public abstract class CustomShape extends JPanel {
    
        public CustomShape(){
            setOpaque(false);
        }
    
        public abstract void paintShape(Graphics g);
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            paintShape(g);
        }
    
    }
    

    然后可以直接在形状上添加侦听器。

    面板 ,并设置 LayoutManager null

    阅读有关手动布局组件的更多信息 here . 如果你不喜欢这种方法,看看我的答案 this