2016-06-24 20 views
1

Lassen Sie mich das Szenario meines Problems vorstellen. Ich möchte den Inhalt einer Datenbanktabelle in einer JTable darstellen. Mit dieser JTable sollte ich in der Lage sein, neue Zeilen einzufügen, Zeilen zu löschen und den Inhalt der Felder der vorhandenen Zeilen zu aktualisieren.Java JTable Wie der Fokus von der aktuellen Zelle im Bearbeitungsmodus auf die nächste Zelle übertragen wird, wenn die Eingabetaste gedrückt wird

Das erste erwünschte Verhalten ist, dass, wenn eine Zelle den Fokus erhält, wenn es editierbar ist, es in den Bearbeitungsmodus direkt mit ihrem gesamten ausgewählten Inhalt eintritt, wenn es ein alphanumerischer Inhalt ist. (Text, Zahlen, Daten, etc.)

Das nächste gewünschte Verhalten ist, dass die Enter Schlüsselwerke als Tab Taste, dh Drücken der Enter Schwerpunkt muss auf die nächste Zelle übertragen werden (und wenn dies bearbeitbare dann Bearbeitungsmodus) sowohl vorwärts (von links nach rechts) als auch rückwärts.

Um die erste Anforderung zu adressieren, überschreibe ich die changeSelection-Methode der JTable-Klasse mit der folgenden Methode.

@Override 
public void changeSelection(int row, int column, boolean toggle, boolean extend) { 
    super.changeSelection(row, column, toggle, extend); 
    if (editCellAt(row, column)) { 
     Component editor = getEditorComponent(); 
     editor.requestFocusInWindow(); 
     if (editor instanceof JFormattedTextField) { 
      ((JFormattedTextField) editor).select(0, 
        ((JFormattedTextField) editor).getText().length()); 
     } else if (editor instanceof JTextField) { 
      ((JTextField) editor).selectAll(); 
     } 
    } 
} 

Nach vieler Dokumentation und Beiträgen zu lesen, ist es klar wurde, dass der am besten geeignete Weg, um das Problem durch die Verwendung von Schlüsseln Bindungen, im Grunde und nach alle Lese war zu begegnen, war die Lösung, die das Verhaltens zuweisen der Schlüssel Tab zu dem Schlüssel Enter, und so tat ich.

private void tableConfiguration() { 
    //Configuramos la tabla para que en el caso de que pierda el foco finalice la edición 
    putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);   
    //Cambiamos el comportamiento por defecto de la tecla enter para que actue como TAB 
    getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 
      .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "selectNextColumnCell"); 
    // cambiamos Shift+Enter para que se comporte como Shift+Tab 
    getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 
      .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK), 
      "selectPreviousColumnCell"); 
    //configuramos el comportamiento por defecto que queremos que tenga nuestro grid 
    setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//seleccion simple de celda 
    setCellSelectionEnabled(true);//muestra la celda activa seleccionada 
    getTableHeader().setReorderingAllowed(false);//no permite reordenar por columnas 
    setRowHeight(26);//altura de la fila 
} 

Wie Sie im Code-Abschnitt sehen können, wurden sie zugewiesen Enter und Shift+Enter das Verhalten von Tab den Shift+Tab Tasten.

Das Problem, das ich habe, ist, dass der Schlüssel Enter ein unerwartetes Verhalten hat. Wenn die Zelle den Fokus erreicht, geht sie direkt in den Bearbeitungsmodus, wenn ich die Taste Enter drücke, beendet sie die Bearbeitung, aber sie überträgt den Fokus nicht auf die nächste Zelle. Ich muss erneut die Taste Enter drücken, um das zu bekommen. Tab und Shift+Tab Tasten funktioniert wie erwartet und neugierig, Shift+Enter Tasten funktioniert auch gut, Bearbeitung beenden, in die vorherige Zelle verschieben und im Bearbeitungsmodus starten.

Ich habe versucht, dieses Verhalten nach verschiedenen Strategien zu korrigieren, das Überschreiben der Methode editingStopped der Klasse JTable, durch die TableCellEditor Klasse, mit Hörern in diferent Weise, etc, und ich habe nicht in der Lage gewesen, dieses Verhalten zu korrigieren, so I‘ Ich stecke jetzt fest. Hat jemand eine Anregung oder die Lösung? Was mache ich falsch?

