在视口组件上使用 JScrollPane 鼠标侦听器

2023-12-11

我有一个JScrollPane可以设置其视口View到一系列不同的面板。我想在单击其视口中的任何其他组件时获取 JScrollPane 组件。如果我添加一个MouseListener对于 JScrollPane,当我直接单击窗格边框时,它会接收鼠标事件,但当我单击组件时,它不会接收鼠标事件。

添加侦听器并最终找到封闭的滚动窗格的正确方法是什么?我不一定会提前知道在视口中显示的面板上的所有组件 - 只是它们将位于 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;
   }
}

注:请参阅这个问题以及 StanislovL 和 mkorbel 的回答以获取更多相关信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在视口组件上使用 JScrollPane 鼠标侦听器 的相关文章

  • 如何让Spring RabbitMQ创建一个新的队列?

    根据我对rabbit mq的 有限 经验 如果您为尚不存在的队列创建新的侦听器 则会自动创建该队列 我正在尝试将 Spring AMQP 项目与rabbit mq 一起使用来设置侦听器 但出现错误 这是我的 xml 配置
  • 使用 AbstractTableModel 获取 JTable 中选定的行

    我有一个JTable using AbstractTableModel我在哪里有一个JCheckBox在第一列中用于选择行 现在 我需要从已检查的表中获取选定的行 现在 我按顺序从第一行遍历到最后一行并获取所有选择的行 如下所示 List
  • 在Java中清空数组/处理

    除了循环遍历数组中的每个元素并将每个元素设置为 null 之外 Java 处理中是否有一个本机函数可以简单地清空数组 或销毁它 以便能够将其重新声明为新数组 There s Arrays fill myArray null 并不是说它执行的
  • 使用 Spring Data REST 处理自定义异常 (i18n)

    我正在使用 Spring Boot 1 5 4 和 Spring JPA Spring Data REST HATEOAS 我正在寻找一种最佳实践 Spring 方式 来自定义异常 Spring Data REST 正在管理添加 i18n
  • 在 TestNG 中运行多个类

    我正在尝试自动化一个场景 其中我想登录一次应用程序 然后进行操作而无需再次重新登录 考虑一下 我有在特定类的 BeforeSuite 方法中登录应用程序的代码 public class TestNGClass1 public static
  • Java Spring 应用程序存在内存泄漏。系统非堆内存不断增加

    我已使用 yourkit 分析器监视我的 Web 应用程序 保留最大大小的主要对象是 SessionFactoryImpl webappclassloader 和 CGlib 对象显示 spring crone调度程序会导致内存泄漏吗 我尝
  • 如何将自定义日志处理程序添加到 Google App Engine?

    我正在尝试向我的 java 应用程序添加自定义日志处理程序 我已经实现了一个扩展 java util Logging Handler 类的 InnerLogger 类 在我的logging properties中声明为处理程序 handle
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 从 sbt 程序集运行 uber jar 会导致错误:无法找到或加载主类

    我有一个使用 sbt 程序集插件打包为 uber jar 的 Spark 作业 这build sbt指定一个可运行的 main 作为生成的 uber jar 的目标 mainClass in assembly Some com foo Ba
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 为什么现在()? (客观化)

    为什么我想要异步加载 Objectify 实体 异步加载到底意味着什么 根据客观化有关加载的文档 https code google com p objectify appengine wiki BasicOperations Loadin
  • 如何使用云打印打印Android活动显示

    我正在尝试将 Google 云打印实现到应用程序中 遵循集成指南 https developers google com cloud print docs android 我试图通过打印 google com 来保持基本 单击我创建的打印按
  • 在服务器内部调用 Web 服务

    我有一个网络服务 getEmployee 当传递 id 时 它会获取单个员工的员工详细信息 同一服务器上的另一个 Web 服务 getEmployeeList 当传递一个部门时 它会获取整个员工列表 这将获取部门的 ID 然后调用 getE
  • 读/写带有特殊字符的.txt文件

    I open Notepad Windows 并写 Some lines with special characters Special 并前往另存为 someFile txt 与Encoding set to UTF 8 在Java中我有
  • Selenium - 等待网络流量

    我们将 Selenium 与 Java API 和一些 Javascript 用户扩展一起使用 我们在应用程序中使用了大量 AJAX 调用 我们的许多测试随机失败 因为有时 AJAX 调用完成得比其他时候慢 因此页面未完全加载 我们通过等待
  • 如果抛出RuntimeException,是否可以将其作为异常捕获?

    如果我有一个try抛出一个块RuntimException子类 可以是后续的catch块将其捕获为Exception 具体来说 public class MyAppException extends RuntimeException In
  • 如何从spark中的hbase表中获取所有数据

    我在 hbase 中有一个大表 名称为 UserAction 它具有三个列族 歌曲 专辑 歌手 我需要从 歌曲 列族中获取所有数据作为 JavaRDD 对象 我尝试了这段代码 但效率不高 有更好的解决方案来做到这一点吗 static Spa
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co

