Mega Code Archive

 
Categories / Java / Swing Components
 

Sortable Table Example

// Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; import java.util.Hashtable; import java.util.Locale; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; /**  * @version 1.0 02/25/99  */ public class SortableTableExample extends JPanel {   public SortableTableExample() {     setLayout(new BorderLayout());     String[] headerStr = { "Name", "Date", "Size", "Dir" };     int[] columnWidth = { 100, 150, 100, 50 };     SortableTableModel dm = new SortableTableModel() {       public Class getColumnClass(int col) {         switch (col) {         case 0:           return String.class;         case 1:           return Date.class;         case 2:           return Integer.class;         case 3:           return Boolean.class;         default:           return Object.class;         }       }       public boolean isCellEditable(int row, int col) {         switch (col) {         case 1:           return false;         default:           return true;         }       }       public void setValueAt(Object obj, int row, int col) {         switch (col) {         case 2:           super.setValueAt(new Integer(obj.toString()), row, col);           return;         default:           super.setValueAt(obj, row, col);           return;         }       }     };     dm         .setDataVector(             new Object[][] {                 { "b", getDate("98/12/02"), new Integer(14),                     new Boolean(false) },                 { "a", getDate("99/01/01"), new Integer(67),                     new Boolean(false) },                 { "d", getDate("99/02/11"), new Integer(2),                     new Boolean(false) },                 { "c", getDate("99/02/27"), new Integer(7),                     new Boolean(false) },                 { "foo", new Date(), new Integer(5),                     new Boolean(true) },                 { "bar", new Date(), new Integer(10),                     new Boolean(true) } }, headerStr);     JTable table = new JTable(dm);     //table.setShowGrid(false);     table.setShowVerticalLines(true);     table.setShowHorizontalLines(false);     SortButtonRenderer renderer = new SortButtonRenderer();     TableColumnModel model = table.getColumnModel();     int n = headerStr.length;     for (int i = 0; i < n; i++) {       model.getColumn(i).setHeaderRenderer(renderer);       model.getColumn(i).setPreferredWidth(columnWidth[i]);     }     JTableHeader header = table.getTableHeader();     header.addMouseListener(new HeaderListener(header, renderer));     JScrollPane pane = new JScrollPane(table);     add(pane, BorderLayout.CENTER);   }   public static void main(String[] args) {     JFrame f = new JFrame("SortableTable Example");     f.getContentPane().add(new SortableTableExample(), BorderLayout.CENTER);     f.setSize(400, 160);     f.setVisible(true);     f.addWindowListener(new WindowAdapter() {       public void windowClosing(WindowEvent e) {         System.exit(0);       }     });   }   private static DateFormat dateFormat = DateFormat.getDateInstance(       DateFormat.SHORT, Locale.JAPAN);   private static Date getDate(String dateString) {     Date date = null;     try {       date = dateFormat.parse(dateString);     } catch (ParseException ex) {       date = new Date();     }     return date;   }   class HeaderListener extends MouseAdapter {     JTableHeader header;     SortButtonRenderer renderer;     HeaderListener(JTableHeader header, SortButtonRenderer renderer) {       this.header = header;       this.renderer = renderer;     }     public void mousePressed(MouseEvent e) {       int col = header.columnAtPoint(e.getPoint());       int sortCol = header.getTable().convertColumnIndexToModel(col);       renderer.setPressedColumn(col);       renderer.setSelectedColumn(col);       header.repaint();       if (header.getTable().isEditing()) {         header.getTable().getCellEditor().stopCellEditing();       }       boolean isAscent;       if (SortButtonRenderer.DOWN == renderer.getState(col)) {         isAscent = true;       } else {         isAscent = false;       }       ((SortableTableModel) header.getTable().getModel()).sortByColumn(           sortCol, isAscent);     }     public void mouseReleased(MouseEvent e) {       int col = header.columnAtPoint(e.getPoint());       renderer.setPressedColumn(-1); // clear       header.repaint();     }   } } class SortableTableModel extends DefaultTableModel {   int[] indexes;   TableSorter sorter;   public SortableTableModel() {   }   public Object getValueAt(int row, int col) {     int rowIndex = row;     if (indexes != null) {       rowIndex = indexes[row];     }     return super.getValueAt(rowIndex, col);   }   public void setValueAt(Object value, int row, int col) {     int rowIndex = row;     if (indexes != null) {       rowIndex = indexes[row];     }     super.setValueAt(value, rowIndex, col);   }   public void sortByColumn(int column, boolean isAscent) {     if (sorter == null) {       sorter = new TableSorter(this);     }     sorter.sort(column, isAscent);     fireTableDataChanged();   }   public int[] getIndexes() {     int n = getRowCount();     if (indexes != null) {       if (indexes.length == n) {         return indexes;       }     }     indexes = new int[n];     for (int i = 0; i < n; i++) {       indexes[i] = i;     }     return indexes;   } } class TableSorter {   SortableTableModel model;   public TableSorter(SortableTableModel model) {     this.model = model;   }   //n2 selection   public void sort(int column, boolean isAscent) {     int n = model.getRowCount();     int[] indexes = model.getIndexes();     for (int i = 0; i < n - 1; i++) {       int k = i;       for (int j = i + 1; j < n; j++) {         if (isAscent) {           if (compare(column, j, k) < 0) {             k = j;           }         } else {           if (compare(column, j, k) > 0) {             k = j;           }         }       }       int tmp = indexes[i];       indexes[i] = indexes[k];       indexes[k] = tmp;     }   }   // comparaters   public int compare(int column, int row1, int row2) {     Object o1 = model.getValueAt(row1, column);     Object o2 = model.getValueAt(row2, column);     if (o1 == null && o2 == null) {       return 0;     } else if (o1 == null) {       return -1;     } else if (o2 == null) {       return 1;     } else {       Class type = model.getColumnClass(column);       if (type.getSuperclass() == Number.class) {         return compare((Number) o1, (Number) o2);       } else if (type == String.class) {         return ((String) o1).compareTo((String) o2);       } else if (type == Date.class) {         return compare((Date) o1, (Date) o2);       } else if (type == Boolean.class) {         return compare((Boolean) o1, (Boolean) o2);       } else {         return ((String) o1).compareTo((String) o2);       }     }   }   public int compare(Number o1, Number o2) {     double n1 = o1.doubleValue();     double n2 = o2.doubleValue();     if (n1 < n2) {       return -1;     } else if (n1 > n2) {       return 1;     } else {       return 0;     }   }   public int compare(Date o1, Date o2) {     long n1 = o1.getTime();     long n2 = o2.getTime();     if (n1 < n2) {       return -1;     } else if (n1 > n2) {       return 1;     } else {       return 0;     }   }   public int compare(Boolean o1, Boolean o2) {     boolean b1 = o1.booleanValue();     boolean b2 = o2.booleanValue();     if (b1 == b2) {       return 0;     } else if (b1) {       return 1;     } else {       return -1;     }   } } class SortButtonRenderer extends JButton implements TableCellRenderer {   public static final int NONE = 0;   public static final int DOWN = 1;   public static final int UP = 2;   int pushedColumn;   Hashtable state;   JButton downButton, upButton;   public SortButtonRenderer() {     pushedColumn = -1;     state = new Hashtable();     setMargin(new Insets(0, 0, 0, 0));     setHorizontalTextPosition(LEFT);     setIcon(new BlankIcon());     // perplexed     // ArrowIcon(SwingConstants.SOUTH, true)     // BevelArrowIcon (int direction, boolean isRaisedView, boolean     // isPressedView)     downButton = new JButton();     downButton.setMargin(new Insets(0, 0, 0, 0));     downButton.setHorizontalTextPosition(LEFT);     downButton         .setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));     downButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN,         false, true));     upButton = new JButton();     upButton.setMargin(new Insets(0, 0, 0, 0));     upButton.setHorizontalTextPosition(LEFT);     upButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));     upButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.UP, false,         true));   }   public Component getTableCellRendererComponent(JTable table, Object value,       boolean isSelected, boolean hasFocus, int row, int column) {     JButton button = this;     Object obj = state.get(new Integer(column));     if (obj != null) {       if (((Integer) obj).intValue() == DOWN) {         button = downButton;       } else {         button = upButton;       }     }     button.setText((value == null) ? "" : value.toString());     boolean isPressed = (column == pushedColumn);     button.getModel().setPressed(isPressed);     button.getModel().setArmed(isPressed);     return button;   }   public void setPressedColumn(int col) {     pushedColumn = col;   }   public void setSelectedColumn(int col) {     if (col < 0)       return;     Integer value = null;     Object obj = state.get(new Integer(col));     if (obj == null) {       value = new Integer(DOWN);     } else {       if (((Integer) obj).intValue() == DOWN) {         value = new Integer(UP);       } else {         value = new Integer(DOWN);       }     }     state.clear();     state.put(new Integer(col), value);   }   public int getState(int col) {     int retValue;     Object obj = state.get(new Integer(col));     if (obj == null) {       retValue = NONE;     } else {       if (((Integer) obj).intValue() == DOWN) {         retValue = DOWN;       } else {         retValue = UP;       }     }     return retValue;   } } class BevelArrowIcon implements Icon {   public static final int UP = 0; // direction   public static final int DOWN = 1;   private static final int DEFAULT_SIZE = 11;   private Color edge1;   private Color edge2;   private Color fill;   private int size;   private int direction;   public BevelArrowIcon(int direction, boolean isRaisedView,       boolean isPressedView) {     if (isRaisedView) {       if (isPressedView) {         init(UIManager.getColor("controlLtHighlight"), UIManager             .getColor("controlDkShadow"), UIManager             .getColor("controlShadow"), DEFAULT_SIZE, direction);       } else {         init(UIManager.getColor("controlHighlight"), UIManager             .getColor("controlShadow"), UIManager             .getColor("control"), DEFAULT_SIZE, direction);       }     } else {       if (isPressedView) {         init(UIManager.getColor("controlDkShadow"), UIManager             .getColor("controlLtHighlight"), UIManager             .getColor("controlShadow"), DEFAULT_SIZE, direction);       } else {         init(UIManager.getColor("controlShadow"), UIManager             .getColor("controlHighlight"), UIManager             .getColor("control"), DEFAULT_SIZE, direction);       }     }   }   public BevelArrowIcon(Color edge1, Color edge2, Color fill, int size,       int direction) {     init(edge1, edge2, fill, size, direction);   }   public void paintIcon(Component c, Graphics g, int x, int y) {     switch (direction) {     case DOWN:       drawDownArrow(g, x, y);       break;     case UP:       drawUpArrow(g, x, y);       break;     }   }   public int getIconWidth() {     return size;   }   public int getIconHeight() {     return size;   }   private void init(Color edge1, Color edge2, Color fill, int size,       int direction) {     this.edge1 = edge1;     this.edge2 = edge2;     this.fill = fill;     this.size = size;     this.direction = direction;   }   private void drawDownArrow(Graphics g, int xo, int yo) {     g.setColor(edge1);     g.drawLine(xo, yo, xo + size - 1, yo);     g.drawLine(xo, yo + 1, xo + size - 3, yo + 1);     g.setColor(edge2);     g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1);     int x = xo + 1;     int y = yo + 2;     int dx = size - 6;     while (y + 1 < yo + size) {       g.setColor(edge1);       g.drawLine(x, y, x + 1, y);       g.drawLine(x, y + 1, x + 1, y + 1);       if (0 < dx) {         g.setColor(fill);         g.drawLine(x + 2, y, x + 1 + dx, y);         g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);       }       g.setColor(edge2);       g.drawLine(x + dx + 2, y, x + dx + 3, y);       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);       x += 1;       y += 2;       dx -= 2;     }     g.setColor(edge1);     g.drawLine(xo + (size / 2), yo + size - 1, xo + (size / 2), yo + size         - 1);   }   private void drawUpArrow(Graphics g, int xo, int yo) {     g.setColor(edge1);     int x = xo + (size / 2);     g.drawLine(x, yo, x, yo);     x--;     int y = yo + 1;     int dx = 0;     while (y + 3 < yo + size) {       g.setColor(edge1);       g.drawLine(x, y, x + 1, y);       g.drawLine(x, y + 1, x + 1, y + 1);       if (0 < dx) {         g.setColor(fill);         g.drawLine(x + 2, y, x + 1 + dx, y);         g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);       }       g.setColor(edge2);       g.drawLine(x + dx + 2, y, x + dx + 3, y);       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);       x -= 1;       y += 2;       dx += 2;     }     g.setColor(edge1);     g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3);     g.setColor(edge2);     g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2);     g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1);   } } class BlankIcon implements Icon {   private Color fillColor;   private int size;   public BlankIcon() {     this(null, 11);   }   public BlankIcon(Color color, int size) {     //UIManager.getColor("control")     //UIManager.getColor("controlShadow")     fillColor = color;     this.size = size;   }   public void paintIcon(Component c, Graphics g, int x, int y) {     if (fillColor != null) {       g.setColor(fillColor);       g.drawRect(x, y, size - 1, size - 1);     }   }   public int getIconWidth() {     return size;   }   public int getIconHeight() {     return size;   } }