Tabbable Currency Table : Grid Table « Swing Components « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » Swing Components » Grid TableScreenshots 
Tabbable Currency Table
Tabbable Currency Table

/*
Core SWING Advanced Programming 
By Kim Topley
ISBN: 0 13 083292 8       
Publisher: Prentice Hall  
*/



import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.CellEditor;
import javax.swing.FocusManager;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
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;

public class TabbableCurrencyTable {
  public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    catch (Exception evt) {}
  
    JFrame f = new JFrame("Tabbable Currency Table");

    TabEditTable tbl = new TabEditTable(
        new TestUpdatableCurrencyTableModel());
    tbl.setDefaultRenderer(java.lang.Number.class,
        new FractionCellRenderer(103, SwingConstants.RIGHT));

    TableColumnModel tcm = tbl.getColumnModel();
    tcm.getColumn(0).setPreferredWidth(150);
    tcm.getColumn(0).setMinWidth(150);
    TextWithIconCellRenderer renderer = new TextWithIconCellRenderer();
    tcm.getColumn(0).setCellRenderer(renderer);
    tbl.setShowHorizontalLines(false);
    tbl.setIntercellSpacing(new Dimension(10));

    // Add the stripe renderer in the leftmost four columns.
    StripedTableCellRenderer.installInColumn(tbl, 0, Color.lightGray,
        Color.white, null, null);
    StripedTableCellRenderer.installInColumn(tbl, 1, Color.lightGray,
        Color.white, null, null);
    StripedTableCellRenderer.installInColumn(tbl, 2, Color.lightGray,
        Color.white, null, null);
    StripedTableCellRenderer.installInColumn(tbl, 3, Color.lightGray,
        Color.white, null, null);

    // Add the highlight renderer to the difference column.
    // The following comparator makes it highlight
    // cells with negative numeric values.
    Comparator cmp = new Comparator() {
      public boolean shouldHighlight(JTable tbl, Object value, int row,
          int column) {
        if (value instanceof Number) {
          double columnValue = ((Numbervalue).doubleValue();
          return columnValue < (double0.0;
        }
        return false;
      }
    };
    tcm.getColumn(3).setCellRenderer(
        new HighlightRenderer(cmp, null, Color.pink, Color.black,
            Color.pink.darker(), Color.white));

    // Install a button renderer in the last column
    ButtonRenderer buttonRenderer = new ButtonRenderer();
    buttonRenderer.setForeground(Color.blue);
    buttonRenderer.setBackground(Color.lightGray);
    tcm.getColumn(4).setCellRenderer(buttonRenderer);

    // Install a button editor in the last column
    TableCellEditor editor = new ButtonEditor(new JButton());
    tcm.getColumn(4).setCellEditor(editor);

    // Install the list of columns containing tabbable editors
    tbl.setEditingColumns(new int[] { 1});

    // Make the rows wide enough to take the buttons
    tbl.setRowHeight(20);

    tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize());

    JScrollPane sp = new JScrollPane(tbl);
    f.getContentPane().add(sp, "Center");
    f.pack();
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) {
        System.exit(0);
      }
    });
    f.setVisible(true);
  }
}

class TabEditTable extends JTable {
  public TabEditTable() {
    super();
  }

  public TabEditTable(TableModel dm) {
    super(dm);
  }

  public TabEditTable(TableModel dm, TableColumnModel cm) {
    super(dm, cm);
  }

  public TabEditTable(TableModel dm, TableColumnModel cm,
      ListSelectionModel sm) {
    super(dm, cm, sm);
  }

  public TabEditTable(int numRows, int numColumns) {
    super(numRows, numColumns);
  }

  public TabEditTable(final Vector rowData, final Vector columnNames) {
    super(rowData, columnNames);
  }

  public TabEditTable(final Object[][] rowData, final Object[] columnNames) {
    super(rowData, columnNames);
  }

  // Set the columns that contain tabbable editors
  public void setEditingColumns(int[] columns) {
    editingColumns = columns;
    convertEditableColumnsToView();
  }

  public int[] getEditingColumns() {
    return editingColumns;
  }

