DefaultTableModel / JTable sortieren

Hallo!

Schau mal hier:
Java:
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.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
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 javax.swing.table.TableCellRenderer;

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

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

    private JTable table;

    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);

        table = new JTable(new SortableTableModel(
                createRowData(),
                createColumnHeaderNames(),
                createColumnComparators()));

        table.getTableHeader().setDefaultRenderer(createTableHeaderRenderer());

        table.getTableHeader().addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                int columnIndex = table.columnAtPoint(evt.getPoint());
                ((SortableTableModel) table.getModel()).sortByColumn(table
                        .getColumnName(columnIndex));
            }
        });

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

        pack();
        setVisible(true);
    }

    private TableCellRenderer createTableHeaderRenderer() {
        return 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);

                SortableTableModel sortableTableModel = (SortableTableModel) table
                        .getModel();
                if (sortableTableModel.sortColumnDesc[sortableTableModel
                        .getOriginalIndexFor(table.getColumnName(column))]) {
                    setIcon(UP_ICON);
                } else {
                    setIcon(DOWN_ICON);
                }
                return this;
            }
        };
    }

    private Comparator[] createColumnComparators() {
        return new Comparator[] { SortableTableModel.STRING_COMPARATOR,
                SortableTableModel.STRING_COMPARATOR,
                SortableTableModel.NUMBER_COMPARATOR };
    }

    private String[] createColumnHeaderNames() {
        return new String[] { "Header1", "Header2", "Header3" };
    }

    private Object[][] createRowData() {
        return new Object[][] { { "a", "c", 17 }, { "b", "b", 4 },
                { "f", "r", -393.2 }, { "q", "a", 44 },
                { "w", "z", 222222222 }, { "c", "a", 111 } };
    }

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

    static class SortableTableModel extends DefaultTableModel {

        private boolean[] sortColumnDesc;
        
        private Map<String, Comparator<?>> columnNameToComparatorMap = new HashMap<String, Comparator<?>>();

        private Map<String, Integer> originalColumnNameToIndexMap = new HashMap<String, Integer>();

        public static final Comparator<String> STRING_COMPARATOR = String.CASE_INSENSITIVE_ORDER;

        public static final Comparator<Number> NUMBER_COMPARATOR = new Comparator<Number>() {
            public int compare(Number o1, Number o2) {
                return Double.valueOf(o1.toString()).compareTo(
                        Double.valueOf(o2.toString()));
            }
        };

        private final RowComparator rowComparator = new RowComparator();

        public SortableTableModel(Object[][] rowData, String[] headers,
                Comparator<?>[] comparators) {
            super(rowData, headers);
            sortColumnDesc = new boolean[headers.length];
            for (int i = 0; i < headers.length; i++) {
                columnNameToComparatorMap.put(headers[i], comparators[i]);
                originalColumnNameToIndexMap
                        .put(headers[i], Integer.valueOf(i));
            }
        }
    
        public int getOriginalIndexFor(String columnName) {
            return originalColumnNameToIndexMap.get(columnName);
        }

        @SuppressWarnings("unchecked")
        public void sortByColumn(final String columnName) {
            rowComparator.setDelegatingComparator(columnNameToComparatorMap
                    .get(columnName));
            int columnIndex = originalColumnNameToIndexMap.get(columnName);
            rowComparator.setCurrentColumn(columnIndex);
            rowComparator.setSortDescending(sortColumnDesc[columnIndex]);
            Collections.sort(this.dataVector, rowComparator);
            sortColumnDesc[columnIndex] ^= true;
        }
    }

    static class RowComparator implements Comparator<Object> {
        int currentColumn;

        boolean sortDescending;

        Comparator<?> delegatingComparator;

        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            Vector v1 = (Vector) o1;
            Vector v2 = (Vector) o2;
            int cmp = getDelegatingComparator().compare(
                    v1.get(getCurrentColumn()),
                    v2.get(getCurrentColumn()));
            if (isSortDescending()) {
                cmp *= -1;
            }
            return cmp;
        }

        /**
         * @return the currentColumn
         */
        public int getCurrentColumn() {
            return currentColumn;
        }

        /**
         * @param currentColumn
         *            the currentColumn to set
         */
        public void setCurrentColumn(int currentColumn) {
            this.currentColumn = currentColumn;
        }

        /**
         * @return the sortDescending
         */
        public boolean isSortDescending() {
            return sortDescending;
        }

        /**
         * @param sortDescending
         *            the sortDescending to set
         */
        public void setSortDescending(boolean sortDescending) {
            this.sortDescending = sortDescending;
        }

        /**
         * @return the comparator
         */
        public Comparator getDelegatingComparator() {
            return delegatingComparator;
        }

        /**
         * @param comparator
         *            the comparator to set
         */
        public void setDelegatingComparator(Comparator comparator) {
            this.delegatingComparator = comparator;
        }
    }
}