Grüße,

+0

((JTextField) -Editor).Wählen Sie Alle(); sollte innerhalb von invokeLater (Verschieben dieses Ereignisses an das Ende der EDT-Warteschlange) – mKorbel

+0

Hallo @mKorbel danke für Ihre Hilfe, ich tat wie Sie vorgeschlagen, aber es hat keine Auswirkungen auf das Verhalten der JTable, es verhält sich immer noch wie oben beschrieben, Tab ',' Shift + Tab' und 'Shift + Enter' arbeiten wie gewünscht, beenden das Editieren der Zelle, wechseln zur nächsten Zelle mit' Tab', zum vorherigen mit 'Shift + Tab' oder' Shift + Enter' und wechseln Sie automatisch in den Bearbeitungsmodus der neuen Zelle, während Sie die Eingabetaste zweimal drücken müssen, um die Bearbeitung zu beenden und zur nächsten Zelle zu wechseln, um sie zu bearbeiten. Ich suche nach dem Weg, dieses Verhalten zu vermeiden. Danke – CodeCat

Antwort

1

Wie here gezeigt, können Sie einen Verweis auf die ursprünglichen Action mit "selectNextColumnCell" assoziiert erhalten, die in der Regel mit Tab und evozieren es in Ihrer Implementierung von editingStopped() verbunden ist. Das vereinfachte Beispiel unten verknüpft die Aktion auch mit dem Drücken von Geben Sie ein. Das Ergebnis ist, dass das Drücken von Enter den gleichen Effekt hat wie das Drücken von Tab, auch wenn der Tastendruck auch die Bearbeitung beendet.

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.KeyStroke; 
import javax.swing.event.ChangeEvent; 

public class TestTableKeyBinding { 

    private final String name = "selectNextColumnCell"; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> { 
      new TestTableKeyBinding(); 
     }); 
    } 

    TestTableKeyBinding() { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     String[] headers = new String[]{"apples", "bananas"}; 
     String[][] data = new String[][]{{"1", "2"}, {"3", "4"}, {"5", "6"}}; 
     JTable table = new JTable(data, headers) { 
      @Override 
      public void editingStopped(ChangeEvent e) { 
       super.editingStopped(e); 
       this.getActionMap().get(name).actionPerformed(
        new ActionEvent(this, ActionEvent.ACTION_FIRST, name)); 
      } 
     }; 
     table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 
      .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), name); 
     table.setCellSelectionEnabled(true); 
     f.add(new JScrollPane(table)); 
     f.pack(); 
     f.setSize(new Dimension(320, 240)); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 
} 
+0

danke, aber leider funktioniert es nicht so wie ich es will, wenn du im Bearbeitungsmodus bist "Enter" bewegt sich zur nächsten Zelle aber "Shift + Enter" bewegt sich auch, und wenn du die 'Tab' Taste benutzt hast es jetzt ein seltsames Verhalten, weil die Bearbeitung nicht mit der fokussierten Zelle übereinstimmt. Mein einziges Problem ist, wie man dieses spezielle Verhalten der 'Enter'-Taste ändert, das die anderen Tasten nicht haben. – CodeCat

+0

Ich verstehe nicht. Bitte bearbeiten Sie Ihre Frage, um eine [mcve], basierend auf meinem vereinfachten Beispiel oben, einzubinden, die Ihren aktuellen Ansatz zeigt. – trashgod

+0

hallo trashgod und danke im Voraus für Ihre Hilfe, da ich hier kein vollständiges Beispiel geben kann, habe ich es in mein [Google-Laufwerk] hochgeladen (https://drive.google.com/file/d/0B6L3Kw_8T4q-dEpvVHE0SHFhekk/ view? usp = sharing) wo du es bekommen kannst und einen Blick darauf werfen kannst, was ich in meinem vorherigen Kommentar gesagt habe. Schauen Sie sich speziell das Verhalten der Tab-Taste und der Shift-Taste an. Nochmals vielen Dank im Voraus. Schöne Grüße. – CodeCat