当前位置: 首页 > 知识库问答 >
问题:

在JTable中检测鼠标点击时出现问题

邢勇
2023-03-14

我有一个JTable,其中第3列和第4列使用JComboBox作为单元格编辑器。第3列指定类型,第4列指定子类型。第4列中可用的子类型列表取决于用户为类型选择的值。此外,用户可以编辑类型和子类型列表(这里的详细信息并不重要,只是类型和子类型列表在运行时都可以更改)。

因为子类型组合框的内容是动态的,所以我的目的是检测用户何时单击子类型单元格,并根据该行中类型的内容设置列表模型(设置可用的子类型项列表)。

然而,我很难在需要的单元格中检测到鼠标点击。我已经在下面发布了我的代码和输出。

问题是,鼠标侦听器没有检测到组合框中的单击。据推测,该事件是由组合框触发的,而不是由表触发的。我可以将ListSelectionListener与TableColumnModelListener结合使用,但我必须想象有更好的方法。我试图使用与组合框相关的事件,但我无法获得选择哪个组合框的信息(因此我不知道我在表中的位置)。我试图获取组合框的容器并以这种方式定位单击,但组合框的getParent()方法返回null。

编辑:在ComboBox ActionListener中,我还尝试了使用JTable的getSseltedRow()和getSseltedCol列()方法,但是它们返回旧单元格的值,而不是新单元格的值。

任何关于如何更简洁一点的建议都将不胜感激。

以下是相关的代码片段(事件处理程序还没有做很多工作,只是试图获取信息):

    // Setup table and table model
    tableTypeDataModel = new TypeAssignmentTableModel();
    JTable typeTable = new JTable(tableTypeDataModel);
    // Add a mouse listener to the table. 
    typeTable.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e)
        {   
           Point pnt = e.getPoint();
           int row = typeTable.rowAtPoint(pnt);
           int col = typeTable.columnAtPoint(pnt);
           System.out.println(Integer.toString(row) + ", " + Integer.toString(col));
        }       
    });

    typeTable.getSelectionModel().addListSelectionListener(new myListSelectionListener());
    typeTable.setFillsViewportHeight(true);
    JScrollPane scpnTypeTable = new JScrollPane(typeTable);
    
    // Set columns and model listener
    TableColumnModel cm = typeTable.getColumnModel();
    cm.addColumnModelListener(new myColumnListSelectionListener());
    
   // Setup type column
    JComboBox<String> cmbTableTypes = new JComboBox<>(arrOfTypes);
    cmbTableTypes.addActionListener(new myCBOActionListener());
    cm.getColumn(TYPECOL_TYPE).setCellEditor(new DefaultCellEditor(cmbTableTypes));
    // This just adds left padding to the cell
    IndentedTableCellRenderer tableTypeRenderer = new IndentedTableCellRenderer(5, 0);
    cm.getColumn(TYPECOL_TYPE).setCellRenderer(tableTypeRenderer);
     
    // Setup subtype column
    tableSubtypeCboModel = new DefaultComboBoxModel<>();
    JComboBox<String> cmbTableSubtypes = new JComboBox<>(tableSubtypeCboModel);
    cm.getColumn(TYPECOL_SUBTYPE).setCellEditor(new DefaultCellEditor(cmbTableSubtypes));
    IndentedTableCellRenderer tableSubtypeRenderer = new IndentedTableCellRenderer(5, 0);
    cm.getColumn(TYPECOL_SUBTYPE).setCellRenderer(tableSubtypeRenderer);
     
    

和...

    class myListSelectionListener implements ListSelectionListener {
        @Override
        public void valueChanged(ListSelectionEvent e) {
            System.out.println("Table List selection listener = " + e.getSource().toString());
        }
    }   

    class myColumnListSelectionListener implements TableColumnModelListener {

        // other methods empty and not shown...

        @Override
        public void columnSelectionChanged(ListSelectionEvent e) {
        // TODO Auto-generated method stub
            System.out.println("Table column model listener Source = " + 
                e.getSource().toString());
        }
    }

    class myCBOActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JComboBox item = (JComboBox) e.getSource();
            System.out.println("CBO Action Listener = " + item.getClass().toString());
            String msg = item.getParent() == null ? "null" : item.getParent().toString();
            System.out.println("CBO Action Listener item parent is " + msg);
        }
    }

以下是单击以下单元格后的控制台输出:

  Row 1, Col 0 (just a regular cell)
  Row 2, Col 1 (just a regular cell)
  Row 3, Col 2 (just a regular cell)
  Row 4, Col 3 (this is the Type column with a combo box editor)

Console Output:
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{0}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{1}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={1}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={0}
1, 0
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{1}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{2}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={2}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={1}
2, 1
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{2}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{3}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={3}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={2}
3, 2
CBO Action Listener = class javax.swing.JComboBox
CBO Action Listener item parent is null
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{3}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{4}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={4}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={3}

谢谢

共有1个答案

池砚文
2023-03-14

您可以将子类型JCombobox作为全局对象进行管理,然后添加一个ActionListener,当子类型JCombobox组件在UI中被“选中”时,它会更新子类型值。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;

public class whatev{

    JComboBox types = new JComboBox();
    JComboBox subtypes = new JComboBox();
    
    Map<String,int[]> m = new HashMap<String,int[]>();  //example source mapping types to sub-types
    int[] t1 = {1,3};
    int[] t2 = {4, 5};
    
    public static void main(String[] args){ new whatev(); }
    
    whatev(){
        //Add example data to types
        types.addItem("Type 1");
        types.addItem("Type 2");
        types.setSelectedIndex(0);
        
        //init map data for example
        m.put("Type 1", t1);
        m.put("Type 2", t2);

        //initialize subtype JCombobox
        updateSubtypes();
        
        //add appropriate listener to subtype box
        subtypes.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateSubtypes();
            }
        });
    }

    private void updateSubtypes() {
        int[] x = m.get(types.getSelectedItem());   //pull appropriate subtypes from type/subtype mapping source
        subtypes.removeAllItems();                  //purge old objects in subtype
        for(int v : x) { subtypes.addItem(v); }     //Add appropriate subtypes  
        }
}
 类似资料:
  • 我想知道如何编写代码来检测鼠标点击精灵。例如:

  • 问题内容: 我正在学习Pygame制作带有Python的游戏。但是,我遇到了一个问题。我正在尝试检测播放器当前何时单击屏幕,但是我的代码无法正常工作。我的代码实际上是搞砸了,还是我正在使用的在线Pygame编译器? 当我运行此代码时,输​​出控制台在每秒几千次内向文本“您正在单击”发送垃圾邮件。即使我没有单击屏幕,它仍然会显示此信息。即使我的鼠标是不是 在 屏幕上。相同的文字。一遍又一遍。Pyga

  • 所以我开始在我的应用程序中为不同的功能设置键,我想知道是否有一种方法可以设置鼠标左键或右键来执行某些操作?我在keycode.java中找不到任何鼠标事件,我不知道如何应用它。 下面是我的代码: 我要完成的是使右键点击你的鼠标按钮停止移动,左键点击再次开始。我该怎么做?谢谢你。

  • 我想实现一个模型,包括一个功能,让我可以通过点击界面上的鼠标来做各种事情。然而,我无法确定基于Repast Simphony的模型是否可以实现鼠标点击。请帮忙。

  • 本文向大家介绍Unity实现鼠标双击与长按的检测,包括了Unity实现鼠标双击与长按的检测的使用技巧和注意事项,需要的朋友参考一下 在unity中,我们会遇到很多的关于鼠标的事件。虽然unity中给出了相关的点击与拖拽方法,可是这些方法只对UI和碰撞体适用。那么,如何直接用代码实现鼠标的双击与长按的检测呢? 首先我们需要几个变量,用来保存时间,以判断是长按还是点击。 先来说说这些变量的用处。mai

  • 但是,鼠标中键不是由Vaadin注册的。我怎么才能让这个起作用?