  // Overrides of JTable methods
  public boolean editCellAt(int row, int column, EventObject evt) {
    if (super.editCellAt(row, column, evt== false) {
      return false;
    }

    if (viewEditingColumns != null) {
      // Note: column is specified in terms of the column model
      int length = viewEditingColumns.length;
      for (int i = 0; i < length; i++) {
        if (column == viewEditingColumns[i]) {
          Component comp = getEditorComponent();
          comp.addKeyListener(tabKeyListener);
          this.addKeyListener(tabKeyListener);
          focusManager = FocusManager.getCurrentManager();
          FocusManager.disableSwingFocusManager();
          inTabbingEditor = true;
          comp.requestFocus();
          break;
        }
      }
    }

    return true;
  }

  public void editingStopped(ChangeEvent evt) {
    if (inTabbingEditor == true) {
      Component comp = getEditorComponent();
      comp.removeKeyListener(tabKeyListener);
      this.removeKeyListener(tabKeyListener);
      FocusManager.setCurrentManager(focusManager);

      inTabbingEditor = false;
    }

    super.editingStopped(evt);
  }

  protected void convertEditableColumnsToView() {
    // Convert the editable columns to view column numbers
    if (editingColumns == null) {
      viewEditingColumns = null;
      return;
    }

    // Create a set of editable columns in terms of view
    // column numbers in ascending order. Note that not all
    // editable columns in the data model need be visible.
    int length = editingColumns.length;
    viewEditingColumns = new int[length];
    int nextSlot = 0;

    for (int i = 0; i < length; i++) {
      int viewIndex = convertColumnIndexToView(editingColumns[i]);
      if (viewIndex != -1) {
        viewEditingColumns[nextSlot++= viewIndex;
      }
    }

    // Now create an array of the right length to hold the view indices
    if (nextSlot < length) {
      int[] tempArray = new int[nextSlot];
      System.arraycopy(viewEditingColumns, 0, tempArray, 0, nextSlot);
      viewEditingColumns = tempArray;
    }

    // Finally, sort the view columns into order
    TableUtilities.sort(viewEditingColumns);
  }

  protected void moveToNextEditor(int row, int column, boolean forward) {
    // Column is specified in terms of the column model
    if (viewEditingColumns != null) {
      int length = viewEditingColumns.length;

      // Move left-to-right or right-to-left across the table
      for (int i = 0; i < length; i++) {
        if (viewEditingColumns[i== column) {
          // Select the next column to edit
          if (forward == true) {
            if (++i == length) {
              // Reached end of row - wrap
              i = 0;
              row++;
              if (row == getRowCount()) {
                // End of table - wrap
                row = 0;
              }
            }
          else {
            if (--i < 0) {
              i = length - 1;
              row--;
              if (row < 0) {
                row = getRowCount() 1;
              }
            }
          }
          final int newRow = row;
          final int newColumn = viewEditingColumns[i];

          // Start editing at new location
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              editCellAt(newRow, newColumn);
              ListSelectionModel rowSel = getSelectionModel();
              ListSelectionModel columnSel = getColumnModel()
                  .getSelectionModel();
              rowSel.setSelectionInterval(newRow, newRow);
              columnSel
                  .setSelectionInterval(newColumn, newColumn);
            }
          });
          break;
        }
      }
    }
  }

  // Catch changes to the table column model
  public void columnAdded(TableColumnModelEvent e) {
    super.columnAdded(e);
    convertEditableColumnsToView();
  }

  public void columnRemoved(TableColumnModelEvent e) {
    super.columnRemoved(e);
    convertEditableColumnsToView();
  }

  public void columnMoved(TableColumnModelEvent e) {
    super.columnMoved(e);
    convertEditableColumnsToView();
  }

  public class TabKeyListener extends KeyAdapter {
    public void keyPressed(KeyEvent evt) {
      if (evt.getKeyCode() == KeyEvent.VK_TAB) {
        if (inTabbingEditor == true) {
          TableCellEditor editor = getCellEditor();
          int editRow = getEditingRow();
          int editColumn = getEditingColumn();
          if (editor != null) {
            boolean stopped = editor.stopCellEditing();
            if (stopped == true) {
              boolean forward = (evt.isShiftDown() == false);
              moveToNextEditor(editRow, editColumn, forward);
            }
          }
        }
      }
    }
  }

  protected boolean inTabbingEditor;

  protected FocusManager focusManager;

  protected int[] editingColumns; // Model columns

  protected int[] viewEditingColumns; // View columns

  protected TabKeyListener tabKeyListener = new TabKeyListener();
}

class FractionCellRenderer extends DefaultTableCellRenderer {
  public FractionCellRenderer(int integer, int fraction, int align) {
    this.integer = integer; // maximum integer digits
    this.fraction = fraction; // exact number of fraction digits
    this.align = align; // alignment (LEFT, CENTER, RIGHT)
  }

