Expense Table

/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class ExpenseReport extends JFrame
{
protected JTable m_table;
protected ExpenseReportData m_data;
protected JLabel m_title;
public ExpenseReport() {
super("Expense Report");
setSize(570, 200);
m_data = new ExpenseReportData(this);
m_table = new JTable();
m_table.setAutoCreateColumnsFromModel(false);
m_table.setModel(m_data);
m_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
for (int k = 0; k < ExpenseReportData.m_columns.length; k++) {
TableCellRenderer renderer;
if (k==ExpenseReportData.COL_APPROVED)
renderer = new CheckCellRenderer();
else {
DefaultTableCellRenderer textRenderer =
new DefaultTableCellRenderer();
textRenderer.setHorizontalAlignment(
ExpenseReportData.m_columns[k].m_alignment);
renderer = textRenderer;
}
TableCellEditor editor;
if (k==ExpenseReportData.COL_CATEGORY)
editor = new DefaultCellEditor(new JComboBox(
ExpenseReportData.CATEGORIES));
else if (k==ExpenseReportData.COL_APPROVED)
editor = new DefaultCellEditor(new JCheckBox());
else
editor = new DefaultCellEditor(new JTextField());
TableColumn column = new TableColumn(k,
ExpenseReportData.m_columns[k].m_width,
renderer, editor);
m_table.addColumn(column);
}
JTableHeader header = m_table.getTableHeader();
header.setUpdateTableInRealTime(false);
JScrollPane ps = new JScrollPane();
ps.setSize(550, 150);
ps.getViewport().add(m_table);
getContentPane().add(ps, BorderLayout.CENTER);
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
ImageIcon penny = new ImageIcon("penny.gif");
m_title = new JLabel("Total: $",
penny, JButton.LEFT);
m_title.setForeground(Color.black);
m_title.setAlignmentY(0.5f);
p.add(m_title);
p.add(Box.createHorizontalGlue());
JButton bt = new JButton("Insert before");
bt.setMnemonic('b');
bt.setAlignmentY(0.5f);
ActionListener lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int row = m_table.getSelectedRow();
m_data.insert(row);
m_table.tableChanged(new TableModelEvent(
m_data, row, row, TableModelEvent.ALL_COLUMNS,
TableModelEvent.INSERT));
m_table.repaint();
}
};
bt.addActionListener(lst);
p.add(bt);
bt = new JButton("Insert after");
bt.setMnemonic('a');
bt.setAlignmentY(0.5f);
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int row = m_table.getSelectedRow();
m_data.insert(row+1);
m_table.tableChanged(new TableModelEvent(
m_data, row+1, row+1, TableModelEvent.ALL_COLUMNS,
TableModelEvent.INSERT));
m_table.repaint();
}
};
bt.addActionListener(lst);
p.add(bt);
bt = new JButton("Delete row");
bt.setMnemonic('d');
bt.setAlignmentY(0.5f);
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int row = m_table.getSelectedRow();
if (m_data.delete(row)) {
m_table.tableChanged(new TableModelEvent(
m_data, row, row, TableModelEvent.ALL_COLUMNS,
TableModelEvent.INSERT));
m_table.repaint();
calcTotal();
}
}
};
bt.addActionListener(lst);
p.add(bt);
getContentPane().add(p, BorderLayout.SOUTH);
calcTotal();
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(wndCloser);
setVisible(true);
}
public void calcTotal() {
double total = 0;
for (int k=0; k<m_data.getRowCount(); k++) {
Double amount = (Double)m_data.getValueAt(k,
ExpenseReportData.COL_AMOUNT);
total += amount.doubleValue();
}
m_title.setText("Total: $"+total);
}
public static void main(String argv[]) {
new ExpenseReport();
}
}
class CheckCellRenderer extends JCheckBox implements TableCellRenderer
{
protected static Border m_noFocusBorder;
public CheckCellRenderer() {
super();
m_noFocusBorder = new EmptyBorder(1, 2, 1, 2);
setOpaque(true);
setBorder(m_noFocusBorder);
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
if (value instanceof Boolean) {
Boolean b = (Boolean)value;
setSelected(b.booleanValue());
}
setBackground(isSelected && !hasFocus ?
table.getSelectionBackground() : table.getBackground());
setForeground(isSelected && !hasFocus ?
table.getSelectionForeground() : table.getForeground());
setFont(table.getFont());
setBorder(hasFocus ? UIManager.getBorder(
"Table.focusCellHighlightBorder") : m_noFocusBorder);
return this;
}
}
class ExpenseData
{
public Date m_date;
public Double m_amount;
public Integer m_category;
public Boolean m_approved;
public String m_description;
public ExpenseData() {
m_date = new Date();
m_amount = new Double(0);
m_category = new Integer(1);
m_approved = new Boolean(false);
m_description = "";
}
public ExpenseData(Date date, double amount, int category,
boolean approved, String description)
{
m_date = date;
m_amount = new Double(amount);
m_category = new Integer(category);
m_approved = new Boolean(approved);
m_description = description;
}
}
class ColumnData
{
public String m_title;
int m_width;
int m_alignment;
public ColumnData(String title, int width, int alignment) {
m_title = title;
m_width = width;
m_alignment = alignment;
}
}
class ExpenseReportData extends AbstractTableModel
{
public static final ColumnData m_columns[] = {
new ColumnData( "Date", 80, JLabel.LEFT ),
new ColumnData( "Amount", 80, JLabel.RIGHT ),
new ColumnData( "Category", 130, JLabel.LEFT ),
new ColumnData( "Approved", 80, JLabel.LEFT ),
new ColumnData( "Description", 180, JLabel.LEFT )
};
public static final int COL_DATE = 0;
public static final int COL_AMOUNT = 1;
public static final int COL_CATEGORY = 2;
public static final int COL_APPROVED = 3;
public static final int COL_DESCR = 4;
public static final String[] CATEGORIES = {
"Fares", "Logging", "Business meals", "Others"
};
protected ExpenseReport m_parent;
protected SimpleDateFormat m_frm;
protected Vector m_vector;
public ExpenseReportData(ExpenseReport parent) {
m_parent = parent;
m_frm = new SimpleDateFormat("MM/dd/yy");
m_vector = new Vector();
setDefaultData();
}
public void setDefaultData() {
m_vector.removeAllElements();
try {
m_vector.addElement(new ExpenseData(
m_frm.parse("04/06/99"), 200, 0, true,
"Airline tickets"));
m_vector.addElement(new ExpenseData(
m_frm.parse("04/06/99"), 50, 2, false,
"Lunch with client"));
m_vector.addElement(new ExpenseData(
m_frm.parse("04/06/99"), 120, 1, true,
"Hotel"));
}
catch (java.text.ParseException ex) {}
}
public int getRowCount() {
return m_vector==null ? 0 : m_vector.size();
}
public int getColumnCount() {
return m_columns.length;
}
public String getColumnName(int column) {
return m_columns[column].m_title;
}
public boolean isCellEditable(int nRow, int nCol) {
return true;
}
public Object getValueAt(int nRow, int nCol) {
if (nRow < 0 || nRow>=getRowCount())
return "";
ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
switch (nCol) {
case COL_DATE: return m_frm.format(row.m_date);
case COL_AMOUNT: return row.m_amount;
case COL_CATEGORY: return CATEGORIES[row.m_category.intValue()];
case COL_APPROVED: return row.m_approved;
case COL_DESCR: return row.m_description;
}
return "";
}
public void setValueAt(Object value, int nRow, int nCol) {
if (nRow < 0 || nRow>=getRowCount())
return;
ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
String svalue = value.toString();
switch (nCol) {
case COL_DATE:
Date date = null;
try {
date = m_frm.parse(svalue);
}
catch (java.text.ParseException ex) {
date = null;
}
if (date == null) {
JOptionPane.showMessageDialog(null,
svalue+" is not a valid date",
"Warning", JOptionPane.WARNING_MESSAGE);
return;
}
row.m_date = date;
break;
case COL_AMOUNT:
try {
row.m_amount = new Double(svalue);
}
catch (NumberFormatException e) { break; }
m_parent.calcTotal();
break;
case COL_CATEGORY:
for (int k=0; k<CATEGORIES.length; k++)
if (svalue.equals(CATEGORIES[k])) {
row.m_category = new Integer(k);
break;
}
break;
case COL_APPROVED:
row.m_approved = (Boolean)value;
break;
case COL_DESCR:
row.m_description = svalue;
break;
}
}
public void insert(int row) {
if (row < 0)
row = 0;
if (row > m_vector.size())
row = m_vector.size();
m_vector.insertElementAt(new ExpenseData(), row);
}
public boolean delete(int row) {
if (row < 0 || row >= m_vector.size())
return false;
m_vector.remove(row);
return true;
}
}
Related examples in the same category
| 1. | Creating a JTable Component | | |
| 2. | Creates tables that allow rows and columns to be added or deleted | | |
| 3. | Build a table from list data and column names | | |
| 4. | Getting the Number of Rows and Columns in a JTable Component | | |
| 5. | Appending a Row to a JTable Component | | |
| 6. | Add columns to a table through DefaultTableModel | | |
| 7. | Insert a row to a table through DefaultTableModel | | |
| 8. | Insert a row to a table through DefaultTableModel at specified row | | |
| 9. | Scroll Table Sample | |  |
| 10. | Simple demonstration of JTable | |  |
| 11. | Create a table with two dimensional array | |  |
| 12. | Create table with Unicode data | |  |
| 13. | Resize Table | |  |
| 14. | StockTable 6: Action and Dynamic Display | |  |
| 15. | JTable selection events | |  |
| 16. | A table with the ability to play with row and column selections | |  |
| 17. | Table Selection mode | |  |
| 18. | Display ResultSet in Table (JTable) | | |
| 19. | JTable(Table) with JDBC and ResultSet | |  |
| 20. | List UI Properties in a JTable and sortable | |  |
| 21. | Property Table: Use JTable to display and edit properties | |  |
| 22. | Table with tool tips for both cells and column headers | |  |
| 23. | StockTable 4: Table Sorter | |  |
| 24. | JTable sorter:click the table header to sort a column and a table | |  |
| 25. | Creating image out of a JTable | | |
| 26. | JTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); | | |
| 27. | JTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | | |
| 28. | JTable.setColumnSelectionAllowed(boolean b); | | |
| 29. | JTable.setRowSelectionAllowed(boolean b); | | |
| 30. | JTable.setCellSelectionEnabled(boolean b); | | |
| 31. | Handle selection and model change events for a JTable. | | |
| 32. | ListSelectionModel rowSelMod = JTable.getSelectionModel(); | | |
| 33. | ListSelectionModel colSelMod = JTable.getColumnModel().getSelectionModel(); | | |
| 34. | JTree.getModel().addTreeModelListener(new TreeModelListener()) | | |
| 35. | Move the last visible column so it becomes the first visible column | | |
| 36. | the last column is moved to the first position | | |
| 37. | Allowing the User to Resize a Column in a JTable Component | | |
| 38. | Retrieve the value in the visible cell (1,2) in a JTable | | |
| 39. | Retrieve the value in cell (1,2) from the model | | |
| 40. | Change a cell in the 2nd visible column | | |
| 41. | Change a cell in the 3rd column in the model | | |
| 42. | Showing the Table Header in a Non-Scrollable JTable Component | | |
| 43. | Changing the Name of a Column in a JTable Component | | |
| 44. | Displaying an Icon in a Column Head of a JTable Component | | |
| 45. | Implementing Variable-Height Column Headers in a JTable Component | | |
| 46. | Removing the Column Headers from a Scrollable in a JTable Component | | |
| 47. | Creating a Custom Column Header Renderer in a JTable Component | | |
| 48. | Setting Column Header Tool Tips in a JTable Components | | |
| 49. | Setting Tool Tips on Cells in a JTable Component | | |
| 50. | Enable row selection (default) in a JTable | | |
| 51. | Enable column selection in a JTable | | |
| 52. | Enable cell selection in a JTable | | |
| 53. | Get default selection mode:MULTIPLE_INTERVAL_SELECTION | | |
| 54. | Allow only single a selection | | |
| 55. | Allow selection to span one contiguous set of rows, visible columns, or block of cells | | |
| 56. | Allow multiple selections of rows, visible columns, or cell blocks (default) | | |
| 57. | Select a column - column 0 in a JTable | | |
| 58. | Select an additional range of columns - columns 1 to 2 | | |
| 59. | Deselect a range of columns - columns 0 to 1 | | |
| 60. | Select a row - row 0 | | |
| 61. | Select an additional range of rows - rows 1 to 2 | | |
| 62. | Deselect a range of rows - rows 0 to 1 | | |
| 63. | Select a cell: cell (2,1) | | |
| 64. | Extend the selection to include all cells (5,3) | | |
| 65. | Deselect a cell: cell (3,2), All cells in the row and column containing (3,2) are deselected. | | |
| 66. | Toggles the selection state, if it were called again, it exactly reverses the first call. | | |
| 67. | Select all cells | | |
| 68. | Deselect all cells | | |
| 69. | Column selection is enabled, get the indices of the selected columns | | |
| 70. | Row selection is enabled, Get the indices of the selected rows | | |
| 71. | Get selected row and selected index | | |
| 72. | Get the min and max ranges of selected cells | | |
| 73. | Check each cell in the min and max ranges of selected cells | | |
| 74. | Disabling Selections in a JTable Component | | |
| 75. | Getting the Anchor Cell in a JTable Component | | |
| 76. | Creating a Scrollable JTable Component | | |
| 77. | Disable auto resizing to make the table horizontal scrollable | | |
| 78. | Determining If a Cell Is Visible in a JTable Component | | |
| 79. | Making a Cell Visible in a JTable Component | | |
| 80. | Scrolling a Cell to the Center of a JTable Component | | |
| 81. | Show both horizontal and vertical grid lines (the default) | | |
| 82. | Don't show any grid lines | | |
| 83. | Show only vertical grid lines | | |
| 84. | Show only horizontal grid lines | | |
| 85. | Set the grid color | | |
| 86. | Getting the Gap Size Between Cells in a JTable Component | | |
| 87. | Add 5 spaces to the left and right sides of a cell. | | |
| 88. | Increase the row height | | |
| 89. | Programmatically Starting Cell Editing in a JTable Component | | |
| 90. | Save the current value in the cell being edited and stops the editing process | | |
| 91. | Discard any changes made by the user and stops the editing process | | |
| 92. | Disabling User Edits in a JTable | | |
| 93. | Disabling User Edits in a JTable with DefaultTableModel | | |
| 94. | Sorting the Rows in a JTable Component Based on a Column | | |
| 95. | Sorting a Column in a JTable Component | | |
| 96. | Listening for Selection Events in a JTable Component | | |
| 97. | Listening for Changes to the Rows and Columns of a JTable Component | | |
| 98. | Listening for Column-Related Changes in a JTable Component | | |
| 99. | Listening for Clicks on a Column Header in a JTable Component | | |
| 100. | Sorting and Filtering Tables | | |
| 101. | Use a regexFilter to filter table content | | |
| 102. | Creating a JTable with rows of variable height | | |
| 103. | Scroll JTable To Center | | |