DefaultTableModel / JTable sortieren

fred31

Mitglied
Hi,

ich würde gerne ein DefaultTableModel sortieren.
Frage: wie mache ich das?

Ich will nur die Daten innerhalb des TableModels sortieren, nicht die Daten sortiert anzeigen (mittels eines JFrame oder ähnliches).
 
Re: DefaultTableModel

Tach,
wie gut sind Deine Vorkenntnisse? Wie allgemein soll die Sortierung sein? Wie liegen die Daten in der Tabelle vor? ...?
 
Re: DefaultTableModel

Hallo!

Bau dir eine Comparator Klasse welches das Comparable Interface implementiert und weis wie deine Elemente innerhalb des DefaultTableModel sortiert werden müssen.
Dann verwendest du einfach Arrays.sort(...) bzw. Collections.sort(...)

Gruß Tom
 
Re: DefaultTableModel

Thomas Darimont hat gesagt.:
Bau dir eine Comparator Klasse welches das Comparable Interface implementiert und weis wie deine Elemente innerhalb des DefaultTableModel sortiert werden müssen.

Vielleicht ne dumme Frage: wie mache ich das?
 
Re: DefaultTableModel

Hallo!

Wenn du die Daten innerhalb eines TableModels sortierst und dieses mit einer JTable "verbunden" ist wird spätestens beim nächsten repaint die neue "Form" angezeigt...
Wenn du das nicht willst musst du ein neues DefaultTableModel erzeugen welches eine Kopie (clone()) des DataVectors des ursprünglichen TableModel arbeitet.

Aber schau mal hier:
Code:
/*
 * Created on 07.02.2005@10:19:11
 *
 * TODO Licence info
 */
package de.tutorials;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 * @author Administrator
 *
 * TODO Explain me
 */
public class JTableExample extends JFrame {

    private JTable table;

    private DefaultTableModel model;

    private JButton btnSort;

    public JTableExample() {
        super("JTableExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Object[][] rowData = { { "b", "d" }, { "a", "d" }, { "a", "b" } };
        Object[] columnHeaders = { "Header1", "Header2" };
        model = new DefaultTableModel(rowData, columnHeaders);

        table = new JTable(model);
        btnSort = new JButton("Sortieren");
        btnSort.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Vector v = model.getDataVector();
                sortAndUpdate(v);
            }
        });

        Container c = getContentPane();
        c.add(table, BorderLayout.CENTER);
        c.add(btnSort, BorderLayout.SOUTH);

        pack();
        setVisible(true);
    }

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

    /**
     * 
     */
    private void sortAndUpdate(Vector v) {
        Collections.sort(v, new Comparator() {
            public int compare(Object o1, Object o2) {

                Vector v1 = (Vector) o1;
                Vector v2 = (Vector) o2;

                int cmp = 0;

                for (int i = 0, size1 = v1.size(); i < size1; i++) {
                    String s1 = (String) v1.get(i);
                    String s2 = (String) v2.get(i);
                    cmp += s1.compareTo(s2);
                }

                return cmp;
            }
        });
        table.updateUI();
    }
}


Gruß Tom
 
Re: DefaultTableModel

Hi,

schon mal vielen Dank für die Hilfe soweit!
Ich habe leider kein JTable (oder änhliches), in dem ich das genüsslich anzeigen könnte (dazu habe ich auch außerordentlich viel im Netz gefunden).

Ich erbe von der Klasse DefaultTableModel und möchte in dieser TableModel nun noch die Funktion "sort()" bzw. "sortByColum(int colum)" realisieren.

Meine Klasse muss hierfür (wenn ich das richtig verstanden habe) den Comparator implementiert haben (und die Funktion "compare(Object obj1, Object obj2)");


....und genau jetzt steh ich auf dem Schlauch!
In meinem DefaultTableModel sind mehrere Vectoren drin, diese enthalten Strings.
Und wie nun weiter?

Über ne Idee wär ich echt dankbar!
 
Re: DefaultTableModel

Hallo!

Klick doch mal auf die Spaltenüberschriften ;-)
Code:
/*
 * Created on 07.02.2005@10:19:11
 *
 * TODO Licence info
 */
package de.tutorials;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 * @author Administrator
 *
 * TODO Explain me
 */
public class JTableExample extends JFrame {

    private JTable table;

    private FooTableModel model;

    public JTableExample() {
        super("JTableExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Object[][] rowData = { { "a", "c" }, { "b", "b" }, { "c", "a" } };
        Object[] columnHeaders = { "Header1", "Header2" };
        model = new FooTableModel(rowData, columnHeaders);

        table = new JTable(model);

        table.getTableHeader().addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                model.sortByColumn(table.columnAtPoint(evt.getPoint()));
            }
        });

        Container c = getContentPane();
        c.add(new JScrollPane(table), BorderLayout.CENTER);

        pack();
        setVisible(true);
    }

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

    class FooTableModel extends DefaultTableModel {
        public FooTableModel(Object[][] rowData, Object[] headers) {
            super(rowData, headers);
        }

        public void sortByColumn(final int clm) {
            Collections.sort(this.dataVector, new Comparator() {
                public int compare(Object o1, Object o2) {
                    Vector v1 = (Vector) o1;
                    Vector v2 = (Vector) o2;

                    int size1 = v1.size();
                    if (clm >= size1)
                        throw new IllegalArgumentException("max column idx: "
                                + size1);

                    String s1 = (String) v1.get(clm);
                    String s2 = (String) v2.get(clm);

                    return s1.compareTo(s2);
                }
            });
        }
    }
}

