2009-10-20 6 views
0

Je suis un peu nouveau sur Java, et particulièrement nouveau dans les tables, et j'ai un peu de mal avec une tâche particulière.Supprimer des lignes d'un DefaultTableModel avec un RowSorter joint ne supprime pas la dernière ligne

J'ai une JTable qui utilise un modèle de table personnalisé qui étend DefaultTableModel, et j'ai attaché un TableRowSorter à la table. L'exemple d'application ci-dessous comporte deux boutons: l'un chargera les lignes dans la table et l'autre supprimera toutes les lignes sélectionnées de la table.

Pour une raison quelconque, si vous sélectionnez la dernière ligne du tableau avec une autre ligne, lorsque vous cliquez sur le bouton "Supprimer", toutes les lignes sélectionnées seront supprimées à l'exception de la dernière ligne. Vous pouvez supprimer toute autre combinaison de lignes et cela fonctionne très bien. De plus, si vous cliquez d'abord sur l'en-tête de colonne pour trier les lignes (même si l'ordre des lignes ne change pas), cela fonctionnera correctement. Si j'ajoute une ligne pour trier explicitement les lignes de la table après l'avoir chargé, le problème «disparaît», mais j'aimerais savoir pourquoi ce que je fais est incorrect.

Pour voir le comportement, cliquez sur le bouton "Charger" pour remplir le tableau, sélectionnez toutes les lignes dans le tableau, puis cliquez sur le bouton "Supprimer". Cela supprimera toutes les lignes sauf la dernière. Comme l'appel à println montre, la première itération à travers la boucle réduit le nombre de lignes sélectionné par deux. Ce comportement est cohérent, quel que soit le nombre de lignes que vous avez dans la table, mais uniquement si vous avez sélectionné la dernière ligne de la table. J'utilise Java version 1.6.0_16. Des idées sur ce que je fais mal?

Merci,

Joe

import javax.swing.*; 
import javax.swing.table.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.Vector; 
import java.util.Arrays; 

public class TableTest 
extends JFrame 
{ 
    private JTable widgetTable; 
    private WidgetTableModel widgetTableModel; 

    public static void main(String[] args) 
    { 
    TableTest frame = new TableTest(); 
    frame.setSize(600, 400); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    } 

    public TableTest() 
    { 
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

    EventQueue.invokeLater(new Runnable() { public void run() { createUI(); } }); 
    } 

    private void createUI() 
    { 
    this.setLayout(new BorderLayout()); 

    JButton loadButton = new JButton("Load"); 
    loadButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     loadPerformed(); 
     } 
    }); 

    this.add(loadButton, BorderLayout.NORTH); 

    widgetTableModel = new WidgetTableModel(); 
    widgetTable = new JTable(widgetTableModel); 
    widgetTable.setRowSorter(new TableRowSorter<WidgetTableModel>(widgetTableModel)); 
    this.add(new JScrollPane(widgetTable), BorderLayout.CENTER); 

    JButton removeButton = new JButton("Remove"); 
    removeButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     removePerformed(); 
     } 
    }); 

    this.add(removeButton, BorderLayout.SOUTH); 
    } 

    private void loadPerformed() 
    { 
    widgetTableModel.addRow(new Object[] {"Widget 1"}); 
    widgetTableModel.addRow(new Object[] {"Widget 2"}); 
    widgetTableModel.addRow(new Object[] {"Widget 3"}); 
    widgetTableModel.addRow(new Object[] {"Widget 4"}); 
    widgetTableModel.addRow(new Object[] {"Widget 5"}); 
    } 

    private void removePerformed() 
    { 
    int selectedRow = widgetTable.getSelectedRow(); 

    while (selectedRow >= 0) { 
     System.out.println("selectedRowCount=" + widgetTable.getSelectedRowCount()); 
     int modelRow = widgetTable.convertRowIndexToModel(selectedRow); 
     widgetTableModel.removeRow(modelRow); 
     selectedRow = widgetTable.getSelectedRow(); 
    } 
    } 
} 


class WidgetTableModel 
extends DefaultTableModel 
{ 
    public WidgetTableModel() 
    { 
    this.addColumn("Column 1"); 
    } 
} 

Répondre

0

changer le "tout" à un "si". Sélectionnez toutes les lignes, puis cliquez sur le bouton. Pour une raison quelconque, la dernière rangée perd sa sélection. Je ne sais pas pourquoi.

Je trouve que la logique de suppression doit généralement être effectuée à partir de la dernière ligne jusqu'à 0. De cette façon, vous n'avez pas à vous soucier des changements de valeurs d'index de lignes lorsqu'une ligne est supprimée. Vous devez donc utiliser la méthode getSelectedRows() et parcourir le tableau dans l'ordre inverse. Bien que, je dois admettre que je n'ai jamais fait cela sur une table triée, donc je ne suis pas sûr si cela va causer un problème ou non.

+0

Itère les lignes sélectionnées en sens inverse l'ordre devrait fonctionner, mais cela ne semble pas nécessaire. La façon dont l'exemple fonctionne maintenant devrait être tout aussi fiable - toujours obtenir la première ligne sélectionnée dans la table. Cela supprime également le besoin de garder une trace des changements d'index. Le problème semble être le "bug" (ou la source) qui provoque la désélection de la dernière ligne. –

0

ont également discuté sur java.net: http://www.java.net/node/698236

Il est bug #6894632 dans le noyau DefaultRowSorter: à sa base (comme cela est expliqué dans le rapport) est une sémantique pas si bien définies de getModelRowCount(). Il est fixé dans SwingX DefaultSortController

/** 
* Additionally, this implementation contains a fix for core 
* <a href=http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6894632>Issue 6894632</a>. 
* It guarantees to only touch the underlying model during sort/filter and during 
* processing the notification methods. This implies that the conversion and size query 
* methods are valid at all times outside the internal updates, including the critical 
* period (in core with undefined behaviour) after the underlying model has changed and 
* before this sorter has been notified. 
*/ 

Malheureusement, le fil dans le forum SwingLabs contenant l'analyse complète (était: http://www.java.net/jive/thread.jspa?threadID=77343) n'est plus disponible après la migration du projet ...

Questions connexes