Ha a JTable cellához egy egyedi, JPanel-re épített CellEditor komponenst rendelek, amely tartalmaz egy szerkeszthető szöveges mezőt is, a billentyűzetet használva nem lesz szerkeszthető a szöveges mező, mert alapesetben a JPanel kapja meg a fókuszt, nem pedig a szöveges mező.

A megoldást Sanhtosh Kumar találta meg és írta le blogjában, az eredeti cikk itt érhető el. Hálás köszönet érte! Ez egy nagyon bonyolult probléma volt.

Út a megoldás felé

Kumar először azt vizsgálta, hogy a DefaultTableCellEditor használata esetén a KeyEvent-ek hogyan kerülnek továbbításra a JTextField objektumnak, és a következő stack trace-t rögzítette:

java.lang.Exception: Stack trace
    at java.lang.Thread.dumpStack(Thread.java:1082)
    at santhosh.CustomEditorDemo$1.insertUpdate(CustomEditorDemo.java:26)
    at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:184)
    at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:749)
    at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:706)
    at javax.swing.text.PlainDocument.insertString(PlainDocument.java:114)
    at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:668)
    at javax.swing.text.JTextComponent.replaceSelection(JTextComponent.java:1072)
    at apple.laf.AquaLookAndFeel$AquaKeyTypedAction.actionPerformed(AquaLookAndFeel.java:1575)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1535)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2470)
    at javax.swing.JTable.processKeyBinding(JTable.java:3330)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2516)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2433)
    at java.awt.Component.processEvent(Component.java:4975)
    at java.awt.Container.processEvent(Container.java:1613)
    at java.awt.Component.dispatchEventImpl(Component.java:3681)
    at java.awt.Container.dispatchEventImpl(Container.java:1671)
    at java.awt.Component.dispatchEvent(Component.java:3543)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1713)

Ami a stack trace-ből kiderült

  1. A felhasználó a kurzorbillentyűkkel a szerkeszteni kívánt cellára navigál.
  2. Ilyenkor a fókusz JTable objektumé, ezért ő kapja a bellentyűeseményeket.
  3. A JTable felülírja a processKeyBinding(...) metódust (lásd a félkövér sort a stack trace-ben)
  4. A felülírt processKeyBinding(...) metódus a következő módon befolyásolja a működést:
    1. Megkérdezi a TableCellEditor-t, hogy a kapott KeyEvent aktiválhatja-e a CellEditor-t.
    2. Ha igen, akkor aktiválja a CellEditor-t és továbbítja a KeyEvent eseményt az aktuális CellEditor komponensnek.

Az ellesett trükk

A lényeg az események továbbításban rejlik. Kumar a következő képpen írta felül a JTable processKeyBinding(...) metódusát:

protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed){
    InputMap map = editorComp.getInputMap(condition);
    ActionMap am = editorComp.getActionMap();

    if(map!=null && am!=null && isEnabled()){
        Object binding = map.get(ks);
        Action action = (binding==null) ? null : am.get(binding);
        if(action!=null){
            return SwingUtilities.notifyAction(action, ks, e, editorComp, e.getModifiers());
        }
    }
    return false;
}

 

A fenti kód megoldotta a problémát: bármely billentyűt leütve a kijelölt táblázatcellába bekerül a begépelt karakter, viszont a cellaszerkesztő még mindig nem kapta meg a fókuszt, ezért még a következő metódust is felülírta:

public void addNotify(){
    super.addNotify();
    editorComp.requestFocus();
}

Kapcsolódó cikkek

Az eredeti cikk

http://jroller.com/santhosh/entry/keyboard_handling_in_tablecelleditor

Kategória: Java

Támogasd munkánkat!

Blogunkat nonprofit módon, teljesen ingyen készítjük, már 7 éve. Ingyenes szoftvereket biztosítunk több száz cég számára, és természetvédelmi tevékenységet is végzünk. Ezekből semmilyen bevételünk nem származik. De mi is csak pénzből tudjuk magunkat fenntartani. Azért gyűjtünk, hogy tovább tudjuk folytatni hasznos értékteremtő munkánkat, ezért kérünk, ha van 1000 - 5000 Ft-od, amit fel tudsz ajánlani számunkra, támogass minket!

Cégünk: Völgyerdő Nonprofit Kft.

Számlaszámunk: 11749015-28535807 (OTP Bank)

 

Látogatók

134497
Ma35
Tegnap43
Ezen a héten77
Ebben a hónapban1002
Összesen134497
Statistik created: 2019-10-22T13:39:11+00:00
Bejelentkezett felhasználók 0
Regisztrált felhasználók 1
Ma regisztráltak 0