Gruß Tom
 
Re: DefaultTableModel

Leck mich am , ES TUT!

Aufsteigend/Absteigend ist ja, dank Dir, auch nur noch en Kindergeburstag.
public void sortByColumn(int i) ist mal absolut gigantisch!

Tom, ich werde Dich in meine Abendgebete einschließen!
Vielen vielen Dank, Du hast mir echt sehr geholfen!


@admin: warum das Ding hier jetzt in Swing/AWT gelandet ist, obwohl es mal gar nich gar nix nix mit Oberflächen (sondern eben mit Datenstrukturen) zu tun hat, find ich übrigens schon komisch...
 
Zuletzt bearbeitet:
Re: DefaultTableModel

Hallo!

... kleiner Nachschlag:
Code:
/*
 * Created on 07.02.2005@10:19:11
 *
 * TODO Licence info
 */
package de.tutorials;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;

import com.sun.java.swing.plaf.motif.MotifGraphicsUtils;

/**
 * @author Administrator
 *
 * TODO Explain me
 */
public class JTableExample extends JFrame {

    private JTable table;

    private FooTableModel model;

    private final ImageIcon UP_ICON = new ImageIcon(MotifGraphicsUtils.class
            .getResource("icons/ScrollUpArrow.gif"));

    private ImageIcon DOWN_ICON = new ImageIcon(MotifGraphicsUtils.class
            .getResource("icons/ScrollDownArrow.gif"));

    public JTableExample() {
        super("JTableExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Object[][] rowData = { { "a", "c" }, { "b", "b" }, { "f", "r" },{ "q", "a" },{ "w", "z" },{ "c", "a" } };
        Object[] columnHeaders = { "Header1", "Header2" };
        model = new FooTableModel(rowData, columnHeaders);

        table = new JTable(model);

        final GeneralPath path = new GeneralPath();
        path.moveTo(0.0F, 0.0F);
        path.lineTo(7.5F, 7.5F);
        path.lineTo(15.0F, 0.0F);
        path.closePath();

        table.getTableHeader().setDefaultRenderer(
                new DefaultTableCellRenderer() {

                    public Component getTableCellRendererComponent(
                            JTable table, Object value, boolean isSelected,
                            boolean hasFocus, int row, int column) {

                        JTableHeader header = table.getTableHeader();
                        setForeground(header.getForeground());
                        setBackground(header.getBackground());
                        setFont(header.getFont());

                        setText(value == null ? "" : value.toString());
                        setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                        setHorizontalAlignment(SwingConstants.CENTER);
                        setHorizontalTextPosition(SwingConstants.LEFT);

                        if (model.sortColumnDesc[column]) {
                            setIcon(UP_ICON);
                        } else {
                            setIcon(DOWN_ICON);
                        }

                        return this;
                    }
                });

        table.getTableHeader().addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                model.sortByColumn(table.columnAtPoint(evt.getPoint()));
            }
        });

        Container c = getContentPane();
        c.add(new JScrollPane(table), BorderLayout.CENTER);

        pack();
        setVisible(true);
    }

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

    class FooTableModel extends DefaultTableModel {

        private boolean[] sortColumnDesc;

        public FooTableModel(Object[][] rowData, Object[] headers) {
            super(rowData, headers);
            sortColumnDesc = new boolean[headers.length];
        }

        public void sortByColumn(final int clm) {
            Collections.sort(this.dataVector, new Comparator() {
                public int compare(Object o1, Object o2) {
                    Vector v1 = (Vector) o1;
                    Vector v2 = (Vector) o2;

                    int size1 = v1.size();
                    if (clm >= size1)
                        throw new IllegalArgumentException("max column idx: "
                                + size1);

                    Comparable c1 = (Comparable) v1.get(clm);
                    Comparable c2 = (Comparable) v2.get(clm);

                    int cmp = c1.compareTo(c2);

                    if (sortColumnDesc[clm]) {
                        cmp *= -1;
                    }

                    return cmp;
                }
            });
            model.sortColumnDesc[clm] ^= true;
        }
    }
}

Btw. hab ich es hierher verschoben. da das IMHO doch sehr wohl was mit Swing zu tun hat, denn den eigentlichen Sortieralgorithmus besprechen bzw. implementieren wir ja nicht...

Gruß Tom
 

Anhänge

  • jtablesort.jpg
    jtablesort.jpg
    8,7 KB · Aufrufe: 1.534
Zuletzt bearbeitet:
Re: DefaultTableModel

Alles klar. Aber eigentlich will ich nur das TableModel sortieren (und nicht anzeigen).
Drum vielen Dank!
 
Zurück