  protected void setValue(Object value) {
    if (value != null && value instanceof Number) {
      formatter.setMaximumIntegerDigits(integer);
      formatter.setMaximumFractionDigits(fraction);
      formatter.setMinimumFractionDigits(fraction);
      setText(formatter.format(((Numbervalue).doubleValue()));
    else {
      super.setValue(value);
    }
    setHorizontalAlignment(align);
  }

  protected int integer;

  protected int fraction;

  protected int align;

  protected static NumberFormat formatter = NumberFormat.getInstance();
}

class TextWithIconCellRenderer extends DefaultTableCellRenderer {
  protected void setValue(Object value) {
    if (value instanceof DataWithIcon) {
      if (value != null) {
        DataWithIcon d = (DataWithIconvalue;
        Object dataValue = d.getData();

        setText(dataValue == null "" : dataValue.toString());
        setIcon(d.getIcon());
        setHorizontalTextPosition(SwingConstants.RIGHT);
        setVerticalTextPosition(SwingConstants.CENTER);
        setHorizontalAlignment(SwingConstants.LEFT);
        setVerticalAlignment(SwingConstants.CENTER);
      else {
        setText("");
        setIcon(null);
      }
    else {
      super.setValue(value);
    }
  }
}

class DataWithIcon {
  public DataWithIcon(Object data, Icon icon) {
    this.data = data;
    this.icon = icon;
  }

  public Icon getIcon() {
    return icon;
  }

  public Object getData() {
    return data;
  }

  public String toString() {
    return data.toString();
  }

  protected Icon icon;

  protected Object data;
}

class TableUtilities {
  // Calculate the required width of a table column
  public static int calculateColumnWidth(JTable table, int columnIndex) {
    int width = 0// The return value
    int rowCount = table.getRowCount();

    for (int i = 0; i < rowCount; i++) {
      TableCellRenderer renderer = table.getCellRenderer(i, columnIndex);
      Component comp = renderer.getTableCellRendererComponent(table,
          table.getValueAt(i, columnIndex), false, false, i,
          columnIndex);
      int thisWidth = comp.getPreferredSize().width;
      if (thisWidth > width) {
        width = thisWidth;
      }
    }

    return width;
  }

  // Set the widths of every column in a table
  public static void setColumnWidths(JTable table, Insets insets,
      boolean setMinimum, boolean setMaximum) {
    int columnCount = table.getColumnCount();
    TableColumnModel tcm = table.getColumnModel();
    int spare = (insets == null : insets.left + insets.right);

    for (int i = 0; i < columnCount; i++) {
      int width = calculateColumnWidth(table, i);
      width += spare;

      TableColumn column = tcm.getColumn(i);
      column.setPreferredWidth(width);
      if (setMinimum == true) {
        column.setMinWidth(width);
      }
      if (setMaximum == true) {
        column.setMaxWidth(width);
      }
    }
  }

  // Sort an array of integers in place
  public static void sort(int[] values) {
    int length = values.length;
    if (length > 1) {
      for (int i = 0; i < length - 1; i++) {
        for (int j = i + 1; j < length; j++) {
          if (values[j< values[i]) {
            int temp = values[i];
            values[i= values[j];
            values[j= temp;
          }
        }
      }
    }
  }
}

class StripedTableCellRenderer implements TableCellRenderer {
  public StripedTableCellRenderer(TableCellRenderer targetRenderer,
      Color evenBack, Color evenFore, Color oddBack, Color oddFore) {
    this.targetRenderer = targetRenderer;
    this.evenBack = evenBack;
    this.evenFore = evenFore;
    this.oddBack = oddBack;
    this.oddFore = oddFore;
  }

  // Implementation of TableCellRenderer interface
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    TableCellRenderer renderer = targetRenderer;
    if (renderer == null) {
      // Get default renderer from the table
      renderer = table.getDefaultRenderer(table.getColumnClass(column));
    }

    // Let the real renderer create the component
    Component comp = renderer.getTableCellRendererComponent(table, value,
        isSelected, hasFocus, row, column);

    // Now apply the stripe effect
    if (isSelected == false && hasFocus == false) {
      if ((row & 1== 0) {
        comp.setBackground(evenBack != null ? evenBack : table
            .getBackground());
        comp.setForeground(evenFore != null ? evenFore : table
            .getForeground());
      else {
        comp.setBackground(oddBack != null ? oddBack : table
            .getBackground());
        comp.setForeground(oddFore != null ? oddFore : table
            .getForeground());
      }
    }

    return comp;
  }

  // Convenience method to apply this renderer to single column
  public static void installInColumn(JTable table, int columnIndex,
      Color evenBack, Color evenFore, Color oddBack, Color oddFore) {
    TableColumn tc = table.getColumnModel().getColumn(columnIndex);

    // Get the cell renderer for this column, if any
    TableCellRenderer targetRenderer = tc.getCellRenderer();

    // Create a new StripedTableCellRenderer and install it
    tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer,
        evenBack, evenFore, oddBack, oddFore));
  }

  // Convenience method to apply this renderer to an entire table
  public static void installInTable(JTable table, Color evenBack,
      Color evenFore, Color oddBack, Color oddFore) {
    StripedTableCellRenderer sharedInstance = null;
    int columns = table.getColumnCount();
    for (int i = 0; i < columns; i++) {
      TableColumn tc = table.getColumnModel().getColumn(i);
      TableCellRenderer targetRenderer = tc.getCellRenderer();
      if (targetRenderer != null) {
        // This column has a specific renderer
        tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer,
            evenBack, evenFore, oddBack, oddFore));
      else {
        // This column uses a class renderer - use a shared renderer
        if (sharedInstance == null) {
          sharedInstance = new StripedTableCellRenderer(null,
              evenBack, evenFore, oddBack, oddFore);
        }
        tc.setCellRenderer(sharedInstance);
      }
    }
  }

  protected TableCellRenderer targetRenderer;

  protected Color evenBack;

  protected Color evenFore;

  protected Color oddBack;

  protected Color oddFore;
}

class HighlightRenderer implements TableCellRenderer {
  public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer,
      Color backColor, Color foreColor, Color highlightBack,
      Color highlightFore) {
    this.cmp = cmp;
    this.targetRenderer = targetRenderer;
    this.backColor = backColor;
    this.foreColor = foreColor;
    this.highlightBack = highlightBack;
    this.highlightFore = highlightFore;
  }

  public Component getTableCellRendererComponent(JTable tbl, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    TableCellRenderer renderer = targetRenderer;
    if (renderer == null) {
      renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column));
    }
    Component comp = renderer.getTableCellRendererComponent(tbl, value,
        isSelected, hasFocus, row, column);
    if (isSelected == false && hasFocus == false && value != null) {
      if (cmp.shouldHighlight(tbl, value, row, column)) {
        comp.setForeground(highlightFore);
        comp.setBackground(highlightBack);
      else {
        comp.setForeground(foreColor);
        comp.setBackground(backColor);
      }
    }

    return comp;
  }

  protected Comparator cmp;

  protected TableCellRenderer targetRenderer;

  protected Color backColor;

  protected Color foreColor;

  protected Color highlightBack;

  protected Color highlightFore;
}

interface Comparator {
  public abstract boolean shouldHighlight(JTable tbl, Object value, int row,
      int column);
}

class ButtonRenderer extends JButton implements TableCellRenderer {
  public ButtonRenderer() {
    this.border = getBorder();
    this.setOpaque(true);
  }

  public void setForeground(Color foreground) {
    this.foreground = foreground;
    super.setForeground(foreground);
  }

  public void setBackground(Color background) {
    this.background = background;
    super.setBackground(background);
  }

  public void setFont(Font font) {
    this.font = font;
    super.setFont(font);
  }

  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    Color cellForeground = foreground != null ? foreground : table
        .getForeground();
    Color cellBackground = background != null ? background : table<