Mega Code Archive

 
Categories / Java / Swing JFC
 

Multiline table header

import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.text.NumberFormat; import java.util.Calendar; import java.util.EventObject; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.StringTokenizer; import java.util.TreeSet; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.EventListenerList; import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; class SortedTableModel extends AbstractTableModel {   protected TableModel sourceModel;   protected int[] indexValues;   public SortedTableModel(TableModel model) {     super();     sourceModel = model;   }   public int getRowCount() {     return sourceModel.getRowCount();   }   public int getColumnCount() {     return sourceModel.getColumnCount();   }   public Object getValueAt(int row, int column) {     if (indexValues != null) {       row = getSourceIndex(row);     }     return sourceModel.getValueAt(row, column);   }   public void setValueAt(Object value, int row, int column) {     if (indexValues != null) {       row = getSourceIndex(row);     }     sourceModel.setValueAt(value, row, column);   }   public boolean isCellEditable(int row, int column) {     return sourceModel.isCellEditable(row, column);   }   public String getColumnName(int column) {     return sourceModel.getColumnName(column);   }   public Class getColumnClass(int column) {     return sourceModel.getColumnClass(column);   }   public int getSourceIndex(int index) {     if (indexValues != null) {       return indexValues[index];     }     return -1;   }   public void sortRows(int column, boolean ascending) {     fireTableDataChanged();   }   public void clearSort() {     indexValues = null;     fireTableDataChanged();   } } class SortedColumnHeaderRenderer implements TableCellRenderer {   protected TableCellRenderer textRenderer;   protected SortedTableModel sortedModel;   protected int sortColumn = -1;   protected boolean sortAscending = true;   public SortedColumnHeaderRenderer(SortedTableModel model,       TableCellRenderer renderer) {     sortedModel = model;     textRenderer = renderer;   }   public SortedColumnHeaderRenderer(SortedTableModel model) {     this(model, null);   }   public Component getTableCellRendererComponent(JTable table, Object value,       boolean isSelected, boolean hasFocus, int row, int column) {     Component text;     JPanel panel = new JPanel();     panel.setLayout(new BorderLayout());     if (textRenderer != null) {       text = textRenderer.getTableCellRendererComponent(table, value,           isSelected, hasFocus, row, column);     } else {       text = new JLabel((String) value, JLabel.CENTER);       LookAndFeel.installColorsAndFont((JComponent) text,           "TableHeader.background", "TableHeader.foreground",           "TableHeader.font");     }     panel.add(text, BorderLayout.CENTER);     if (column == sortColumn) {       BasicArrowButton bab = new BasicArrowButton(           (sortAscending ? SwingConstants.NORTH : SwingConstants.SOUTH));       panel.add(bab, BorderLayout.WEST);     }     LookAndFeel.installBorder(panel, "TableHeader.cellBorder");     return panel;   }   public void columnSelected(int column) {     if (column != sortColumn) {       sortColumn = column;       sortAscending = true;     } else {       sortAscending = !sortAscending;       if (sortAscending)         sortColumn = -1;     }     if (sortColumn != -1) {       sortedModel.sortRows(sortColumn, sortAscending);     } else {       sortedModel.clearSort();     }   } } class TableValues extends AbstractTableModel {   public final static int FIRST_NAME = 0;   public final static int LAST_NAME = 1;   public final static int DATE_OF_BIRTH = 2;   public final static int ACCOUNT_BALANCE = 3;   public final static int GENDER = 4;   public final static boolean GENDER_MALE = true;   public final static boolean GENDER_FEMALE = false;   public final static String[] columnNames = { "First\nName", "Last\nName",       "Date of\nBirth", "Account\nBalance", "Gender" };   public Object[][] values = {       { "A", "B",           new GregorianCalendar(1962, Calendar.FEBRUARY, 20).getTime(),           new Float(12345.67), new Boolean(GENDER_MALE) },       { "C", "D",           new GregorianCalendar(1987, Calendar.JANUARY, 6).getTime(),           new Float(23456.78), new Boolean(GENDER_MALE) },       { "E", "F",           new GregorianCalendar(1989, Calendar.AUGUST, 31).getTime(),           new Float(34567.89), new Boolean(GENDER_FEMALE) },       { "G", "H",           new GregorianCalendar(1945, Calendar.JANUARY, 16).getTime(),           new Float(-456.70), new Boolean(GENDER_FEMALE) },       { "I", "J",           new GregorianCalendar(1907, Calendar.AUGUST, 2).getTime(),           new Float(567.00), new Boolean(GENDER_FEMALE) } };   public int getRowCount() {     return values.length;   }   public int getColumnCount() {     return values[0].length;   }   public Object getValueAt(int row, int column) {     return values[row][column];   }   public String getColumnName(int column) {     return columnNames[column];   }   public Class getColumnClass(int column) {     Class dataType = super.getColumnClass(column);     if (column == ACCOUNT_BALANCE) {       dataType = Float.class;     } else if (column == DATE_OF_BIRTH) {       dataType = java.util.Date.class;     } else if ((column == FIRST_NAME) || (column == LAST_NAME)) {       dataType = String.class;     } else if (column == GENDER) {       dataType = Boolean.class;     }     return dataType;   }   public boolean isCellEditable(int row, int column) {     if (column == GENDER) {       return true;     }     return false;   }   public void setValueAt(Object value, int row, int column) {     values[row][column] = value;   } } public class SimpleTableTestMultilineHeader extends JFrame {   protected JTable table;   protected SortedColumnHeaderRenderer renderer;   public static void main(String[] args) {     SimpleTableTestMultilineHeader stt = new SimpleTableTestMultilineHeader();     stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     stt.setSize(400, 200);     stt.setVisible(true);   }   public SimpleTableTestMultilineHeader() {     Container pane = getContentPane();     pane.setLayout(new BorderLayout());     TableValues tv = new TableValues();     SortedTableModel stm = new SortedTableModel(tv);     stm.sortRows(TableValues.ACCOUNT_BALANCE, true);     table = new JTable(stm);     table.setRowSelectionAllowed(false);     table.setColumnSelectionAllowed(true);     TableColumnModel tcm = table.getColumnModel();     TableColumn tc = tcm.getColumn(TableValues.GENDER);     MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();     tc = tcm.getColumn(TableValues.ACCOUNT_BALANCE);     tc.setHeaderRenderer(mlhr);     renderer = new SortedColumnHeaderRenderer(stm, mlhr);     int count = tcm.getColumnCount();     for (int i = 0; i < count; i++) {       tc = tcm.getColumn(i);       tc.setHeaderRenderer(renderer);     }     JTableHeaderToolTips jthtt = new JTableHeaderToolTips(table         .getColumnModel());     jthtt.setToolTips(new String[] { "Customer's First Name",         "Customer's Last Name", "Customer's Date of Birth",         "Customer's Account Balance", "Customer's Gender" });     table.setTableHeader(jthtt);     JScrollPane jsp = new JScrollPane(table);     pane.add(jsp, BorderLayout.CENTER);     addHeaderListener();   }   public void addHeaderListener() {     table.getTableHeader().addMouseListener(new MouseAdapter() {       public void mousePressed(MouseEvent event) {         JTableHeader header = (JTableHeader) (event.getSource());         int index = header.columnAtPoint(event.getPoint());         Class dataType = table.getModel().getColumnClass(index);         Class[] interfaces = dataType.getInterfaces();         for (int i = 0; i < interfaces.length; i++) {           if (interfaces[i].equals(java.lang.Comparable.class)) {             renderer.columnSelected(index);             break;           }         }         table.setColumnSelectionInterval(index, index);       }     });   } } class JTableHeaderToolTips extends JTableHeader {   protected String[] toolTips;   public JTableHeaderToolTips(TableColumnModel tcm) {     super(tcm);   }   public void setToolTips(String[] tips) {     toolTips = tips;   }   public String getToolTipText(MouseEvent event) {     String tip = super.getToolTipText(event);     int column = columnAtPoint(event.getPoint());     if ((toolTips != null) && (column < toolTips.length)         && (toolTips[column] != null)) {       tip = toolTips[column];     }     return tip;   } } class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {   public Component getTableCellRendererComponent(JTable table, Object value,       boolean isSelected, boolean hasFocus, int row, int column) {     JLabel label;     removeAll();     String[] header = ((String) value).split("\n");     setLayout(new GridLayout(header.length, 1));     for(String s: header){       label = new JLabel(s, JLabel.CENTER);       LookAndFeel.installColorsAndFont(label, "TableHeader.background",           "TableHeader.foreground", "TableHeader.font");       add(label);     }     LookAndFeel.installBorder(this, "TableHeader.cellBorder");     return this;   } }