Gruß Tom
 
Um da durchzusteigen reichen meine Java Kentnisse leider noch nicht aus....aber trotzdem Danke!!
Gibt es vielleicht die möglichkeit im Beispiel von Seite 1 einen zweiten Comperator einzubauen der int werte vergleicht und beim Klicken auf die Spaltenüberschrift unterscheidet er welchen Comperator er benutzt? Wär echt nett wenn das mal jemand einbinden könnte...hab keine Idee wie ich das anstellen soll.
 
Hey Thomas, ich hab versucht mit deiner Klasse hinzubekommen, daß meine Spalten in der Tabelle sortiert werden. Aber das funktioniert nicht :( Kannst du mir helfen?

Code:
package gui;

import java.awt.Component;
import java.awt.GridLayout;
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.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;

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

/**
 * @author Nina 
 * @version 1.0
 * 
 */
public class PanelStandorte extends JPanel {

	private MyTableModel model;

	// private String[][] rowData = new String[50][50];
	private String[][] rowData = { { "a", "c" }, { "b", "b" }, { "f", "r" },
			{ "q", "a" }, { "w", "z" }, { "c", "a" } };

	private String[] columnHeaders = { "Standort", "Status" };

	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"));

	/**
	 * Konstruktor.
	 */
	public PanelStandorte() {

		final MyTableModel model = new MyTableModel(rowData, columnHeaders);

		final JTable table = new JTable(model);

		setLayout(new GridLayout());
		TitledBorder tb = new TitledBorder("Standorte");

		JScrollPane scroll = new JScrollPane(table,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		table.setEnabled(false);
		setBorder(tb);
		add(scroll);

		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()));
			}
		});

		setVisible(true);
	}// Konstruktor Ende

	/**
	 * Klasse des TableModels.
	 * 
	 * @author Nina 
	 * @version
	 */
	class MyTableModel extends DefaultTableModel {

		private boolean[] sortColumnDesc;

		/**
		 * Konstruktor der Klasse MyTableModel.
		 * 
		 * @param rowData
		 * @param headers
		 */
		public MyTableModel(Object[][] rowData, Object[] headers) {
			super(rowData, headers);
			sortColumnDesc = new boolean[headers.length];
		}

		/**
		 * Methode um nach Spalten zu sortieren.
		 * 
		 * @param clm
		 */
		public void sortByColumn(final int clm) {
			Collections.sort(this.dataVector, new Comparator() {

				/**
				 * @param o1
				 * @param o2
				 * @return
				 */
				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;
		}
	}
}
 
steige doch so langsam durch den quelltext durch...

eine sache noch...unterscheidet der comperator je nach zelleninhalt ob er den Int oder String Comperator nehmen soll oder ist jeder Zeile fest ein Comperator zugewiesen?

Weil wenn ich die daten dynamisch aus einer Datenbank hole dann müsste er ja jedesmal den Datentyp erkennen und entsprechend den Comperator wählen...ist das möglich?
 
Hallo Zusammen,

tut mir leid, wenn ich einen alten Thread wieder ausgrabe, aber ich wollt keinen Neuen erstellen, da es vom Thema her gut passt.

Ich habe ein eigenes TableModel, welches als Datenbasis eine Multirow Bean besitzt (Liste aus HashMaps).

Das Sortieren funktioniert korrekt.
Komischerweise muss ich in der sortByColumn() Methode explizit fireTableDataChanged(); aufrufen, da sich die Table sonst erst beim Scrollen aktuallisiert.

Mein Problem ist nun folgendes, ich hab für die TableHeader einen Renderer programmiert (im Grunde derselbe wie hier im Thread.)

Nun ändern sich die Symbole allerdings nicht, wenn ich auf die TableHeaders klicke, sondern erst, wenn ich den Mauszeiger wieder von der Spaltenüberschrift wegbewege.


Bin für jede Hilfe bzw jeden Tip dankbar.

Gruß
Tom

TableModel
Code:
package swing.base;

import javax.swing.table.AbstractTableModel;
import java.util.HashMap;
import org.apache.log4j.Logger;
import java.util.Collections;
import java.util.Comparator;
import javax.swing.event.TableModelEvent;
import java.util.Map;

public class BaseTableModel extends AbstractTableModel
{
  protected static Logger log = Utilities.getLogger(BaseTableModel.class);

  private boolean DEBUG = true;

  public Object[] longValues =
     {};
  private String[] columnNames =
     {};
  private String[] parameterNames =
     {};
  public boolean[] sortColumnDesc;

  protected BaseBean _bean = null;

  public BaseTableModel(BaseBean data)
  {
    _bean = data;
    fireTableStructureChanged();
  }

  public void setLongValues(Object[] lv)
  {
    longValues = lv;
  }

  public String[] getParameterNames()
  {
    return parameterNames;
  }

  public void setParameterNames(String[] cn)
  {
    parameterNames = cn;
    sortColumnDesc = new boolean[parameterNames.length];
  }

  public String[] getColumnNames()
  {
    return columnNames;
  }

  public void setColumnNames(String[] cn)
  {
    columnNames = cn;
    fireTableStructureChanged();
  }


  public int getColumnCount()
  {
    return columnNames.length;
  }

  public int getRowCount()
  {
    return _bean.size();
  }

  public String getColumnName(int col)
  {
    return columnNames[col];
  }

  public Class getColumnClass(int col)
  {
    return getValueAt(0, col).getClass();
  }

  public boolean isCellEditable(int row, int col)
  {
    if(col < 1)
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  public Object getValueAt(int row, int col)
  {
    if(this.parameterNames == null)
      throw new RuntimeException("Display Properties not set!");
  
    HashMap m = null;

    log.debug("[start] BaseTableModel.getValueAt - row=" + row + ", column=" +  col);
    _bean.gotoRow(row);
    
    m = (HashMap)_bean.returnMap();

    Object value = null;
    try
    {
      value = m.get(parameterNames[col]);
   }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    log.debug("[end] BaseTableModel.getValueAt - value=" + value);
    return value;
  }

  public void setValueAt(Object value, int row, int col)
  {
    if(this.parameterNames == null)
      throw new RuntimeException("Display Properties not set!");

    HashMap m = null;

    _bean.gotoRow(row);
    m = (HashMap)_bean.returnMap();
    
    try
    {
      m.put(parameterNames[col], value);
   }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }

    fireTableCellUpdated(row, col);
  }

  public void sortByColumn(final String columnName)
  {
    Comparator comparator = new BaseBeanPropertyComparator(columnName);
    int columnIndex = 0;

    for(int i = 0; i < parameterNames.length; i++)
    {
      if(parameterNames[i].equals(columnName))
      {
        columnIndex = i;
        break;
      }
    }

    ((BaseBeanPropertyComparator)comparator).setSortDescending(sortColumnDesc[columnIndex]);

    Collections.sort(_bean.getResList(),comparator);

    sortColumnDesc[columnIndex] ^= true;

    this.fireTableDataChanged();

  }
}


TableCellRenderer
Code:
package swing.base;

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import com.sun.java.swing.plaf.motif.MotifGraphicsUtils;

public class HeaderSortTableCellRenderer
   extends DefaultTableCellRenderer
{
  private final ImageIcon UP_ICON = new ImageIcon(MotifGraphicsUtils.class
                                                  .getResource("../../icons/asc.gif"));
  private final ImageIcon DOWN_ICON = new ImageIcon(MotifGraphicsUtils.class
                                              .getResource("../../icons/desc.gif"));

  public HeaderSortTableCellRenderer()
  {
    super();
  }

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

    Component comp = (Component)super.getTableCellRendererComponent(table,
       value, isSelected, hasFocus, row, column);

    JTableHeader header = table.getTableHeader();

    this.setForeground(header.getForeground());
    this.setBackground(header.getBackground());
    this.setFont(header.getFont());
    this.setText(value == null ? "" : value.toString());
    this.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    this.setHorizontalAlignment(SwingConstants.CENTER);
    this.setHorizontalTextPosition(SwingConstants.LEFT);

    DKSExportTableModel model = (DKSExportTableModel) table.getModel();

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


Frame
Code:
package swing.base;

import java.io.*;
import java.util.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

import com.borland.dbswing.*;
import com.borland.jbcl.layout.*;
import com.sun.java.swing.plaf.motif.*;

public class TableFrame
   extends JFrame
{
  JPanel contentPane;

  XYLayout xYLayout1 = new XYLayout();

  DKSExportTableModel model;
    
  TableScrollPane tableScrollPane = new TableScrollPane();
  
  JTable table = new JTable();
  
  private DKSExportBean bean = null;
 

  public TableFrame()
  {
    try
    {
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      init();
      retrieveTableData();
    }
    catch(Exception exception)
    {
      exception.printStackTrace();
    }
  }

  private void init()
     throws Exception
  {
    contentPane = (JPanel) getContentPane();
    contentPane.setLayout(xYLayout1);

    setSize(new Dimension(685, 500));
 
    table.getTableHeader().setReorderingAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    table.setRowSelectionAllowed(true);

    tableScrollPane.setAutoscrolls(true);
    tableScrollPane.setBorder(BorderFactory.createLineBorder(Color.black));
    tableScrollPane.getViewport().add(table);

    contentPane.add(tableScrollPane, new XYConstraints(3, 60, 670, 110));
   
    addTableRenderer();
    addTableListener();    
  }

  private void retrieveTableData()
  {
    bean = new DKSExportBean();
    
    try
    {
      bean.populateAll("CurrentDataSelect");
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }

    model = new DKSExportTableModel(bean);
    table.setModel(model);  
  }

  private void addTableRenderer()
  {        
    HeaderSortTableCellRenderer hstcr = new HeaderSortTableCellRenderer();
    table.getTableHeader().setDefaultRenderer(hstcr);
  }

  private void addTableListener()
  {   
    table.getTableHeader().addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent evt)
      {
        model.sortByColumn(model.getParameterNames()[table.columnAtPoint(evt.getPoint())]);
      }
    });
  }

