how do I simulate “onStartCellEditing” for DefaultCellEditor

前端 未结 2 729
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-25 01:28

CellEditorListener has \"editingStopped\" and \"editingCancelled\". But how might I implement a piece of code which needs to run when a cell editing session starts?

A t

2条回答
  •  礼貌的吻别
    2021-01-25 01:55

    Rob Camick's answer is great, but I have another one for "completists" to peruse.

    I use Jython but it should be simple enough for Java people to understand. In Python/Jython you can add arbitrary "attributes" to (almost) any object. So in editCellAt I add an attribute "start_editing" which then signals to the caret listener added to the JTextField editor component that a session has just begun. If the caret dot and mark are equal (collapsed), if the click-count-to-start-editing == 2, and if the editor has the "start_editing" attr, you select-all (again), and you also remove the "start_editing" attr... it works (!), without spawning a new 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 )
    

    A similar result could be achieved in Java, clearly, using a private field of the editor, or something along those lines.

    NB why have I put "requestFocus" in there? If you press key F2 on an editable table cell the editing starts and the editor component (typically a JTextField) gets focus automatically. However you can also start editing just by typing into the table cell. It took me much head-scratching to work out that, oddly, if you do this you do indeed start editing, but the editor component does not get focus automatically. So this is a way to "resolve this anomaly".

    NB2 One final point about my solution. In a real-world implementation you also need to set a timer to remove the attribute "start_editing" after a certain finite time (e.g. 0.5 s). Otherwise you might click once, which would not start an editing session (if click-to-start == 2), and then click again 10 seconds later, after having started editing by another means, to find that selectAll happens confusingly and inexplicably. This attribute must be made to be like the tape in Mission Impossible: self-destruct after x seconds...

提交回复
热议问题