java – 使用TableCellEditor时,如何在鼠标单击位置获取组件?
|
我在表格单元格中使用自定义TableCellRenderer和多个JFormattedTextField.我使用与TableCellEditor相同的组件.现在我需要知道用户单击的JFormattedTextField,以及此字段中的位置(可以使用viewToModel完成). 使用自定义TableCellEditor时,从鼠标单击获取Point的唯一方法是CellEditor中的
但是如何在单击的坐标上获取组件?我尝试过 这是我测试过的一些代码: @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和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,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();
}
});
}
}
解决方法不完全确定我明白出了什么问题(只是让我知道,如果我关闭,所以我可以删除这个:-)假设您希望获得触发编辑开始的鼠标(单击/按下)下的“真实”组件,诀窍是在将编辑器添加到其父级之后进行转换(从父级到编辑器坐标).这对于shouldSelectCell是有保证的,但不是对于isCellEditable(后者之前被调用) 树的上下文中的recent answer(应该足够相似)有一些可运行的示例.这是相关的片段: /**
* 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
....
}
});
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
