2016-07-15 8 views
0

Kurzfassung: Angesichts einer JTable mit einem TableModel, die DefaultTableModel erweitert, kann ich den gesamten Text in einer Zelle mit der Klasse String ohne die Verwendung eines CellEditors auswählen?Gibt es eine Möglichkeit, den gesamten Text in einer Zelle in einer JTable ohne CellEditor auszuwählen?

Lange Version: Ich habe ein TableModel erstellt, das DefaultTableModel erweitert und sollte nur auswählbare Zeilen bearbeitbar sein. Hier sind die relevanten Teile:

class MyTableModel extends DefaultTableModel { 

    private List<String> columnNames; 
    private List<List<String>> strings; 

    /** editable stores the columns which we're allowed to change */ 
    private List<Integer> editable; 

    public MyTableModel (List<String> columnNames, List<List<String>> 
      strings, List<Integer> editable) { 
     this.columnNames = columnNames; 
     this.strings = strings; 
     this.editable = editable; 
    } 

    public Object getValueAt(int row, int col) { 
     return strings.get(col).get(row); 
     return null; 
    } 

    public void setValueAt(Object value, int row, int col) { 
     strings.get(col).set(row, (String) value); 
     fireTableCellUpdated(row, col); 
    } 

    public boolean isCellEditable(int row, int col) { 
     return canEdit(col); 
    } 

    /** 
    * This method looks like it should be lumped into isCellEditable() 
    * But there's unique behavior I plan on having later for the first 
    * column and this will let my code down the road be much cleaner. 
    **/ 
    public boolean canEdit(int col) { 
     return col != 0 && editable.indexOf(col) != -1; 
    } 
} 

Soweit verstehen, der DefaultTableModel behandelt Zellen besiedelt mit Strings als JTextFields. Wir verwenden diese Tabelle, um sie mit zwei Spalten zu füllen. Eine nicht editierbare Spalte mit Dateinamen (als Strings), gefolgt von einer bearbeitbaren leeren Spalte mit Strings. Wenn eine editierbare Zelle ausgewählt ist, möchte ich, dass sie den Text des Dateinamens davor setzt und dann den gesamten Text auswählt (später führt der Benutzer einen Befehl aus, der für jede Datei ein optionales String-Feld hat, also wenn ein Dateiname Die verknüpfte editierbare Zelle ist nicht leer, sie verwendet diesen Wert. Wir möchten nicht, dass der Benutzer den gesamten Dateinamen jedes Mal neu eingeben muss, wenn sie dies festlegen, sondern ihnen auch die Möglichkeit geben möchten, dies schnell zu tun, wenn sie dies möchten.

Die Tabelle verfügt über einen MouseListener, der überprüft, ob eine bearbeitbare Zelle angeklickt wurde, und falls dies der Fall ist, füllt sie auch die Zelle mit dem Namen der Datei davor aus.

Das funktioniert gut, aber ich kann den Text nicht ausgewählt werden. Ich kann anscheinend keine Methode finden, die die Komponente einer Zelle zurückgibt, und ich habe einen CellEditor hinzugefügt, den ich online gefunden habe, aber er ändert nichts.

class MyCellEditor extends DefaultCellEditor { 

    public MyCellEditor(JTextField textField) { 
     super(textField); 

     textField.addFocusListener(new FocusAdapter() { 
      public void focusGained(FocusEvent e) { 
       textField.selectAll(); 
      } 
     }); 
    } 
} 

hinzugefügt, um die Tabelle mit diesem:

for(int i = 0; i < table.getRowCount(); i++) 
    table.setCellEditor(new MyCellEditor(new 
       JTextField((String)table.getValueAt(i, 2)))); 

Dinge würden viel einfacher, wenn es eine Möglichkeit gäbe, den CellEditor ganz wegzulassen, aber wenn es etwas, was ich habe, wie vermasseln die Reihenfolge getan Diese Zuhörer verarbeiten Ereignisse, ich nehme nichts dagegen. Was ich vermeiden möchte, ist, dass ich einen riesigen CellEditor schreiben oder jeden Code überarbeiten muss, nur um ein kleines bisschen Bequemlichkeit hinzuzufügen.

+1

* „Hier ist die relevanten Teile:“ * Für eine bessere Hilfe früher, Posten [MCVE] oder [Kurzes, eigenständiges, korrektes Beispiel] (http://www.sscce.org/). –

+0

* "X funktioniert gut, aber .." * (seufzt) Ich wünschte, ich hätte einen Dollar für jedes Mal, wenn ich solche Wörter gelesen habe. –

+0

"Je mehr Code es gibt, desto weniger Leute können deine finden Problem: Optimieren Sie Ihr Beispiel auf zwei Arten: Neustart von Grund auf neu Erstellen Sie ein neues Programm und fügen Sie nur das hinzu, was erforderlich ist, um das Problem zu sehen.Dies kann für große Systeme schneller sein, bei denen Sie die Quelle des Problem Auch nützlich, wenn Sie den ursprünglichen Code aus rechtlichen oder ethischen Gründen nicht öffentlich veröffentlichen können Teilen und erobern Wenn Sie eine kleine Menge Code haben, aber die Ursache des Problems völlig unklar ist, starten Sie den Code ein wenig zu entfernen eine Zeit bis das Problem verschwindet - dann .... " –

Antwort

3

Versuchen Sie, die selectAll() Anweisung in eine SwingUtilities.invokeLater(...) zu wickeln.

See: how do I simulate "onStartCellEditing" for DefaultCellEditor

für ein allgemeines Beispiel für Text in einer beliebigen Zelle auswählt, wenn Zelle Bearbeitung gestartet wird:

+0

Vielen Dank! Ich kopiere und klebte einfach die übergeordnete Funktion direkt nach "= new JTable() {", und es funktionierte wie ein Zauber! Eine weitere Frage. Wenn ich die Box anwähle, kann ich sie direkt bearbeiten, und der Text wird ausgewählt, aber nicht hervorgehoben. Ich muss noch doppelklicken, um hinein zu kommen und meinen Cursor zu setzen. Ich habe versucht, GrabFocus() vor oder nach selectAll() hinzufügen, aber keiner der beiden funktionierte. Das ist ein ziemlich kleines Problem, aber unsere Benutzer sind nicht phänomenal computeraffin, also denke ich, dass das Highlighting des Textes ihnen sehr helfen würde. –

+0

Scratch das. Ich wechselte von grabFocus() zu requestFocusInWindow() und fügte dann einen expliziten Aufruf von editCell (row, col) am Ende meiner mouseReleased() -Funktion auf dem Tisch hinzu und es funktioniert perfekt! Danke nochmal für die Hilfe! –