Multiline table header : Table Column « Swing JFC « Java






Multiline table header

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

}


 

   
    
  








Related examples in the same category

1.Combine TableModel and ColumModelCombine TableModel and ColumModel
2.JTable with a custom column modelJTable with a custom column model
3.A row header column with the TableColumnModelA row header column with the TableColumnModel
4.Install Table Column to TableColumnModelInstall Table Column to TableColumnModel
5.Swing Table Column ToolTip SampleSwing Table Column ToolTip Sample
6.Table ColumnModel and TableColumnModelListenerTable ColumnModel and TableColumnModelListener
7.Table header: Label Header with iconTable header: Label Header with icon
8.Table Headerless SampleTable Headerless Sample
9.Row Number Table Header
10.Frozen Column Table Header
11.Packing a Column of a JTable Component according to the header text
12.Packing a Column of a JTable Component according to the row data
13.Set column width based on cell renderer
14.Set table column auto-resize off
15.Get the columns from TableColumnModel in the order that they appear in the view
16.Get column count
17.Returns the TableColumn associated with the specified column index in the model
18.Setting the Width of a Column in a JTable Component
19.Disable auto resizing, Set the first visible column to 100 pixels wide
20.Setting the Column Resize Mode of a JTable Component: Disable auto resizing
21.When the width of a column is changed, the width of the right-most column is changed
22.When the width of a column is changed, all columns to the right are resized
23.When the width of a column is changed, only the columns to the left and right of the margin change
24.When the width of a column is changed, the widths of all columns are changed
25.Locking the Width of a Column in a JTable Component
26.This program demonstrates how to work with rows and columns in a table.