Das im Frame verwendete TableModel ist nur eine Ableitung vom BaseTableModel
Code:
package swing.base;

public class DKSExportTableModel
   extends BaseTableModel
{

  public DKSExportTableModel(DKSExportBean data)
  {
    super(data);

    this.setColumnNames(new String[]
                        {"Jahr", "Monat", "Name", "PNR", "Typ",
                        "Betrag DM", "Betrag EUR", "Status"});

    this.setParameterNames(new String[]
                           {"year", "month", "fullname", "pnr", "type",
                           "amount_dm", "amount_eur", "status"});

  }

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


UPDATE:
--------------------------

Problem gefunden, Schuld an der ganzen Sache ist folgendes:

table.getTableHeader().setReorderingAllowed(false);


Um die Funktionalität (Renderer, Sortieren) dennoch zu behalten, aber das Reordering der Spalten zu verbieten, hab ich folgende Lösung gefunden.

Code:
table.getTableHeader().addMouseMotionListener(new MouseMotionAdapter()
{
      public void mouseDragged(MouseEvent evt)
      {
          table.getTableHeader().setDraggedColumn(null);
       }
});
Ist wohl eine ziemliche Quick&Dirty Lösung, aber funktioniert einwandfrei.
 
Zuletzt bearbeitet:
Hallo!

Schau mal hier:
Java:
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.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
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 javax.swing.table.TableCellRenderer;

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

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

    private JTable table;

    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);

        table = new JTable(new SortableTableModel(
                createRowData(),
                createColumnHeaderNames(),
                createColumnComparators()));

        table.getTableHeader().setDefaultRenderer(createTableHeaderRenderer());

        table.getTableHeader().addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                int columnIndex = table.columnAtPoint(evt.getPoint());
                ((SortableTableModel) table.getModel()).sortByColumn(table
                        .getColumnName(columnIndex));
            }
        });

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

        pack();
        setVisible(true);
    }

    private TableCellRenderer createTableHeaderRenderer() {
        return 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);

                SortableTableModel sortableTableModel = (SortableTableModel) table
                        .getModel();
                if (sortableTableModel.sortColumnDesc[sortableTableModel
                        .getOriginalIndexFor(table.getColumnName(column))]) {
                    setIcon(UP_ICON);
                } else {
                    setIcon(DOWN_ICON);
                }
                return this;
            }
        };
    }

    private Comparator[] createColumnComparators() {
        return new Comparator[] { SortableTableModel.STRING_COMPARATOR,
                SortableTableModel.STRING_COMPARATOR,
                SortableTableModel.NUMBER_COMPARATOR };
    }

    private String[] createColumnHeaderNames() {
        return new String[] { "Header1", "Header2", "Header3" };
    }

    private Object[][] createRowData() {
        return new Object[][] { { "a", "c", 17 }, { "b", "b", 4 },
                { "f", "r", -393.2 }, { "q", "a", 44 },
                { "w", "z", 222222222 }, { "c", "a", 111 } };
    }

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

    static class SortableTableModel extends DefaultTableModel {

        private boolean[] sortColumnDesc;
        
        private Map<String, Comparator<?>> columnNameToComparatorMap = new HashMap<String, Comparator<?>>();

        private Map<String, Integer> originalColumnNameToIndexMap = new HashMap<String, Integer>();

        public static final Comparator<String> STRING_COMPARATOR = String.CASE_INSENSITIVE_ORDER;

        public static final Comparator<Number> NUMBER_COMPARATOR = new Comparator<Number>() {
            public int compare(Number o1, Number o2) {
                return Double.valueOf(o1.toString()).compareTo(
                        Double.valueOf(o2.toString()));
            }
        };

        private final RowComparator rowComparator = new RowComparator();

        public SortableTableModel(Object[][] rowData, String[] headers,
                Comparator<?>[] comparators) {
            super(rowData, headers);
            sortColumnDesc = new boolean[headers.length];
            for (int i = 0; i < headers.length; i++) {
                columnNameToComparatorMap.put(headers[i], comparators[i]);
                originalColumnNameToIndexMap
                        .put(headers[i], Integer.valueOf(i));
            }
        }
    
        public int getOriginalIndexFor(String columnName) {
            return originalColumnNameToIndexMap.get(columnName);
        }

        @SuppressWarnings("unchecked")
        public void sortByColumn(final String columnName) {
            rowComparator.setDelegatingComparator(columnNameToComparatorMap
                    .get(columnName));
            int columnIndex = originalColumnNameToIndexMap.get(columnName);
            rowComparator.setCurrentColumn(columnIndex);
            rowComparator.setSortDescending(sortColumnDesc[columnIndex]);
            Collections.sort(this.dataVector, rowComparator);
            sortColumnDesc[columnIndex] ^= true;
        }
    }

    static class RowComparator implements Comparator<Object> {
        int currentColumn;

        boolean sortDescending;

        Comparator<?> delegatingComparator;

        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            Vector v1 = (Vector) o1;
            Vector v2 = (Vector) o2;
            int cmp = getDelegatingComparator().compare(
                    v1.get(getCurrentColumn()),
                    v2.get(getCurrentColumn()));
            if (isSortDescending()) {
                cmp *= -1;
            }
            return cmp;
        }

        /**
         * @return the currentColumn
         */
        public int getCurrentColumn() {
            return currentColumn;
        }

        /**
         * @param currentColumn
         *            the currentColumn to set
         */
        public void setCurrentColumn(int currentColumn) {
            this.currentColumn = currentColumn;
        }

        /**
         * @return the sortDescending
         */
        public boolean isSortDescending() {
            return sortDescending;
        }

        /**
         * @param sortDescending
         *            the sortDescending to set
         */
        public void setSortDescending(boolean sortDescending) {
            this.sortDescending = sortDescending;
        }

        /**
         * @return the comparator
         */
        public Comparator getDelegatingComparator() {
            return delegatingComparator;
        }

        /**
         * @param comparator
         *            the comparator to set
         */
        public void setDelegatingComparator(Comparator comparator) {
            this.delegatingComparator = comparator;
        }
    }
}

Gruß Tom
Hallo Thomas,

gibt es auch für Java 1.4 eine Lösung (Sortieren bei verschobener Spalte)?

Die von dir gezeigte bezieht sich leider nur auf Java 1.5+> - ich bin aber an Version 1.4 gebunden.

Grüße,
Christian
 
huhu zusammen, ich weiss dass dieser Thread schon "etwas" älter ist... Aber woanders finde ich nichts was mit MotifGraphicsUtils zu tun hat. In einem Applet benutze ich die Left und Right Arrows aus dem Paket: com.sun.java.swing.plaf.motif.MotifGraphicsUtils
Genauso wie es Tom in seinem Code gemacht hat, nur wenn ich das Applet im Browser (Firefox) aufrufe, dann bekomme ich anstatt der beiden Icons eine NullPointerException. Wenn ich die Arrows aus dem Code nehme, dann funktioniert es einwandfrei (nur ohne Pfeile), sowie auch unter eclipse funktioniert es mit den Pfeilen, nur im Browser nicht.... Weiss jemand woran das liegen könnte

glg
jal1976
 
Zuletzt bearbeitet:
Zurück