使用 TableCellEditor 时如何获取鼠标单击位置的组件?

2024-02-12

我用的是自定义的TableCellRenderer与多个JFormattedTextField在表格单元格中。我使用相同的组件TableCellEditor。现在我需要知道在什么方面JFormattedTextField用户单击,以及该字段中的位置(可以使用viewToModel).

使用自定义时TableCellEditor,唯一获得的方法是Point鼠标点击是isCellEditable(EventObject e) http://docs.oracle.com/javase/7/docs/api/javax/swing/CellEditor.html#isCellEditable%28java.util.EventObject%29中的方法CellEditor. The Point给出的是在父母坐标系中。

anEvent 位于调用组件坐标系中。

但是如何获取点击坐标处的组件呢?我尝试过findComponentAt(Point p) http://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#findComponentAt%28java.awt.Point%29但它返回null for me.

这是我测试过的一些代码:

@Override
    public boolean isCellEditable(EventObject e) {

        if(e instanceof MouseEvent) {
            MouseEvent ev = (MouseEvent)e;
            Point p = ev.getPoint();

            // gives strange values
            Point p3 = editor.getLocation();

            // x: 0 y: 0
            Point tp = ((JTable)e.getSource()).getLocation();

            // these returns null
            Component c1 = renderer.findComponentAt(p);
            Component c2 = editor.findComponentAt(p);

            System.out.println("Click at " + p + " editor at: " + p3);
        }

        return true;
    }

组件位置的值editor.getLocation();给出 y 坐标的几乎随机值(例如,当在表中使用 5 行时)。

如何获取用户在使用时单击的组件TableCellEditor and a TableCellRenderer?


这是一个完整的示例:

public class FormattedTableEditDemo extends JFrame {

    public FormattedTableEditDemo() {

        MyTableModel model = new MyTableModel();
        MyTableCellEditorAndRenderer cellEditorAndRenderer =
                new MyTableCellEditorAndRenderer();     

        JTable table = new JTable(model);
        table.setDefaultRenderer(BigDecimal.class, cellEditorAndRenderer);
        table.setDefaultEditor(BigDecimal.class, cellEditorAndRenderer);
        table.setRowHeight(40);

        add(new JScrollPane(table));
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

    }

    class MyTableCellEditorAndRenderer extends AbstractCellEditor
            implements TableCellEditor, TableCellRenderer {

        MyCellPanel editor = new MyCellPanel();
        MyCellPanel renderer = new MyCellPanel();

        @Override
        public Object getCellEditorValue() {
            return editor.getValue();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, 
                Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {
            renderer.setValue(value);
            return renderer;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            editor.setValue(value);
            return editor;
        }

        @Override
        public boolean shouldSelectCell(EventObject e) {
            return false;
        }

        @Override
        public boolean isCellEditable(EventObject e) {

            if(e instanceof MouseEvent) {
                MouseEvent ev = (MouseEvent)e;
                Point p = ev.getPoint();

                // gives strange values
                Point p3 = editor.getLocation();

                // x: 0 y: 0
                Point tp = ((JTable)e.getSource()).getLocation();

                // these returns null
                Component c1 = renderer.findComponentAt(p);
                Component c2 = editor.findComponentAt(p);

                System.out.println("Click at " + p + " editor at: " + p3);
            }

            return true;
        }

    }

    class MyCellPanel extends JPanel {

        JFormattedTextField field1 = new JFormattedTextField();
        JFormattedTextField field2 = new JFormattedTextField();

        public MyCellPanel() {

            field1.setColumns(8);
            field2.setColumns(8);

            field2.setValue(new BigDecimal("0.00"));

            setLayout(new BorderLayout());
            add(field1, BorderLayout.WEST);
            add(Box.createHorizontalStrut(30));
            add(field2, BorderLayout.EAST);
        }

        public Object getValue() {
            return field1.getValue();
        }

        public void setValue(Object value) {
            field1.setValue(value);
        }
    }

    class MyTableModel extends AbstractTableModel {

        List<BigDecimal> values = new ArrayList<BigDecimal>();

        public MyTableModel() {

            // test values
            values.add(new BigDecimal("37.00"));
            values.add(new BigDecimal("4305.90"));
            values.add(new BigDecimal("386.04"));
            values.add(new BigDecimal("3486.58"));
            values.add(new BigDecimal("6546.45"));
        }

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public int getRowCount() {
            return values.size();
        }

        @Override
        public Object getValueAt(int row, int column) {
            return values.get(row);
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return true;
        }

        @Override
        public Class<?> getColumnClass(int column) {
            return BigDecimal.class;
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new FormattedTableEditDemo();
            }

        });
    }

}

不完全确定我明白出了什么问题(如果我不在,请告诉我,这样我就可以删除这个:-)

假设您想获得触发编辑开始的鼠标(单击/按下)下的“真实”组件,技巧是进行转换(从父坐标到编辑器坐标)after编辑器被添加到其父级。这对于 shouldSelectCell 是有保证的,但对于 isCellEditable 则不然(后者被称为before)

A 最近的回答 https://stackoverflow.com/questions/8119718/treecelleditor-must-select-cell-to-edit-even-if-shouldselectcell-return-false/8279716#8279716在树的上下文中(应该足够相似)有一些可运行的示例。这是相关的片段:

