gpt4 book ai didi

java - 在视口(viewport)组件上使用 JScrollPane 鼠标监听器

转载 作者:行者123 更新时间:2023-11-29 03:44:51 25 4
gpt4 key购买 nike

我有一个 JScrollPane 可以将其 viewportView 设置为一系列不同的面板。每当单击其视口(viewport)中的任何其他组件时,我都想获取 JScrollPane 组件。如果我将 MouseListener 添加到 JScrollPane,它会在我直接单击 Pane 的边框时接收我的鼠标事件,但在我单击组件时不会接收。

添加监听器并最终找到封闭的 scrollPane 的正确方法是什么?我不一定会提前知道我在视口(viewport)中显示的面板上的所有组件 - 只是知道它们将位于 JPanel 的某个子类上。

import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.MouseInputAdapter;

import net.miginfocom.swing.MigLayout;

public class TestScrollPane extends MouseInputAdapter{
public void mouseEntered(MouseEvent arg0) {System.out.println("Entered " + arg0.getComponent());}
public void mouseExited(MouseEvent arg0) {System.out.println("Exited " + arg0.getComponent());}
public void mousePressed(MouseEvent arg0) {System.out.println("Pressed " + arg0.getComponent());}
public void mouseReleased(MouseEvent arg0) {System.out.println("Released " + arg0.getComponent());}

public static void main(String[] args){
JFrame frame = new JFrame();
frame.setLayout(new MigLayout());
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestPane pane1 = new TestPane("Scroll Pane 1");
TestPane pane2 = new TestPane("Scroll Pane 2");
frame.add(pane1, "push,grow");
frame.add(pane2, "push, grow");
TestMouseListener listener = new TestMouseListener();
pane1.addMouseListener(listener);
pane1.addMouseMotionListener(listener);
pane2.addMouseListener(listener);
pane2.addMouseMotionListener(listener);
frame.setVisible(true);
}
}

class TestPanel2 extends JPanel {
String name;
TestPanel2(String name){
this.name = name;
setLayout(new MigLayout());
JTextArea area = new JTextArea();
area.append(name);
add(area, "push, grow");
}
public String toString(){ return name; }
}
class TestPane extends JScrollPane {
String name;
TestPane(String name){
this.name = name;
TestPanel2 panel = new TestPanel2(name + " panel");
setViewportView(panel);
}
public String toString(){ return name; }
}

在这个例子中,我获得了鼠标进入和退出事件,但我只能通过点击文本区域周围的边框来获得鼠标点击事件。即使我更改 TestPane 类以将监听器添加到它的 viewportView 面板,我也无法知道 textArea 中发生了什么。

class TestPane extends JScrollPane {
String name;
TestPane(String name){
this.name = name;
TestPanel2 panel = new TestPanel2(name + " panel");
TestMouseListener listener = new TestMouseListener();
panel.addMouseListener(listener);
panel.addMouseMotionListener(listener);
setViewportView(panel);
}
public String toString(){ return name; }
}

不过,我无法通过任何方式知道 JPanel 上有什么,因此我无法手动更深入地添加监听器。

最佳答案

另一种可能的方法是使用 AWTEventListener,然后向上冒泡父树以查看您感兴趣的组件是否已被按下或包含一个已被按下的子组件。例如:

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.MouseInputAdapter;

// import net.miginfocom.swing.MigLayout;

public class TestScrollPane extends MouseInputAdapter {
public void mouseEntered(MouseEvent arg0) {
System.out.println("Entered " + arg0.getComponent());
}

public void mouseExited(MouseEvent arg0) {
System.out.println("Exited " + arg0.getComponent());
}

public void mousePressed(MouseEvent arg0) {
System.out.println("Pressed " + arg0.getComponent());
}

public void mouseReleased(MouseEvent arg0) {
System.out.println("Released " + arg0.getComponent());
}

public static void main(String[] args) {
JFrame frame = new JFrame();
// frame.setLayout(new MigLayout());
frame.getContentPane().setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestPane pane1 = new TestPane("Scroll Pane 1");
TestPane pane2 = new TestPane("Scroll Pane 2");
frame.add(pane1, "push,grow");
frame.add(pane2, "push, grow");
// !! TestMouseListener listener = new TestMouseListener();
TestScrollPane listener = new TestScrollPane();
pane1.addMouseListener(listener);
pane1.addMouseMotionListener(listener);
pane2.addMouseListener(listener);
pane2.addMouseMotionListener(listener);
frame.pack();
frame.setVisible(true);

Toolkit.getDefaultToolkit().addAWTEventListener(
listener.createAWTWindowListener(), AWTEvent.MOUSE_EVENT_MASK);

}

private AWTEventListener createAWTWindowListener() {
AWTEventListener awt1 = new AWTEventListener() {

@Override
public void eventDispatched(AWTEvent e) {
if (MouseEvent.MOUSE_PRESSED == e.getID()) {
MouseEvent event = (MouseEvent) e;
Component comp = event.getComponent();

if (comp != null) {
String scrollPanelName = recursivelyCheckForScrollPanel(comp);
if (scrollPanelName != null) {
System.out.println("TestPane pressed. Name: " + scrollPanelName);
} else {
System.out.println("TestPane not pressed");
}
}
}
}

private String recursivelyCheckForScrollPanel(Component comp) {
if (comp instanceof TestPane) {
return comp.toString();
} else {
comp = comp.getParent();
if (comp != null) {
return recursivelyCheckForScrollPanel(comp);
}
}
return null;
}
};
return awt1;
}
}

class TestPanel2 extends JPanel {
String name;

TestPanel2(String name) {
this.name = name;
// setLayout(new MigLayout());
JTextArea area = new JTextArea(5, 20);
area.append(name);
add(area, "push, grow");
}

public String toString() {
return name;
}
}

class TestPane extends JScrollPane {
String name;

TestPane(String name) {
this.name = name;
TestPanel2 panel = new TestPanel2(name + " panel");
setViewportView(panel);
}

public String toString() {
return name;
}
}

注意:请参阅this question以及 StanislovL 和 mkorbel 的回答以获得更多相关信息。

关于java - 在视口(viewport)组件上使用 JScrollPane 鼠标监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11478147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com