不同 JPanel 的鼠标侦听器事件
Mouse Listener Event for different JPanels
是否可以有一个全局鼠标移动侦听器,它根据单击的 JPanel 具有不同的效果(仅使用一个鼠标移动侦听器)?
例如:我有一个 JFrame,其中添加了两个 JPanel 和一个添加到 JFrame 的鼠标运动侦听器。我希望在单击一个 JPanel 时调整屏幕大小,但我希望在单击另一个时拖动 JFrame。我认为这可以使用 JLabel 来完成,使用 JLabel 的文本进行检查,与 JButton 相同。
编辑:是的,这绝对不是正确的做事方式,只是想知道是否可行,如果可行,怎么做?
编辑:为了让事情更清楚一点,我有一个 class 扩展了 ActionListener、MouseMotionListener、MouseListener。是否可以让这个 class 处理一个 JFrame 的所有事件,这个 JFrame 有很多不同的 JPanel 附加到它上面,并根据按下的 JPanel 做一些不同的事情? (例如将 ID 附加到 JPanels,我可以将 event.getSource() 与之进行比较)
我不确定这是否是最好的方法,但我刚刚测试了它并且它确实有效,至少就我的代码测试而言。找到鼠标在按下时悬停在哪个方框上并相应地执行操作。
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");
}
}
});
}
编辑 2
这应该是你的答案,我在调试时注意到,当我点击框架上的空白区域时,我得到了一个名为 "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);
}
}
编辑 1
根据您的评论我了解到,请尝试以下操作:
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;
}
}
}
正解
public class 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
}
});
}
}
首先,一个 "global" 监听器,它为不同的组件做不同的事情,这是一个坏主意,它将太多的逻辑放在一个单一的逻辑中,耦合代码并成为维护的噩梦。
话虽如此,您可以使用单个 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);
}
}
}
然后您可以简单地使用 MouseEvent#getSource
来确定哪个组件触发了事件。为简单起见,我为每个面板提供了一个 name
并显示了它,在决定要做什么之前,我会使用其他方式来识别组件。
更好的解决方案是提供一个特定的MouseListener
,它根据需要对每个面板执行特定的工作,这变得更容易管理、隔离责任、解耦代码并且更容易维护和管理
是否可以有一个全局鼠标移动侦听器,它根据单击的 JPanel 具有不同的效果(仅使用一个鼠标移动侦听器)?
例如:我有一个 JFrame,其中添加了两个 JPanel 和一个添加到 JFrame 的鼠标运动侦听器。我希望在单击一个 JPanel 时调整屏幕大小,但我希望在单击另一个时拖动 JFrame。我认为这可以使用 JLabel 来完成,使用 JLabel 的文本进行检查,与 JButton 相同。
编辑:是的,这绝对不是正确的做事方式,只是想知道是否可行,如果可行,怎么做?
编辑:为了让事情更清楚一点,我有一个 class 扩展了 ActionListener、MouseMotionListener、MouseListener。是否可以让这个 class 处理一个 JFrame 的所有事件,这个 JFrame 有很多不同的 JPanel 附加到它上面,并根据按下的 JPanel 做一些不同的事情? (例如将 ID 附加到 JPanels,我可以将 event.getSource() 与之进行比较)
我不确定这是否是最好的方法,但我刚刚测试了它并且它确实有效,至少就我的代码测试而言。找到鼠标在按下时悬停在哪个方框上并相应地执行操作。
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");
}
}
});
}
编辑 2
这应该是你的答案,我在调试时注意到,当我点击框架上的空白区域时,我得到了一个名为 "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);
}
}
编辑 1
根据您的评论我了解到,请尝试以下操作:
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;
}
}
}
正解
public class 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
}
});
}
}
首先,一个 "global" 监听器,它为不同的组件做不同的事情,这是一个坏主意,它将太多的逻辑放在一个单一的逻辑中,耦合代码并成为维护的噩梦。
话虽如此,您可以使用单个 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);
}
}
}
然后您可以简单地使用 MouseEvent#getSource
来确定哪个组件触发了事件。为简单起见,我为每个面板提供了一个 name
并显示了它,在决定要做什么之前,我会使用其他方式来识别组件。
更好的解决方案是提供一个特定的MouseListener
,它根据需要对每个面板执行特定的工作,这变得更容易管理、隔离责任、解耦代码并且更容易维护和管理