/**
 * At this point in time the editing component is added to the table (not documented!) but
 * table's internal cleanup might not yet be ready
 */ 
@Override
public boolean shouldSelectCell(EventObject anEvent) {
    if (anEvent instanceof MouseEvent) {
        redirect((MouseEvent) anEvent);
    }
    return false;
}

private void redirect(final MouseEvent anEvent) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            MouseEvent ev = SwingUtilities.convertMouseEvent(anEvent.getComponent(), anEvent, editor);
            // at this point you have the mouse coordinates in the editor's system
            // do stuff, like f.i. findComponent
            ....
        }
    });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 TableCellEditor 时如何获取鼠标单击位置的组件? 的相关文章

  • 如何将 javax.persistence.Column 定义为 Unsigned TINYINT?

    我正在基于 MySQL 数据库中的现有表创建 Java 持久性实体 Bean 使用 NetBeans IDE 8 0 1 我在这个表中遇到了一个字段 其类型为 无符号 TINYINT 3 我发现可以执行以下操作将列的类型定义为 unsign
  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • “java.net.MalformedURLException:未找到协议”读取到 html 文件

    我收到一个错误 java net MalformedURLException Protocol not found 我想读取网络上的 HTML 文件 mainfest uses permission android name android
  • 通往楼梯顶部的可能路径

    这是一个非常经典的问题 我听说谷歌在他们的面试中使用过这个问题 问题 制定一个递归方法 打印从楼梯底部到楼梯顶部的所有可能的独特路径 有 n 个楼梯 您一次只能走 1 步或 2 步 示例输出 如果它是一个有 3 级楼梯的楼梯 1 1 1 2
  • 当客户端关闭连接时,Spring StreamingResponseBody 请求线程未清理

    我在控制器中有一个端点 它返回一个StreamingResponseBody 用于向客户端发送文件 其代码大致如下 RestController RequestMapping value api public class Controlle
  • 来自十六进制代码的 Apache POI XSSFColor

    我想将单元格的前景色设置为十六进制代码中的给定颜色 例如 当我尝试将其设置为红色时 style setFillForegroundColor new XSSFColor Color decode FF0000 getIndexed 无论我在
  • 使用 JUnit 时,有没有办法验证测试方法中是否调用了 try/catch 指令的 Catch 部分?

    例如 如果我想测试以下课程 public class SomeClass public void someMethod try Some code where comething could go wrong catch Exception
  • 如何使用 Hibernate (EntityManager) 或 JPA 调用 Oracle 函数或过程

    我有一个返回 sys refcursor 的 Oracle 函数 当我使用 Hibernate 调用该函数时 出现以下异常 Hibernate call my function org hibernate exception Generic
  • 套接字的读写如何同步?

    我们创建一个套接字 在套接字的一侧有一个 服务器 在另一侧有一个 客户端 服务器和客户端都可以向套接字写入和读取 这是我的理解 我不明白以下事情 如果服务器从套接字读取数据 它在套接字中是否只看到客户端写入套接字的内容 我的意思是 如果服务
  • 从 GitHub 上托管的 Spring Cloud Config Server 访问存储库的身份验证问题

    我在 GitHub 上的存储库中托管配置 如果我将回购公开 一切都好 但如果我将其设为私有 我将面临 org eclipse jgit errors TransportException https github com my user m
  • 在另一个模块中使用自定义 gradle 插件模块

    我正在开发一个自定义插件 我希望能够在稍后阶段将其部署到存储库 因此我为其创建了一个独立的模块 在对其进行任何正式的 TDD 之前 我想手动进行某些探索性测试 因此 我创建了一个使用给定插件的演示模块 到目前为止 我发现执行此操作的唯一方法
  • Freemarker 和 Struts 2,有时它计算为序列+扩展哈希

    首先我要说的是 使用 Struts2 Freemarker 真是太棒了 然而有些事情让我发疯 因为我不明白为什么会发生这种情况 我在这里问是因为也许其他人有一个想法可以分享 我有一个动作 有一个属性 说 private String myT
  • QuerySyntaxException:无法找到类

    我正在使用 hql 生成 JunctionManagementListDto 类的实际 Java 对象 但我最终在控制台上出现以下异常 org hibernate hql internal ast QuerySyntaxException
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • 使用布尔值进行冒泡排序以确定数组是否已排序

    我有以下用于冒泡排序的代码 但它根本不排序 如果我删除布尔值那么它工作正常 我知道 由于我的 a 0 小于所有其他元素 因此没有执行交换 任何人都可以帮助我解决这个问题 package com sample public class Bub
  • “无法实例化活动”错误

    我的一个 Android 应用程序拥有大约 100 000 个用户 每周大约 10 次 我会通过 Google 的市场工具向我报告以下异常情况 java lang RuntimeException Unable to instantiate
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复
  • 在java中使用多个bufferedImage

    我正在 java 小程序中制作游戏 并且正在尝试优化我的代码以减少闪烁 我已经实现了双缓冲 因此我尝试使用另一个 BufferedImage 来存储不改变的游戏背景元素的图片 这是我的代码的相关部分 public class QuizApp
  • Spring表单ModelAttribute字段验证避免400 Bad Request错误

    我有一个ArticleFormModel包含正常发送的数据html form由 Spring 使用注入 ModelAttribute注释 即 RequestMapping value edit method RequestMethod PO

随机推荐