TableRowSorter nicht beim Klick auf TableHeader sortieren

ElJarno

Mitglied
Hi Leute,
der Titel sagst eigentlich schon. Wollte gern, das Sortieren des TableRowSorter über ein Pop-Up Menü steuern und nicht über den Klick auf den Tabellenkopf.

gruß Jan
 
Hi!
Schau dir mal das an:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TestFrame.java
 *
 * Created on 05.05.2010, 18:09:27
 * 
 */

package javaapplication5;

import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.table.TableRowSorter;

/**
 *
 * @author jw
 */
public class TestFrame extends javax.swing.JFrame {

    /** Creates new form TestFrame */
    private TableRowSorter sorter = null;
    public TestFrame() {
        initComponents();
        init();

    }
    private void init(){
        sorter = new TableRowSorter();
        sorter.setModel(jTable1.getModel());
        jTable1.setRowSorter(sorter);
        /* Falls nicht auf Klicks auf den Table Header reagiert werden soll
         * dann diese Zeilen auskommentieren.
         * Ist aber nur ne Quick and Dirty Lösung, da Tooltips und alles was sonst so mit MouseKlicks
         * auf den TableHeader zu tun hat, nun nicht mehr funktioniert.
         * Falls das gebraucht wird, muss man die Lösung noch ein wenig verfeinern. 
        MouseListener ml[] =jTable1.getTableHeader().getMouseListeners();
        for (MouseListener l : ml){
            jTable1.getTableHeader().removeMouseListener(l);
        }
         */ 
    }
   

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"211", "55", "99", "fthfh"},
                {"22", "66", "00", null},
                {"33", "77", "9879", "fgh"},
                {"44", "88", "9", "fgh"}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(jTable1);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jButton1.setText("Sort");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sortTable(evt);
            }
        });
        getContentPane().add(jButton1, java.awt.BorderLayout.PAGE_START);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-579)/2, (screenSize.height-363)/2, 579, 363);
    }// </editor-fold>

    private void sortTable(java.awt.event.ActionEvent evt) {
       ArrayList<RowSorter.SortKey> keys = new ArrayList<RowSorter.SortKey>();
       RowSorter.SortKey key = new RowSorter.SortKey(0,SortOrder.DESCENDING);
       keys.add(key);
       sorter.setSortKeys(keys);
       sorter.sort();
     
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration

}
 
Jo sowas hab ich gesucht, hab mir schon gedacht, dass ich die Listener einfach von der Header entfernen muss. Hatte nur nach den Listnener direkt in der JTable gesucht. Hab mir jetzt was anderes überlegt und leg mir das Pop-Up auf die Rechte Maustaste und das Sortiern bleibt ja auf die Linke Maustaste begrenzt. Diese Form der Bearbeitung hat sich ja auch bei Windows und anderen Produkten bewährt. Nur jetzt hab ich beim leeren und Befüllen der TableModel zig Exceptions wie sie auch bei der AutoRowSorter von der JTable vorkommen. tableModel.fireDateChanged() bringts nicht wirklich.

Gruß Jan
 
Moin!
Poste doch mal ein einfaches, lauffähiges Beispiel, bei dem man die Exceptions zu sehen bekommt.

Gruß!
 
Habs soweit hinbekommen, trotzdem einfach mal reingucken obs so in Ordnung ist oder obs was Besseres gibt. Entferne vor dem Befüllen der TableModel den Sorter und setzt ihn danach wieder auf. Zum Schluss noch die fireTableDataChanged(). Wenn ich diese weglasse oder vor dem Hinzufügen der RowSorter setzt kommen die untenstehende Fehlermeldungen.

Code:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3 >= 0
	at java.util.Vector.elementAt(Vector.java:427)
	at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:632)
	at javax.swing.JTable.getValueAt(JTable.java:2686)
	at javax.swing.JTable.prepareRenderer(JTable.java:5703)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2072)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1974)
	at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1770)
	at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
	at javax.swing.JComponent.paintComponent(JComponent.java:752)
	at javax.swing.JComponent.paint(JComponent.java:1029)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
	at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
	at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
	at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Code:
	public void pflegeDatensatz() {
		TableRowSorter<TMOeffnungszeit> rowSorter = null;
		if (this.jPanelTimeIT.getJTable().getRowSorter() != null) {
			rowSorter = (TableRowSorter<TMOeffnungszeit>) this.jPanelTimeIT.getJTable()
					.getRowSorter();
			this.jPanelTimeIT.getJTable().setRowSorter(null);
		}
		this.dbReadMySQL.setConnection();
		this.dbWriteMySQL.setConnection();

		if (!dbDatum.isWeOderFeiertag()) {
			try {
				this.readDataDB(getStatement());
			} catch (ParseException e) {
				JOptionPane.showMessageDialog(null, "Fehler beim Lesen der Öffnungszeitentabelle: "
						+ e.getMessage(), "Info", JOptionPane.WARNING_MESSAGE);
			}
		} else {

			this.tmMethods.clearTMOeffnungszeit();
			this.jPanelTimeIT.getJLabelInfo().setText(
					"Bei dem " + this.dbDatum.getSqlDatumNFormat()
							+ " handelt sich um einen Wochenend- oder Feiertage");
		}
		this.dbReadMySQL.closeConnection();
		this.dbWriteMySQL.closeConnection();

		if (this.jPanelTimeIT.getJTable().getRowSorter() == null) {
			if (rowSorter != null) {
				this.jPanelTimeIT.getJTable().setRowSorter(rowSorter);
			}
		}
		this.tmMethods.getTmOeffnungszeit().fireTableDataChanged();
	}

In dem folgende Link wird beschrieben wie dieses Problem beim AutoRowSorter auftritt und dass er es auf die ähnliche Weise löst.
http://tippsundtools.blogspot.com/2009/12/tabellen-in-java-swing-per-klick.html.

Gruß Jan
 
Hi!
aus deinem Beispiel kann ich nun nicht genau erkennen, wie du du das Model füllst, bzw. ob es neu erstellt wird. Vielleicht würde es auch reichen, ein fireTableChanged oder ein fireTableStructureChanged abzufeuern, nachdem du deine Daten eingelesen hast.

Falls das nicht helfen sollte, kann ich nun aber nichts erkennen, was gegen die Lösung aus dem Link sprechen würde..

*grüssle*
 
Zurück