简体   繁体   English

不同JPanel的鼠标侦听器事件

[英]Mouse Listener Event for different JPanels

Is is possible to have a global mouse motion listener that has different effects depending on what JPanel is clicked (with only using one mouse motion listener)? 是否可能有一个全局鼠标动作侦听器,其效果取决于单击的JPanel(仅使用一个鼠标动作侦听器)而有所不同?

For example: I have a JFrame with two added JPanels and a mouse motion listener added to the JFrame. 例如:我有一个JFrame,其中添加了两个JPanels,并且向JFrame中添加了一个鼠标动作侦听器。 I want the screen to resize when I click on one JPanel, but I want the JFrame to be dragged around when I click the other. 我希望在单击一个JPanel时调整屏幕大小,但我希望在单击另一个JPanel时拖动JFrame。 I think this can be done using JLabels using the text of the JLabel to check against, same with a JButton. 我认为可以使用JLabel进行检查,使用JLabel的文本进行检查,与JButton相同。

EDIT: yes this is definitly not the proper way to do things but just wondering if it is possible, if so, how? 编辑:是的,这绝对不是正确的做事方式,只是想知道是否有可能,如果可以,怎么办?

EDIT: Just to make things a bit more clearer, I have one class that extends ActionListener, MouseMotionListener, MouseListener. 编辑:为了使事情更清楚一些,我有一类扩展了ActionListener,MouseMotionListener,MouseListener。 is it possible to have this one class handle all events of a JFrame that has lots of different JPanels attached to it and do something different based off of which JPanel was pressed? 是否有可能让这个类处理JFrame的所有事件,而JFrame上附加了许多不同的JPanels,并且基于按下哪个JPanel而做了不同的事情? (such as having an ID attached to JPanels that I can compare the event.getSource() with) (例如,我可以将event.getSource()与ID关联的ID附加到JPanels上)

First of all, a "global" listener, that does different things for different components, is a bad idea, it places too much logic into a single, couples the code and becomes a maintenance nightmare. 首先,一个“全局”侦听器会对不同的组件执行不同的操作,这是一个坏主意,它将太多的逻辑放在一个逻辑中,使代码耦合,成为维护的噩梦。

Having said that, you could use a single MouseListener add to each component, for example... 话虽如此,您可以对每个组件使用单个MouseListener添加,例如...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

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

                JPanel left = new TestPane();
                JPanel right = new TestPane();

                left.setBackground(Color.RED);
                right.setBackground(Color.BLUE);

                left.setName("left");
                right.setName("right");

                MouseListener listener = new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        System.out.println(((JPanel)e.getSource()).getName());
                    }
                };

                left.addMouseListener(listener);
                right.addMouseListener(listener);

                JFrame frame = new JFrame("Testing");
                frame.setLayout(new GridLayout(0, 2));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(left);
                frame.add(right);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

Then you could simple use MouseEvent#getSource to determine which component triggered the event. 然后,您可以简单地使用MouseEvent#getSource确定哪个组件触发了该事件。 For simplicity, I've supplied a name for each panel and displayed that, I would use some other way to identify the component before making a decision about what to do. 为了简单起见,我为每个面板提供了一个name ,并显示了该name ,在决定要做什么之前,我将使用其他方法来标识组件。

The better solution would be to provide a specific MouseListener which did a specific job to the each panel as required, this becomes much easier to manage, isolates responsibility, decouples the code and becomes easier to maintain and manage 更好的解决方案是提供一个特定的MouseListener ,以便根据需要对每个面板执行特定的工作,这将变得更易于管理,隔离职责,解耦代码并变得易于维护和管理。

I'm not sure if this is the best way to do it, but I just tested it and it does work, at least as far as my code tests it. 我不确定这是否是最好的方法,但我只是对其进行了测试,并且至少在我的代码对其进行测试的范围内,它确实有效。 Find which box the mouse is over when it's pressed and do stuff accordingly. 找到按下鼠标时将鼠标悬停在哪个框上,并相应地进行操作。

public static void main(String[] args) {
    JFrame main = new JFrame("test");
    JPanel first = new JPanel();
    JPanel second = new JPanel();
    first.setSize(400, 500);
    first.setBackground(Color.BLUE);
    second.setBackground(Color.RED);
    second.setSize(400,500);
    main.setSize(800, 500);
    main.add(first);
    first.setLocation(0,0);
    second.setLocation(400, 500);
    main.add(second);
    main.pack();
    main.setVisible(true);
    main.setSize(800, 500);
    main.addMouseListener(new MouseListener() {

        @Override
        public void mousePressed(MouseEvent e) {
            if(first.getBounds().contains(new Point(e.getX(), e.getY())))
            {
                System.out.println("first box");
            }else if(second.getBounds().contains(new Point(e.getX(), e.getY())))
            {
                System.out.println("Second box");
            }
        }
    });
}

