CellEditorListener具有“editingStopped”和“editingCancelled”。但是,我如何实现一个需要在单元格编辑会话开始时运行的代码?
一个典型示例可能是您希望在开始编辑时JTextField编辑器组件的文本转到selectAll()的位置。我很想要做的事情是覆盖DefaultCellEditor的一个方法,例如getTableCellEditorComponent或getCellEditorValue或getComponent,但是没有一个明确地说它们是在编辑会话开始时调用的。
相反,我们知道如果我们正在编辑JTable.getCellEditor会返回编辑器,否则返回null。这是因为在编辑开始时组件被制成JTable的子对象。它似乎也在编辑会话开始时得到了关注,因此您可能会想到将FocusListener添加到编辑器组件(JTextField等)。但这有保证吗?此外,可能会丢失焦点,然后在编辑会话期间返回。
有一种方法可以监听此编辑器组件的“添加”(作为子对象):ContainerListener。除非有人告诉我不同,否则这似乎是获得编辑会话已开始的电话的最直接和最合理的方式。但似乎很奇怪,没有更直接的方式...
答案 0 :(得分:2)
一个典型的例子可能是您希望在开始编辑时JTextField编辑器组件的文本转到selectAll()。
您可以覆盖JTable的editCellAt(...)
方法,以便在编辑开始后选择文本:
@Override
public boolean editCellAt(int row, int column, EventObject e)
{
boolean result = super.editCellAt(row, column, e);
final Component editor = getEditorComponent();
if (editor != null && editor instanceof JTextComponent)
{
((JTextComponent)editor).selectAll();
if (e == null)
{
((JTextComponent)editor).selectAll();
}
else if (e instanceof MouseEvent)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
((JTextComponent)editor).selectAll();
}
});
}
}
return result;
}
答案 1 :(得分:1)
我使用Jython但它应该足够简单,以便Java人员理解。在Python / Jython中,您可以添加任意"属性" (几乎)任何物体。所以在editCellAt中我添加了一个属性" start_editing"然后发信号给插入符号监听器添加到JTextField编辑器组件会话刚刚开始。如果插入点和标记相等(折叠),如果点击计数到开始编辑== 2,并且编辑器具有" start_editing" attr,你选择全部(再次),你也删除" start_editing" attr ...它可以工作(!),而不会产生新的Runnable。
class DatesTable( javax.swing.JTable ):
def editCellAt(self, row, column, event_obj ):
result = self.super__editCellAt( row, column, event_obj )
if self.editorComponent:
self.editorComponent.requestFocus() # explanation below
self.editorComponent.selectAll()
if isinstance( event_obj, java.awt.event.MouseEvent ):
self.cellEditor.start_editing = None
return result
class DatesTableCellEditor( javax.swing.DefaultCellEditor ):
def __init__( editor_self, table, *args, **kvargs ):
jtf = javax.swing.JTextField()
class JTFCaretListener( javax.swing.event.CaretListener ):
def caretUpdate( self, caret_event ):
if hasattr( editor_self, 'start_editing' ):
del editor_self.start_editing
if caret_event.dot == caret_event.mark and editor_self.clickCountToStart == 2:
caret_event.source.selectAll()
jtf.addCaretListener( JTFCaretListener())
javax.swing.DefaultCellEditor.__init__( editor_self, jtf, **kvargs )
使用编辑器的私有字段或类似的东西,可以在Java中实现类似的结果。
注意为什么我要把#34; requestFocus"在那里?如果在可编辑的表格单元格上按F2键,编辑将开始,编辑器组件(通常是JTextField)将自动获得焦点。但是,您也可以通过键入表格单元格来开始编辑。奇怪的是,如果你这样做,你确实开始编辑,但是 编辑器组件没有自动获得焦点 ,这让我感到很头疼。所以这是一种解决这种异常的方法"。
NB2关于我的解决方案的最后一点。在实际实现中,您还需要设置一个计时器来删除属性" start_editing"在一定的有限时间(例如0.5秒)之后。否则你可能会点击一次,这不会启动编辑会话(如果点击开始== 2),然后在10秒后再次点击,在通过其他方式开始编辑后,发现selectAll发生了令人困惑和莫名其妙的混乱。这个属性必须像“不可能的任务”中的磁带一样:x秒后自毁......