テーブルセルにJFormattedTextField
という複数のカスタムのTableCellRenderer
を使用します。私はTableCellEditor
と同じコンポーネントを使用します。今私はJFormattedTextField
がクリックされたこと、そしてこのフィールドのどこで(viewToModel
でできるか)を知る必要があります。TableCellEditorを使用するとき、どのようにしてマウスクリック位置でコンポーネントを取得できますか?
カスタムTableCellEditor
を使用する場合、Point
をマウスクリックから取得する唯一の方法は、CellEditor
のisCellEditable(EventObject e)
メソッドです。与えられたPoint
は親座標系にあります。
anEventは起動コンポーネントの座標系にあります。
クリックした座標でコンポーネントを取得するにはどうすればよいですか?私はfindComponentAt(Point p)
で試しましたが、私にとってはnull
を返します。
@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,
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();
}
});
}
}
+1ですが、希望のフィールド自体を聞くのはなぜですか? – trashgod
@trashgod:セルに既にフォーカスがない限り、 'TableCellEditor'で使用されているときに' MouseEvent'を受け取らない。 'isCellEditable'は、フォーカスを持たない行をクリックしたときに' MouseEvent'を受け取る唯一の方法です。 – Jonas
いいえ、 'MouseEvent'をスキップして、適切な(アクション、プロパティなどの)リスナーを各' JFormattedTextField'に追加することを意味します。 – trashgod