EDIT 2 编辑2

This should be your answer, I noticed on debugging that when I click on empty area on the frame I get a component with the name "null.contentPane" so I put it in the condition and it worked!, I hope I helped. 这应该是您的答案,我在调试时注意到,当我单击框架上的空白区域时,我得到一个名称为"null.contentPane"的组件,因此我将其置于条件中并且可以正常工作!希望对我有所帮助。

public class PanelsListener extends JFrame {

public static void main(String[] args) {
    PanelsListener pl = new PanelsListener();
    pl.setSize(700, 700);
    pl.setLayout(new FlowLayout());
    JPanel fp = new JPanel();

    fp.setName("First");
    fp.setSize(200, 200);
    fp.setBorder(new LineBorder(Color.red));
    JPanel sp = new JPanel();
    sp.setName("Second");
    sp.setSize(200, 200);
    sp.setBorder(new LineBorder(Color.blue));
    pl.add(fp);
    pl.add(sp);

    pl.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {
            JPanel pnl = (JPanel) javax.swing.SwingUtilities
                    .getDeepestComponentAt((PanelsListener) e.getSource(),
                            e.getX(), e.getY());
            if (pnl != null && (!pnl.getName().equals("null.contentPane"))) {
                String name = pnl.getName();
                if (name != null) {
                    if (name.equals("First")) {
                        pl.setSize(500, 500);
                    } else if (name.equals("Second")) {
                        pl.setSize(800, 800);
                    }
                    pl.repaint();
                }
            }

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }
    });

    pl.setVisible(true);
}

}

EDIT 1 编辑1

As I understand from your comment, try instead the following: 据您的评论所知,请尝试以下方法:

public class PanelsListener extends JFrame{

public static int  panel_identifier=0;

public static void main(String[] args) {
    PanelsListener pl = new PanelsListener();
    pl.setSize(700, 700);
    pl.setLayout(new FlowLayout());
    JPanel fp=new JPanel();
    fp.setSize(200,200);
    fp.setBorder(new LineBorder(Color.red));
    JPanel sp=new JPanel();
    sp.setSize(200,200);
    sp.setBorder(new LineBorder(Color.blue));

    pl.add(fp);
    pl.add(sp);

    //panel_identifier is used to specify which panel has been clicked.

    fp.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent me) {
           pl.panel_identifier=1;
           pl.mouseClicked(me);
        }
    });
    sp.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent me) {
            pl.panel_identifier=2;
             pl.mouseClicked(me);
        }
    });

    pl.setVisible(true);
}
protected void mouseClicked(MouseEvent me) {
    if(panel_identifier==1)
    {
        this.setSize(500, 500);
        panel_identifier=0;
    }
    else if(panel_identifier==2)
    {
        this.setSize(800, 800);
        panel_identifier=0;
    }

}
}

Normal Solution 普通溶液

public class PanelsListener extends JFrame { 公共类PanelsListener扩展JFrame {

public static void main(String[] args) {
    PanelsListener pl = new PanelsListener();
    pl.setSize(700, 700);
    pl.setLayout(new FlowLayout());
    pl.add(new FirstPanel(pl));
    pl.add(new SecondPanel(pl));
    pl.setVisible(true);
}
}

class FirstPanel extends JPanel {

public FirstPanel(Frame frm) {
    setBorder(new LineBorder(Color.red));
    setSize(200, 200);
    addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            frm.setSize(500, 500);
            frm.repaint();
        }
    });
    addMouseMotionListener(new MouseAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            // do some action when mouse dragged over this panel
        }
    });
 }
 }

 class SecondPanel extends JPanel {

 public SecondPanel(Frame frm) {
    setBorder(new LineBorder(Color.blue));
    setSize(200, 200);
     addMouseListener(new MouseAdapter() {
     @Override
     public void mouseClicked(MouseEvent e) {
     frm.setSize(800,800);
     frm.repaint();
     }
     });

    addMouseMotionListener(new MouseAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            // do some action when mouse dragged over this panel
        }
    });
 }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM