2017-10-30 2 views
0

Ich muss JTable (Object[][] data, Object[] headers) nach dem Hinzufügen neuer Zeile sortieren.Sortieren von JTable nach dem Hinzufügen von Zeilen

Hier ist der Code (nicht funktioniert)

public class Window extends JFrame { 
    Window() { 
     super(); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     JTable table = new JTable(); 
     table.setModel(new DefaultTableModel(null, new String[]{"col1"})); 
     TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel()); 
     sorter.setComparator(0, new Comparator<String>() { 
      @Override 
      public int compare(String o1, String o2) { 
       return o1.compareTo(o2); 
      } 
     }); 
     sorter.setSortsOnUpdates(true); 
     table.setRowSorter(sorter); 

     DefaultTableModel model = (DefaultTableModel)table.getModel(); 
     model.addRow(new String[] {"A"}); 
     model.addRow(new String[] {"C"}); 
     model.addRow(new String[] {"B"}); 

     this.getContentPane().add(table); 
     pack(); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new Window(); 
    } 
} 

Output Ergebnis: Tabelle (A, C, B), erwartet (A, B, C)

Modell - DefaultTableModel
deviceTable - jtable

+0

Für beste Hilfe sortiert sind, erstellen Sie bitte und senden Sie sich ein gültiges [MCVE] - ein kleines Programm, klein genug, um in Ihrer Frage zu stellen vollständig als Code - formatierter Text, den wir ohne Änderungen kompilieren und ausführen können und der Ihr Problem für uns demonstriert. –

+0

@HovercraftFullOfEels hinzugefügt MCVE – Ladence

Antwort

1

Basierend auf Ihrem Beispiel, benötigen Sie einen Sortierschlüssel zu definieren, sonst wird die Tabelle effektiv unsortiert ...

List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); 
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); 
sorter.setSortKeys(sortKeys); 
table.setRowSorter(sorter); 

Das folgende Beispiel (basierend auf Ihrem) sortiert die erste Spalte. Wenn Sie auf die Schaltfläche tippen, fügt es die Zeilen, die dann

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Comparator; 
import java.util.List; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.RowSorter; 
import javax.swing.SortOrder; 
import javax.swing.SwingUtilities; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableModel; 
import javax.swing.table.TableRowSorter; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       JTable table = new JTable(); 
       table.setModel(new DefaultTableModel(null, new String[]{"col1"})); 
       TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel()); 
       sorter.setComparator(0, new Comparator<String>() { 
        @Override 
        public int compare(String o1, String o2) { 
         return o1.compareTo(o2); 
        } 
       }); 
       sorter.setSortsOnUpdates(true); 
       List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); 
       sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); 
       sorter.setSortKeys(sortKeys); 
       table.setRowSorter(sorter); 

       JButton btn = new JButton("..."); 
       btn.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         DefaultTableModel model = (DefaultTableModel) table.getModel(); 
         model.addRow(new String[]{"A"}); 
         model.addRow(new String[]{"C"}); 
         model.addRow(new String[]{"B"}); 
        } 
       }); 

       frame.add(new JScrollPane(table)); 
       frame.add(btn, BorderLayout.SOUTH); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

} 
+0

vielen dank! Es funktioniert wirklich, aber nur visuell (wenn ich Zeile auswähle und table.getSelectedRow() aufruft, gibt es die alte Position zurück) – Ladence

+0

Ja, 'RowSorter' führt eine" virtuelle "Sortierung durch, sortiert die Zeilenindizes, die dann zwischen der Ansicht und zugeordnet werden das Model. Sie müssen die 'JTable # convertRowIndexToModel' und' JTable # convertRowIndexToView' verwenden, um zwischen dem Modell und der Ansicht zu übersetzen. All dies wird im Lernprogramm [Verwendung von Tabellen, Sortieren und Filtern] (https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#sorting) behandelt. Dies bedeutet, dass das Modell dies ist nie verändert – MadProgrammer

1
model.fireTableDataChanged(); 

Sie die fireXXX() Methoden nicht direkt aufrufen.

Es liegt in der Verantwortung, dass TableModel die entsprechende Methode aufruft (in diesem Fall wäre dies fireTableRowsInserted).

Edit:

Sie sich von dem Code befreien, die den Sortierer und der Komparator erzeugt.

Sie lassen nur die Tabelle den Sortierer erstellen. Aber dann, wenn Sie dies tun, müssen Sie den Sortierer sagen, welche Spalte sortieren:

table.setAutoCreateRowSorter(true); 
((DefaultRowSorter)table.getRowSorter()).toggleSortOrder(0); 
+0

Es hilft nicht – Ladence

+0

Dann poste deine [mcve], die das Problem demonstriert. Sie beginnen also damit, mit fest codierten Daten zu testen, um die MCVE vollständig zu machen, da wir keinen Zugriff auf Ihr benutzerdefiniertes Objekt benötigen, um zu beweisen, dass das Modell automatisch sortiert wird, wenn Daten hinzugefügt werden. Außerdem sind revalidate() und repaint() nicht erforderlich. Swing-Komponenten werden automatisch neu gezeichnet, wenn das Modell geändert wird. Schließlich, warum verwenden Sie einen benutzerdefinierten Vergleicher? Ein String Comparator wird standardmäßig verwendet. – camickr

+0

Wie kann ich Standard-String-Komparator übergeben? – Ladence

Verwandte Themen