Java – how do I get components at the mouse click position when using TableCell editor?

I use a custom tablecellrenderer and multiple jformattedtextfields in table cells I use the same components as TableCell editor Now I need to know the jformattedtextfield that the user clicked and the location in this field (which can be done using viewtomodel)

When using a custom tablecelleditor, the only way to get a point from a mouse click is the iscelleditable (eventobject E) method in celleditor The given point is in the parent coordinate system

But how do I get the component at the clicked coordinates? I tried findcomponentat (point P), but it returned null for me

Here are some of the codes I have tested:

@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;
    }

Value of component location editor getLocation(); Give an almost random value for the Y coordinate (for example, when 5 rows are used in the table)

When using tablecelleditor and tablecellrenderer, how to get the component clicked by the user?

This is a complete example:

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,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(@R_408_2419@.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();
            }

        });
    }

}

Solution

Not quite sure I understand what's wrong (just let me know if I close, so I can delete this: -)

Suppose you want to get the "real" component under the mouse (click / Press) that triggers the start of editing. The trick is to convert (from parent to editor coordinates) after adding the editor to its parent This is guaranteed for shouldselectcell, but not for iscelleditable (which was called earlier)

There are some runnable examples of recent answers (which should be similar enough) in the context of the tree This is a related fragment:

/**
 * 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
            ....
        }
    });
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>