随机推荐

  • Fortran 中的自动类型转换(类型转换)如何工作?

    我正在使用 gfortran 编译器 还请告诉我 gfortran 在执行自动类型转换 类型转换 时是否使用 Fortran 标准以外的其他内容 赋值由 Fortran 2008 第 7 2 节定义 值得注意的是 Cl 7 2 1 3 第
  • 通过 CMake 添加外部库(例如 Eigen)

    我已经处理这个问题几个星期了 我知道我可能只是错过了一个我没有意识到的小步骤 因此 任何见解都将受到高度赞赏 我正在尝试添加一些外部库并在我的 C 项目中使用它们 但似乎无法弄清楚如何 我阅读了互联网上有关添加外部库的所有帖子 但我相信我错
  • Three.js:使用变形目标获取更新的顶点

    我有一些变形目标正在工作 https jsfiddle net 3wtwzuh3 2 使用滑块控件查看变形 但是 我希望能够访问变形后顶点的新位置 如果您在链接的示例中注意到 我正在显示立方体第一个顶点的 y 坐标 但它没有更新 This
  • ORA-01422: PL/SQL 精确获取返回的行数多于请求的行数

    我不断收到此错误 我无法弄清楚出了什么问题 DECLARE 第 1 行错误 ORA 01422 精确提取返回的行数多于请求的行数ORA 06512 在第 11 行 这是我的代码 DECLARE rec ENAME EMPLOYEE ENAM
  • 以编程方式控制折线图中的符号等

    我有一个 JavaFX 应用程序 我希望用户能够控制折线图中的符号 线条样式等 我不想创建多个样式表 而是想将此功能构建到 Java 代码中 感谢 Jewelsea 之前发布的优秀示例 我可以动态更改线条样式 这太棒了 但我无法更改默认符号
  • 此正则表达式 (RegEx) 标志有何含义 /iD

    我想使用这个正则表达式来验证 IPv6 但我想了解它所做的一切https stackoverflow com a 1934546 3112803 gt gt a f0 9 1 4 gt 1 7 a f0 9 gt 8 1 gt 1 0 6
  • .NET 如何从电子邮件中提取嵌入的图像?

    您好 我正在开发 NET 1 1 中的一个项目 我需要从我收到的电子邮件中提取 并将其保存在某处 嵌入图像 有人可以告诉我从哪里开始吗 谢谢 从 POP 服务器下载的电子邮件将是文本格式 您必须解析整个电子邮件 并找到所有 img 标签具有
  • SharePoint Online 中的 Office 365 Workbooks.open 打开空白文件

    我们公司正在使用 Office 365 Pro Plus 的半年更新频道 最近我们从版本 1708 更新到了 1803 我们正在使用一些自动化宏 而不是从 SharePoint 在线租户打开文件 自更新以来 调用了 Workbooks op
  • 将 pandas 数据帧写入 xlsm 文件(启用宏的 Excel)

    写一个pandas DataFrame到 Excel 工作簿中 xlsx格式很简单 import pandas as pd df pd DataFrame firstColumn 5 2 0 10 4 secondColumn 9 8 21
  • AntiXss.HtmlEncode 与 AntiXss.GetSafeHtmlFragment

    谁能告诉我这两者之间的区别吗 AntiXss HtmlEncode vs AntiXss GetSafeHtmlFragment Html编码实际上对标签进行编码 AntiXss HtmlEncode b hello b
  • Java MongoDB:com.mongodb.DB 和 com.mongodb.client 之间有什么区别

    我是 MongoDB 的新手 我正在一个 Java 项目中工作 我开始了一些教程来开始使用驱动程序 我正在使用com mongodb client直到我注意到里面没有findOne方法com mongodb client MongoColl
  • 示例 MQTT 客户端代码不工作 C

    我从那里得到了示例代码here 我有头文件MQTTClient h以及 但是 当我构建时 我收到错误 undefined reference to MQTTClient create undefined reference to MQTTC
  • 如何使用 Blazor 生成并保存文件客户端?

    我想要一个 SPA 来完成客户端的所有工作 甚至生成一些图表 视觉效果 我希望能够让用户单击按钮并保存页面中的视觉效果 表格和其他内容 既可见又不可见 因此右键单击保存或复制 粘贴并不总是一个选项 如何从 web assembly blaz
  • 如何通过管道传输字符串来处理'STDIN?

    我有一个命令需要来自管道的输入 例如 考虑一下著名的cat命令 echo Hello cat Hello 假设我在 Perl 6 程序中有一个字符串 我想将其通过管道传输到命令 use v6 my input Hello This is t
  • flutter - 如何在应用程序启动和使用时下载资产

    目前 我的应用程序有许多资产 图像 声音 字体 json SQL lite 数据库文件等 全部已定义在pubspec yaml 但是 由于要求减少 APK 大小 我需要其中一些应用程序启动时下载并将其保存到存储中 下次无需下载 如果资源尚未
  • 如何使用 Spring MVC 从 url 下载文件?

    我的 jsp 中有这样的下载选项 a href img src images download gif alt Download border 0 align right 上面的 url 是文件的位置 名称是文件名 单击jsp中的下载选项时
  • awk每列n条数据的平均值

    使用 awk 将值存储在数字列表中 提供使用 awk 对列中每组 3 个点进行平均的解决方案 如何将其扩展到保持格式的无限数量的列 例如 2457135 564106 13 249116 13 140903 0 003615 0 00344
  • 检测并修复 JavaScript 中的循环引用

    鉴于我在一个大型 JavaScript 对象中有一个循环引用 我尝试JSON stringify problematicObject 浏览器抛出 类型错误 将循环结构转换为 JSON 这是预期的 那我想找到这个循环引用的原因 最好使用Chr
  • git 警告“无法访问权限被拒绝”在 .gitignore 目录上

    我的一个名为 Database 的目录中有一个名为 gitignore 的子目录 我希望 git 忽略它 所以我将其列在我的 gitingore 文件中 gitignore Bb in Dd ebug Rr elease gitignore
  • 在视口组件上使用 JScrollPane 鼠标侦听器

    我有一个JScrollPane可以设置其视口View到一系列不同的面板 我想在单击其视口中的任何其他组件时获取 JScrollPane 组件 如果我添加一个MouseListener对于 JScrollPane 当我直接单击窗格边框时 它会