提交 4e480fb9 编写于 作者: M mrkam

7027701: /jfc/TableExample demo needs to be improved

Reviewed-by: alexp
上级 18059efb
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,46 +29,50 @@ ...@@ -29,46 +29,50 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
/** /**
* An adaptor, transforming the JDBC interface to the TableModel interface. * An adaptor, transforming the JDBC interface to the TableModel interface.
* *
* @author Philip Milne * @author Philip Milne
*/ */
@SuppressWarnings("serial")
import java.util.Vector;
import java.sql.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.TableModelEvent;
public class JDBCAdapter extends AbstractTableModel { public class JDBCAdapter extends AbstractTableModel {
Connection connection;
Statement statement; Connection connection;
ResultSet resultSet; Statement statement;
String[] columnNames = {}; ResultSet resultSet;
Vector rows = new Vector(); String[] columnNames = {};
ResultSetMetaData metaData; List<List<Object>> rows = new ArrayList<List<Object>>();
ResultSetMetaData metaData;
public JDBCAdapter(String url, String driverName, public JDBCAdapter(String url, String driverName,
String user, String passwd) { String user, String passwd) {
try { try {
Class.forName(driverName); Class.forName(driverName);
System.out.println("Opening db connection"); System.out.println("Opening db connection");
connection = DriverManager.getConnection(url, user, passwd); connection = DriverManager.getConnection(url, user, passwd);
statement = connection.createStatement(); statement = connection.createStatement();
} } catch (ClassNotFoundException ex) {
catch (ClassNotFoundException ex) {
System.err.println("Cannot find the database driver classes."); System.err.println("Cannot find the database driver classes.");
System.err.println(ex); System.err.println(ex);
} } catch (SQLException ex) {
catch (SQLException ex) {
System.err.println("Cannot connect to this database."); System.err.println("Cannot connect to this database.");
System.err.println(ex); System.err.println(ex);
} }
} }
public void executeQuery(String query) { public void executeQuery(String query) {
if (connection == null || statement == null) { if (connection == null || statement == null) {
...@@ -79,27 +83,28 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -79,27 +83,28 @@ public class JDBCAdapter extends AbstractTableModel {
resultSet = statement.executeQuery(query); resultSet = statement.executeQuery(query);
metaData = resultSet.getMetaData(); metaData = resultSet.getMetaData();
int numberOfColumns = metaData.getColumnCount(); int numberOfColumns = metaData.getColumnCount();
columnNames = new String[numberOfColumns]; columnNames = new String[numberOfColumns];
// Get the column names and cache them. // Get the column names and cache them.
// Then we can close the connection. // Then we can close the connection.
for(int column = 0; column < numberOfColumns; column++) { for (int column = 0; column < numberOfColumns; column++) {
columnNames[column] = metaData.getColumnLabel(column+1); columnNames[column] = metaData.getColumnLabel(column + 1);
} }
// Get all rows. // Get all rows.
rows = new Vector(); rows = new ArrayList<List<Object>>();
while (resultSet.next()) { while (resultSet.next()) {
Vector newRow = new Vector(); List<Object> newRow = new ArrayList<Object>();
for (int i = 1; i <= getColumnCount(); i++) { for (int i = 1; i <= getColumnCount(); i++) {
newRow.addElement(resultSet.getObject(i)); newRow.add(resultSet.getObject(i));
} }
rows.addElement(newRow); rows.add(newRow);
} }
// close(); Need to copy the metaData, bug in jdbc:odbc driver. // close(); Need to copy the metaData, bug in jdbc:odbc driver.
fireTableChanged(null); // Tell the listeners a new table has arrived.
} // Tell the listeners a new table has arrived.
catch (SQLException ex) { fireTableChanged(null);
} catch (SQLException ex) {
System.err.println(ex); System.err.println(ex);
} }
} }
...@@ -111,6 +116,7 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -111,6 +116,7 @@ public class JDBCAdapter extends AbstractTableModel {
connection.close(); connection.close();
} }
@Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
close(); close();
super.finalize(); super.finalize();
...@@ -121,9 +127,8 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -121,9 +127,8 @@ public class JDBCAdapter extends AbstractTableModel {
// Implementation of the TableModel Interface // Implementation of the TableModel Interface
// //
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// MetaData // MetaData
@Override
public String getColumnName(int column) { public String getColumnName(int column) {
if (columnNames[column] != null) { if (columnNames[column] != null) {
return columnNames[column]; return columnNames[column];
...@@ -132,49 +137,49 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -132,49 +137,49 @@ public class JDBCAdapter extends AbstractTableModel {
} }
} }
public Class getColumnClass(int column) { @Override
public Class<?> getColumnClass(int column) {
int type; int type;
try { try {
type = metaData.getColumnType(column+1); type = metaData.getColumnType(column + 1);
} } catch (SQLException e) {
catch (SQLException e) {
return super.getColumnClass(column); return super.getColumnClass(column);
} }
switch(type) { switch (type) {
case Types.CHAR: case Types.CHAR:
case Types.VARCHAR: case Types.VARCHAR:
case Types.LONGVARCHAR: case Types.LONGVARCHAR:
return String.class; return String.class;
case Types.BIT: case Types.BIT:
return Boolean.class; return Boolean.class;
case Types.TINYINT: case Types.TINYINT:
case Types.SMALLINT: case Types.SMALLINT:
case Types.INTEGER: case Types.INTEGER:
return Integer.class; return Integer.class;
case Types.BIGINT: case Types.BIGINT:
return Long.class; return Long.class;
case Types.FLOAT: case Types.FLOAT:
case Types.DOUBLE: case Types.DOUBLE:
return Double.class; return Double.class;
case Types.DATE: case Types.DATE:
return java.sql.Date.class; return java.sql.Date.class;
default: default:
return Object.class; return Object.class;
} }
} }
@Override
public boolean isCellEditable(int row, int column) { public boolean isCellEditable(int row, int column) {
try { try {
return metaData.isWritable(column+1); return metaData.isWritable(column + 1);
} } catch (SQLException e) {
catch (SQLException e) {
return false; return false;
} }
} }
...@@ -184,14 +189,13 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -184,14 +189,13 @@ public class JDBCAdapter extends AbstractTableModel {
} }
// Data methods // Data methods
public int getRowCount() { public int getRowCount() {
return rows.size(); return rows.size();
} }
public Object getValueAt(int aRow, int aColumn) { public Object getValueAt(int aRow, int aColumn) {
Vector row = (Vector)rows.elementAt(aRow); List<Object> row = rows.get(aRow);
return row.elementAt(aColumn); return row.get(aColumn);
} }
public String dbRepresentation(int column, Object value) { public String dbRepresentation(int column, Object value) {
...@@ -202,43 +206,42 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -202,43 +206,42 @@ public class JDBCAdapter extends AbstractTableModel {
} }
try { try {
type = metaData.getColumnType(column+1); type = metaData.getColumnType(column + 1);
} } catch (SQLException e) {
catch (SQLException e) {
return value.toString(); return value.toString();
} }
switch(type) { switch (type) {
case Types.INTEGER: case Types.INTEGER:
case Types.DOUBLE: case Types.DOUBLE:
case Types.FLOAT: case Types.FLOAT:
return value.toString(); return value.toString();
case Types.BIT: case Types.BIT:
return ((Boolean)value).booleanValue() ? "1" : "0"; return ((Boolean) value).booleanValue() ? "1" : "0";
case Types.DATE: case Types.DATE:
return value.toString(); // This will need some conversion. return value.toString(); // This will need some conversion.
default: default:
return "\""+value.toString()+"\""; return "\"" + value.toString() + "\"";
} }
} }
@Override
public void setValueAt(Object value, int row, int column) { public void setValueAt(Object value, int row, int column) {
try { try {
String tableName = metaData.getTableName(column+1); String tableName = metaData.getTableName(column + 1);
// Some of the drivers seem buggy, tableName should not be null. // Some of the drivers seem buggy, tableName should not be null.
if (tableName == null) { if (tableName == null) {
System.out.println("Table name returned null."); System.out.println("Table name returned null.");
} }
String columnName = getColumnName(column); String columnName = getColumnName(column);
String query = String query =
"update "+tableName+ "update " + tableName + " set " + columnName + " = "
" set "+columnName+" = "+dbRepresentation(column, value)+ + dbRepresentation(column, value) + " where ";
" where ";
// We don't have a model of the schema so we don't know the // We don't have a model of the schema so we don't know the
// primary keys or which columns to lock on. To demonstrate // primary keys or which columns to lock on. To demonstrate
// that editing is possible, we'll just lock on everything. // that editing is possible, we'll just lock on everything.
for(int col = 0; col<getColumnCount(); col++) { for (int col = 0; col < getColumnCount(); col++) {
String colName = getColumnName(col); String colName = getColumnName(col);
if (colName.equals("")) { if (colName.equals("")) {
continue; continue;
...@@ -246,19 +249,18 @@ public class JDBCAdapter extends AbstractTableModel { ...@@ -246,19 +249,18 @@ public class JDBCAdapter extends AbstractTableModel {
if (col != 0) { if (col != 0) {
query = query + " and "; query = query + " and ";
} }
query = query + colName +" = "+ query = query + colName + " = " + dbRepresentation(col,
dbRepresentation(col, getValueAt(row, col)); getValueAt(row, col));
} }
System.out.println(query); System.out.println(query);
System.out.println("Not sending update to database"); System.out.println("Not sending update to database");
// statement.executeQuery(query); // statement.executeQuery(query);
} } catch (SQLException e) {
catch (SQLException e) {
// e.printStackTrace(); // e.printStackTrace();
System.err.println("Update failed"); System.err.println("Update failed");
} }
Vector dataRow = (Vector)rows.elementAt(row); List<Object> dataRow = rows.get(row);
dataRow.setElementAt(value, column); dataRow.set(column, value);
} }
} }
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,28 +29,26 @@ ...@@ -29,28 +29,26 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import java.lang.Thread; import java.util.EventObject;
import java.util.*; import java.util.List;
import java.awt.*; import javax.swing.JTable;
import java.awt.event.*; import javax.swing.table.DefaultTableModel;
import javax.swing.*; import javax.swing.table.TableCellEditor;
import javax.swing.event.*; import javax.swing.table.TableCellRenderer;
import javax.swing.plaf.*; import javax.swing.table.TableColumn;
import javax.swing.table.*;
/** /**
* The OldJTable is an unsupported class containing some methods that were * The OldJTable is an unsupported class containing some methods that were
* deleted from the JTable between releases 0.6 and 0.7 * deleted from the JTable between releases 0.6 and 0.7
*/ */
@SuppressWarnings("serial")
public class OldJTable extends JTable public class OldJTable extends JTable
{ {
/* /*
* A new convenience method returning the index of the column in the co-ordinate * A new convenience method returning the index of the column in the
* space of the view. * co-ordinate space of the view.
*/ */
public int getColumnIndex(Object identifier) { public int getColumnIndex(Object identifier) {
return getColumnModel().getColumnIndex(identifier); return getColumnModel().getColumnIndex(identifier);
...@@ -65,7 +63,7 @@ public class OldJTable extends JTable ...@@ -65,7 +63,7 @@ public class OldJTable extends JTable
return addColumn(columnIdentifier, width, null, null, null); return addColumn(columnIdentifier, width, null, null, null);
} }
public TableColumn addColumn(Object columnIdentifier, Vector columnData) { public TableColumn addColumn(Object columnIdentifier, List columnData) {
return addColumn(columnIdentifier, -1, null, null, columnData); return addColumn(columnIdentifier, -1, null, null, columnData);
} }
...@@ -79,16 +77,17 @@ public class OldJTable extends JTable ...@@ -79,16 +77,17 @@ public class OldJTable extends JTable
public TableColumn addColumn(Object columnIdentifier, int width, public TableColumn addColumn(Object columnIdentifier, int width,
TableCellRenderer renderer, TableCellRenderer renderer,
TableCellEditor editor, Vector columnData) { TableCellEditor editor, List columnData) {
checkDefaultTableModel(); checkDefaultTableModel();
// Set up the model side first // Set up the model side first
DefaultTableModel m = (DefaultTableModel)getModel(); DefaultTableModel m = (DefaultTableModel)getModel();
m.addColumn(columnIdentifier, columnData); m.addColumn(columnIdentifier, columnData.toArray());
// The column will have been added to the end, so the index of the // The column will have been added to the end, so the index of the
// column in the model is the last element. // column in the model is the last element.
TableColumn newColumn = new TableColumn(m.getColumnCount()-1, width, renderer, editor); TableColumn newColumn = new TableColumn(
m.getColumnCount()-1, width, renderer, editor);
super.addColumn(newColumn); super.addColumn(newColumn);
return newColumn; return newColumn;
} }
...@@ -104,9 +103,9 @@ public class OldJTable extends JTable ...@@ -104,9 +103,9 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).addRow(rowData); ((DefaultTableModel)getModel()).addRow(rowData);
} }
public void addRow(Vector rowData) { public void addRow(List rowData) {
checkDefaultTableModel(); checkDefaultTableModel();
((DefaultTableModel)getModel()).addRow(rowData); ((DefaultTableModel)getModel()).addRow(rowData.toArray());
} }
public void removeRow(int rowIndex) { public void removeRow(int rowIndex) {
...@@ -124,9 +123,9 @@ public class OldJTable extends JTable ...@@ -124,9 +123,9 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).insertRow(rowIndex, rowData); ((DefaultTableModel)getModel()).insertRow(rowIndex, rowData);
} }
public void insertRow(int rowIndex, Vector rowData) { public void insertRow(int rowIndex, List rowData) {
checkDefaultTableModel(); checkDefaultTableModel();
((DefaultTableModel)getModel()).insertRow(rowIndex, rowData); ((DefaultTableModel)getModel()).insertRow(rowIndex, rowData.toArray());
} }
public void setNumRows(int newSize) { public void setNumRows(int newSize) {
...@@ -134,9 +133,10 @@ public class OldJTable extends JTable ...@@ -134,9 +133,10 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).setNumRows(newSize); ((DefaultTableModel)getModel()).setNumRows(newSize);
} }
public void setDataVector(Vector newData, Vector columnIds) { public void setDataVector(Object[][] newData, List columnIds) {
checkDefaultTableModel(); checkDefaultTableModel();
((DefaultTableModel)getModel()).setDataVector(newData, columnIds); ((DefaultTableModel)getModel()).setDataVector(
newData, columnIds.toArray());
} }
public void setDataVector(Object[][] newData, Object[] columnIds) { public void setDataVector(Object[][] newData, Object[] columnIds) {
...@@ -154,11 +154,11 @@ public class OldJTable extends JTable ...@@ -154,11 +154,11 @@ public class OldJTable extends JTable
// //
public Object getValueAt(Object columnIdentifier, int rowIndex) { public Object getValueAt(Object columnIdentifier, int rowIndex) {
return super.getValueAt(rowIndex, getColumnIndex(columnIdentifier)); return super.getValueAt(rowIndex, getColumnIndex(columnIdentifier));
} }
public boolean isCellEditable(Object columnIdentifier, int rowIndex) { public boolean isCellEditable(Object columnIdentifier, int rowIndex) {
return super.isCellEditable(rowIndex, getColumnIndex(columnIdentifier)); return super.isCellEditable(rowIndex, getColumnIndex(columnIdentifier));
} }
public void setValueAt(Object aValue, Object columnIdentifier, int rowIndex) { public void setValueAt(Object aValue, Object columnIdentifier, int rowIndex) {
...@@ -217,7 +217,8 @@ public class OldJTable extends JTable ...@@ -217,7 +217,8 @@ public class OldJTable extends JTable
public TableColumn addColumn(int modelColumn, int width, public TableColumn addColumn(int modelColumn, int width,
TableCellRenderer renderer, TableCellRenderer renderer,
TableCellEditor editor) { TableCellEditor editor) {
TableColumn newColumn = new TableColumn(modelColumn, width, renderer, editor); TableColumn newColumn = new TableColumn(
modelColumn, width, renderer, editor);
addColumn(newColumn); addColumn(newColumn);
return newColumn; return newColumn;
} }
......
/* /*
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
/** /**
* A a UI around the JDBCAdaptor, allowing database data to be interactively * A a UI around the JDBCAdaptor, allowing database data to be interactively
...@@ -41,41 +39,56 @@ ...@@ -41,41 +39,56 @@
* *
* @author Philip Milne * @author Philip Milne
*/ */
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.BevelBorder;
public final class TableExample implements LayoutManager {
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.border.*;
public class TableExample implements LayoutManager {
static String[] ConnectOptionNames = { "Connect" }; static String[] ConnectOptionNames = { "Connect" };
static String ConnectTitle = "Connection Information"; static String ConnectTitle = "Connection Information";
Dimension origin = new Dimension(0, 0);
Dimension origin = new Dimension(0, 0); JButton fetchButton;
JButton showConnectionInfoButton;
JButton fetchButton; JPanel connectionPanel;
JButton showConnectionInfoButton; JFrame frame; // The query/results window.
JLabel userNameLabel;
JPanel connectionPanel; JTextField userNameField;
JFrame frame; // The query/results window. JLabel passwordLabel;
JTextField passwordField;
JLabel userNameLabel;
JTextField userNameField;
JLabel passwordLabel;
JTextField passwordField;
// JLabel queryLabel; // JLabel queryLabel;
JTextArea queryTextArea; JTextArea queryTextArea;
JComponent queryAggregate; JComponent queryAggregate;
JLabel serverLabel; JLabel serverLabel;
JTextField serverField; JTextField serverField;
JLabel driverLabel; JLabel driverLabel;
JTextField driverField; JTextField driverField;
JPanel mainPanel;
JPanel mainPanel;
TableSorter sorter; TableSorter sorter;
JDBCAdapter dataBase; JDBCAdapter dataBase;
JScrollPane tableAggregate; JScrollPane tableAggregate;
...@@ -85,14 +98,15 @@ public class TableExample implements LayoutManager { ...@@ -85,14 +98,15 @@ public class TableExample implements LayoutManager {
* If the user clicks on the 'Connect' button the connection is reset. * If the user clicks on the 'Connect' button the connection is reset.
*/ */
void activateConnectionDialog() { void activateConnectionDialog() {
if(JOptionPane.showOptionDialog(tableAggregate, connectionPanel, ConnectTitle, if (JOptionPane.showOptionDialog(tableAggregate, connectionPanel,
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, ConnectTitle,
null, ConnectOptionNames, ConnectOptionNames[0]) == 0) { JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, ConnectOptionNames, ConnectOptionNames[0]) == 0) {
connect(); connect();
frame.setVisible(true); frame.setVisible(true);
} } else if (!frame.isVisible()) {
else if(!frame.isVisible())
System.exit(0); System.exit(0);
}
} }
/** /**
...@@ -102,21 +116,21 @@ public class TableExample implements LayoutManager { ...@@ -102,21 +116,21 @@ public class TableExample implements LayoutManager {
public void createConnectionDialog() { public void createConnectionDialog() {
// Create the labels and text fields. // Create the labels and text fields.
userNameLabel = new JLabel("User name: ", JLabel.RIGHT); userNameLabel = new JLabel("User name: ", JLabel.RIGHT);
userNameField = new JTextField("guest"); userNameField = new JTextField("app");
passwordLabel = new JLabel("Password: ", JLabel.RIGHT); passwordLabel = new JLabel("Password: ", JLabel.RIGHT);
passwordField = new JTextField("trustworthy"); passwordField = new JTextField("app");
serverLabel = new JLabel("Database URL: ", JLabel.RIGHT); serverLabel = new JLabel("Database URL: ", JLabel.RIGHT);
serverField = new JTextField("jdbc:sybase://dbtest:1455/pubs2"); serverField = new JTextField("jdbc:derby://localhost:1527/sample");
driverLabel = new JLabel("Driver: ", JLabel.RIGHT); driverLabel = new JLabel("Driver: ", JLabel.RIGHT);
driverField = new JTextField("connect.sybase.SybaseDriver"); driverField = new JTextField("org.apache.derby.jdbc.ClientDriver");
connectionPanel = new JPanel(false); connectionPanel = new JPanel(false);
connectionPanel.setLayout(new BoxLayout(connectionPanel, connectionPanel.setLayout(new BoxLayout(connectionPanel,
BoxLayout.X_AXIS)); BoxLayout.X_AXIS));
JPanel namePanel = new JPanel(false); JPanel namePanel = new JPanel(false);
namePanel.setLayout(new GridLayout(0, 1)); namePanel.setLayout(new GridLayout(0, 1));
...@@ -145,22 +159,22 @@ public class TableExample implements LayoutManager { ...@@ -145,22 +159,22 @@ public class TableExample implements LayoutManager {
// Create the buttons. // Create the buttons.
showConnectionInfoButton = new JButton("Configuration"); showConnectionInfoButton = new JButton("Configuration");
showConnectionInfoButton.addActionListener(new ActionListener() { showConnectionInfoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
activateConnectionDialog(); public void actionPerformed(ActionEvent e) {
} activateConnectionDialog();
} }
); });
fetchButton = new JButton("Fetch"); fetchButton = new JButton("Fetch");
fetchButton.addActionListener(new ActionListener() { fetchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fetch(); public void actionPerformed(ActionEvent e) {
} fetch();
} }
); });
// Create the query text area and label. // Create the query text area and label.
queryTextArea = new JTextArea("SELECT * FROM titles", 25, 25); queryTextArea = new JTextArea("SELECT * FROM APP.CUSTOMER", 25, 25);
queryAggregate = new JScrollPane(queryTextArea); queryAggregate = new JScrollPane(queryTextArea);
queryAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED)); queryAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));
...@@ -178,7 +192,12 @@ public class TableExample implements LayoutManager { ...@@ -178,7 +192,12 @@ public class TableExample implements LayoutManager {
// Create a Frame and put the main panel in it. // Create a Frame and put the main panel in it.
frame = new JFrame("TableExample"); frame = new JFrame("TableExample");
frame.addWindowListener(new WindowAdapter() { frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setBackground(Color.lightGray); frame.setBackground(Color.lightGray);
frame.getContentPane().add(mainPanel); frame.getContentPane().add(mainPanel);
frame.pack(); frame.pack();
...@@ -189,13 +208,13 @@ public class TableExample implements LayoutManager { ...@@ -189,13 +208,13 @@ public class TableExample implements LayoutManager {
} }
public void connect() { public void connect() {
dataBase = new JDBCAdapter( dataBase = new JDBCAdapter(
serverField.getText(), serverField.getText(),
driverField.getText(), driverField.getText(),
userNameField.getText(), userNameField.getText(),
passwordField.getText()); passwordField.getText());
sorter.setModel(dataBase); sorter.setModel(dataBase);
} }
public void fetch() { public void fetch() {
dataBase.executeQuery(queryTextArea.getText()); dataBase.executeQuery(queryTextArea.getText());
...@@ -221,25 +240,48 @@ public class TableExample implements LayoutManager { ...@@ -221,25 +240,48 @@ public class TableExample implements LayoutManager {
} }
public static void main(String s[]) { public static void main(String s[]) {
// Trying to set Nimbus look and feel
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
Logger.getLogger(TableExample.class.getName()).log(Level.SEVERE,
"Failed to apply Nimbus look and feel", ex);
}
new TableExample(); new TableExample();
} }
public Dimension preferredLayoutSize(Container c){return origin;} public Dimension preferredLayoutSize(Container c) {
public Dimension minimumLayoutSize(Container c){return origin;} return origin;
public void addLayoutComponent(String s, Component c) {} }
public void removeLayoutComponent(Component c) {}
public Dimension minimumLayoutSize(Container c) {
return origin;
}
public void addLayoutComponent(String s, Component c) {
}
public void removeLayoutComponent(Component c) {
}
public void layoutContainer(Container c) { public void layoutContainer(Container c) {
Rectangle b = c.getBounds(); Rectangle b = c.getBounds();
int topHeight = 90; int topHeight = 90;
int inset = 4; int inset = 4;
showConnectionInfoButton.setBounds(b.width-2*inset-120, inset, 120, 25); showConnectionInfoButton.setBounds(b.width - 2 * inset - 120, inset, 120,
fetchButton.setBounds(b.width-2*inset-120, 60, 120, 25); 25);
fetchButton.setBounds(b.width - 2 * inset - 120, 60, 120, 25);
// queryLabel.setBounds(10, 10, 100, 25); // queryLabel.setBounds(10, 10, 100, 25);
queryAggregate.setBounds(inset, inset, b.width-2*inset - 150, 80); queryAggregate.setBounds(inset, inset, b.width - 2 * inset - 150, 80);
tableAggregate.setBounds(new Rectangle(inset, tableAggregate.setBounds(new Rectangle(inset,
inset + topHeight, inset + topHeight,
b.width-2*inset, b.width - 2 * inset,
b.height-2*inset - topHeight)); b.height - 2 * inset - topHeight));
} }
} }
/* /*
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,28 +29,36 @@ ...@@ -29,28 +29,36 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
/** /**
* A minimal example, using the JTable to view data from a database. * A minimal example, using the JTable to view data from a database.
* *
* @author Philip Milne * @author Philip Milne
*/ */
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Dimension;
public class TableExample2 { public class TableExample2 {
public TableExample2(String URL, String driver, String user, public TableExample2(String URL, String driver, String user,
String passwd, String query) { String passwd, String query) {
JFrame frame = new JFrame("Table"); JFrame frame = new JFrame("Table");
frame.addWindowListener(new WindowAdapter() { frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JDBCAdapter dt = new JDBCAdapter(URL, driver, user, passwd); JDBCAdapter dt = new JDBCAdapter(URL, driver, user, passwd);
dt.executeQuery(query); dt.executeQuery(query);
...@@ -68,9 +76,26 @@ public class TableExample2 { ...@@ -68,9 +76,26 @@ public class TableExample2 {
public static void main(String[] args) { public static void main(String[] args) {
if (args.length != 5) { if (args.length != 5) {
System.err.println("Needs database parameters eg. ..."); System.err.println("Needs database parameters eg. ...");
System.err.println("java TableExample2 \"jdbc:sybase://dbtest:1455/pubs2\" \"connect.sybase.SybaseDriver\" guest trustworthy \"select * from titles\""); System.err.println(
"java TableExample2 \"jdbc:derby://localhost:1527/sample\" "
+ "org.apache.derby.jdbc.ClientDriver app app "
+ "\"select * from app.customer\"");
return; return;
} }
// Trying to set Nimbus look and feel
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
Logger.getLogger(TableExample2.class.getName()).log(Level.SEVERE,
"Failed to apply Nimbus look and feel", ex);
}
new TableExample2(args[0], args[1], args[2], args[3], args[4]); new TableExample2(args[0], args[1], args[2], args[3], args[4]);
} }
} }
/* /*
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,16 +29,6 @@ ...@@ -29,16 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
/**
* An example showing the JTable with a dataModel that is not derived
* from a database. We add the optional TableSorter object to give the
* JTable the ability to sort.
*
* @author Philip Milne
*/
import javax.swing.*; import javax.swing.*;
import javax.swing.table.*; import javax.swing.table.*;
...@@ -46,63 +36,104 @@ import javax.swing.table.*; ...@@ -46,63 +36,104 @@ import javax.swing.table.*;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager.LookAndFeelInfo;
/**
* An example showing the JTable with a dataModel that is not derived
* from a database. We add the optional TableSorter object to give the
* JTable the ability to sort.
*
* @author Philip Milne
*/
public class TableExample3 { public class TableExample3 {
public TableExample3() { public TableExample3() {
JFrame frame = new JFrame("Table"); JFrame frame = new JFrame("Table");
frame.addWindowListener(new WindowAdapter() { frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Take the dummy data from SwingSet. // Take the dummy data from SwingSet.
final String[] names = {"First Name", "Last Name", "Favorite Color", final String[] names = { "First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian"}; "Favorite Number", "Vegetarian" };
final Object[][] data = { final Object[][] data = {
{"Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE}, { "Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE },
{"Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE}, { "Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE },
{"Alan", "Chung", "Green", new Integer(838), Boolean.FALSE}, { "Alan", "Chung", "Green", new Integer(838), Boolean.FALSE },
{"Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE}, { "Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE },
{"Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE}, { "Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE },
{"Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE}, { "Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE },
{"James", "Gosling", "Pink", new Integer(21), Boolean.FALSE}, { "James", "Gosling", "Pink", new Integer(21), Boolean.FALSE },
{"David", "Karlton", "Red", new Integer(1), Boolean.FALSE}, { "David", "Karlton", "Red", new Integer(1), Boolean.FALSE },
{"Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE}, { "Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE },
{"Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE}, { "Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE },
{"Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE}, { "Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE },
{"Dave", "Moore", "Green", new Integer(88), Boolean.FALSE}, { "Dave", "Moore", "Green", new Integer(88), Boolean.FALSE },
{"Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE}, { "Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE },
{"Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE}, { "Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE },
{"Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE}, { "Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE },
{"Chester", "Rose", "Black", new Integer(0), Boolean.FALSE}, { "Chester", "Rose", "Black", new Integer(0), Boolean.FALSE },
{"Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE}, { "Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE },
{"Georges", "Saab", "Red", new Integer(4), Boolean.FALSE}, { "Georges", "Saab", "Red", new Integer(4), Boolean.FALSE },
{"Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE}, { "Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE },
{"Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE}, { "Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE },
{"Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE} { "Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE }
}; };
// Create a model of the data. // Create a model of the data.
@SuppressWarnings("serial")
TableModel dataModel = new AbstractTableModel() { TableModel dataModel = new AbstractTableModel() {
// These methods always need to be implemented. // These methods always need to be implemented.
public int getColumnCount() { return names.length; }
public int getRowCount() { return data.length;} public int getColumnCount() {
public Object getValueAt(int row, int col) {return data[row][col];} return names.length;
}
public int getRowCount() {
return data.length;
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
// The default implementations of these methods in // The default implementations of these methods in
// AbstractTableModel would work, but we can refine them. // AbstractTableModel would work, but we can refine them.
public String getColumnName(int column) {return names[column];} @Override
public Class getColumnClass(int col) {return getValueAt(0,col).getClass();} public String getColumnName(int column) {
public boolean isCellEditable(int row, int col) {return (col==4);} return names[column];
}
@Override
public Class getColumnClass(int col) {
return getValueAt(0, col).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return (col == 4);
}
@Override
public void setValueAt(Object aValue, int row, int column) { public void setValueAt(Object aValue, int row, int column) {
data[row][column] = aValue; data[row][column] = aValue;
} }
}; };
// Instead of making the table display the data as it would normally with: // Instead of making the table display the data as it would normally
// with:
// JTable tableView = new JTable(dataModel); // JTable tableView = new JTable(dataModel);
// Add a sorter, by using the following three lines instead of the one above. // Add a sorter, by using the following three lines instead of the one
TableSorter sorter = new TableSorter(dataModel); // above.
JTable tableView = new JTable(sorter); TableSorter sorter = new TableSorter(dataModel);
JTable tableView = new JTable(sorter);
sorter.addMouseListenerToHeaderInTable(tableView); sorter.addMouseListenerToHeaderInTable(tableView);
JScrollPane scrollpane = new JScrollPane(tableView); JScrollPane scrollpane = new JScrollPane(tableView);
...@@ -114,6 +145,18 @@ public class TableExample3 { ...@@ -114,6 +145,18 @@ public class TableExample3 {
} }
public static void main(String[] args) { public static void main(String[] args) {
// Trying to set Nimbus look and feel
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
Logger.getLogger(TableExample3.class.getName()).log(Level.SEVERE,
"Failed to apply Nimbus look and feel", ex);
}
new TableExample3(); new TableExample3();
} }
} }
/* /*
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,83 +29,112 @@ ...@@ -29,83 +29,112 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
/**
* Another JTable example, showing how column attributes can be refined
* even when columns have been created automatically. Here we create some
* specialised renderers and editors as well as changing widths and colors
* for some of the columns in the SwingSet demo table.
*
* @author Philip Milne
*/
import javax.swing.*; import javax.swing.*;
import javax.swing.table.*; import javax.swing.table.*;
import javax.swing.border.*; import javax.swing.border.*;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.Color; import java.awt.Color;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager.LookAndFeelInfo;
/**
* Another JTable example, showing how column attributes can be refined
* even when columns have been created automatically. Here we create some
* specialised renderers and editors as well as changing widths and colors
* for some of the columns in the SwingSet demo table.
*
* @author Philip Milne
*/
public class TableExample4 { public class TableExample4 {
public TableExample4() { public TableExample4() {
JFrame frame = new JFrame("Table"); JFrame frame = new JFrame("Table");
frame.addWindowListener(new WindowAdapter() { frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Take the dummy data from SwingSet. // Take the dummy data from SwingSet.
final String[] names = {"First Name", "Last Name", "Favorite Color", final String[] names = { "First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian"}; "Favorite Number", "Vegetarian" };
final Object[][] data = { final Object[][] data = {
{"Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE}, { "Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE },
{"Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE}, { "Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE },
{"Alan", "Chung", "Green", new Integer(838), Boolean.FALSE}, { "Alan", "Chung", "Green", new Integer(838), Boolean.FALSE },
{"Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE}, { "Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE },
{"Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE}, { "Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE },
{"Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE}, { "Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE },
{"James", "Gosling", "Pink", new Integer(21), Boolean.FALSE}, { "James", "Gosling", "Pink", new Integer(21), Boolean.FALSE },
{"David", "Karlton", "Red", new Integer(1), Boolean.FALSE}, { "David", "Karlton", "Red", new Integer(1), Boolean.FALSE },
{"Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE}, { "Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE },
{"Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE}, { "Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE },
{"Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE}, { "Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE },
{"Dave", "Moore", "Green", new Integer(88), Boolean.FALSE}, { "Dave", "Moore", "Green", new Integer(88), Boolean.FALSE },
{"Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE}, { "Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE },
{"Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE}, { "Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE },
{"Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE}, { "Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE },
{"Chester", "Rose", "Black", new Integer(0), Boolean.FALSE}, { "Chester", "Rose", "Black", new Integer(0), Boolean.FALSE },
{"Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE}, { "Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE },
{"Georges", "Saab", "Red", new Integer(4), Boolean.FALSE}, { "Georges", "Saab", "Red", new Integer(4), Boolean.FALSE },
{"Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE}, { "Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE },
{"Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE}, { "Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE },
{"Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE} { "Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE }
}; };
// Create a model of the data. // Create a model of the data.
@SuppressWarnings("serial")
TableModel dataModel = new AbstractTableModel() { TableModel dataModel = new AbstractTableModel() {
// These methods always need to be implemented. // These methods always need to be implemented.
public int getColumnCount() { return names.length; }
public int getRowCount() { return data.length;} public int getColumnCount() {
public Object getValueAt(int row, int col) {return data[row][col];} return names.length;
}
public int getRowCount() {
return data.length;
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
// The default implementations of these methods in // The default implementations of these methods in
// AbstractTableModel would work, but we can refine them. // AbstractTableModel would work, but we can refine them.
public String getColumnName(int column) {return names[column];} @Override
public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} public String getColumnName(int column) {
public boolean isCellEditable(int row, int col) {return true;} return names[column];
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object aValue, int row, int column) { public void setValueAt(Object aValue, int row, int column) {
System.out.println("Setting value to: " + aValue); System.out.println("Setting value to: " + aValue);
data[row][column] = aValue; data[row][column] = aValue;
} }
}; };
// Create the table // Create the table
JTable tableView = new JTable(dataModel); JTable tableView = new JTable(dataModel);
// Turn off auto-resizing so that we can set column sizes programmatically. // Turn off auto-resizing so that we can set column sizes
// In this mode, all columns will get their preferred widths, as set blow. // programmatically. In this mode, all columns will get their preferred
// widths, as set blow.
tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Create a combo box to show that you can use one in a table. // Create a combo box to show that you can use one in a table.
...@@ -123,15 +152,18 @@ public class TableExample4 { ...@@ -123,15 +152,18 @@ public class TableExample4 {
colorColumn.setCellEditor(new DefaultCellEditor(comboBox)); colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
// Set a pink background and tooltip for the Color column renderer. // Set a pink background and tooltip for the Color column renderer.
DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer(); DefaultTableCellRenderer colorColumnRenderer =
new DefaultTableCellRenderer();
colorColumnRenderer.setBackground(Color.pink); colorColumnRenderer.setBackground(Color.pink);
colorColumnRenderer.setToolTipText("Click for combo box"); colorColumnRenderer.setToolTipText("Click for combo box");
colorColumn.setCellRenderer(colorColumnRenderer); colorColumn.setCellRenderer(colorColumnRenderer);
// Set a tooltip for the header of the colors column. // Set a tooltip for the header of the colors column.
TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer(); TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
if (headerRenderer instanceof DefaultTableCellRenderer) if (headerRenderer instanceof DefaultTableCellRenderer) {
((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!"); ((DefaultTableCellRenderer) headerRenderer).setToolTipText(
"Hi Mom!");
}
// Set the width of the "Vegetarian" column. // Set the width of the "Vegetarian" column.
TableColumn vegetarianColumn = tableView.getColumn("Vegetarian"); TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
...@@ -139,9 +171,14 @@ public class TableExample4 { ...@@ -139,9 +171,14 @@ public class TableExample4 {
// Show the values in the "Favorite Number" column in different colors. // Show the values in the "Favorite Number" column in different colors.
TableColumn numbersColumn = tableView.getColumn("Favorite Number"); TableColumn numbersColumn = tableView.getColumn("Favorite Number");
DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() { @SuppressWarnings("serial")
DefaultTableCellRenderer numberColumnRenderer
= new DefaultTableCellRenderer() {
@Override
public void setValue(Object value) { public void setValue(Object value) {
int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0; int cellValue = (value instanceof Number) ? ((Number) value).
intValue() : 0;
setForeground((cellValue > 30) ? Color.black : Color.red); setForeground((cellValue > 30) ? Color.black : Color.red);
setText((value == null) ? "" : value.toString()); setText((value == null) ? "" : value.toString());
} }
...@@ -160,6 +197,19 @@ public class TableExample4 { ...@@ -160,6 +197,19 @@ public class TableExample4 {
} }
public static void main(String[] args) { public static void main(String[] args) {
// Trying to set Nimbus look and feel
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
Logger.getLogger(TableExample4.class.getName()).log(Level.SEVERE,
"Failed to apply Nimbus look and feel", ex);
}
new TableExample4(); new TableExample4();
} }
} }
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
/** /**
* In a chain of data manipulators some behaviour is common. TableMap * In a chain of data manipulators some behaviour is common. TableMap
...@@ -41,32 +39,34 @@ ...@@ -41,32 +39,34 @@
* a TableMap which has not been subclassed into a chain of table filters * a TableMap which has not been subclassed into a chain of table filters
* should have no effect. * should have no effect.
* *
* @author Philip Milne */ * @author Philip Milne
*/
import javax.swing.table.*; import javax.swing.table.*;
import javax.swing.event.TableModelListener; import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelEvent;
public class TableMap extends AbstractTableModel implements TableModelListener
{ @SuppressWarnings("serial")
public class TableMap extends AbstractTableModel implements TableModelListener {
protected TableModel model; protected TableModel model;
public TableModel getModel() { public TableModel getModel() {
return model; return model;
} }
public void setModel(TableModel model) { public void setModel(TableModel model) {
this.model = model; this.model = model;
model.addTableModelListener(this); model.addTableModelListener(this);
} }
// By default, Implement TableModel by forwarding all messages // By default, Implement TableModel by forwarding all messages
// to the model. // to the model.
public Object getValueAt(int aRow, int aColumn) { public Object getValueAt(int aRow, int aColumn) {
return model.getValueAt(aRow, aColumn); return model.getValueAt(aRow, aColumn);
} }
@Override
public void setValueAt(Object aValue, int aRow, int aColumn) { public void setValueAt(Object aValue, int aRow, int aColumn) {
model.setValueAt(aValue, aRow, aColumn); model.setValueAt(aValue, aRow, aColumn);
} }
...@@ -79,16 +79,19 @@ public class TableMap extends AbstractTableModel implements TableModelListener ...@@ -79,16 +79,19 @@ public class TableMap extends AbstractTableModel implements TableModelListener
return (model == null) ? 0 : model.getColumnCount(); return (model == null) ? 0 : model.getColumnCount();
} }
@Override
public String getColumnName(int aColumn) { public String getColumnName(int aColumn) {
return model.getColumnName(aColumn); return model.getColumnName(aColumn);
} }
@Override
public Class getColumnClass(int aColumn) { public Class getColumnClass(int aColumn) {
return model.getColumnClass(aColumn); return model.getColumnClass(aColumn);
} }
@Override
public boolean isCellEditable(int row, int column) { public boolean isCellEditable(int row, int column) {
return model.isCellEditable(row, column); return model.isCellEditable(row, column);
} }
// //
// Implementation of the TableModelListener interface, // Implementation of the TableModelListener interface,
......
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,8 +29,19 @@ ...@@ -29,8 +29,19 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/ import javax.swing.table.TableModel;
import javax.swing.event.TableModelEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
/** /**
* A sorter for TableModels. The sorter has a model (conforming to TableModel) * A sorter for TableModels. The sorter has a model (conforming to TableModel)
...@@ -48,46 +59,29 @@ ...@@ -48,46 +59,29 @@
* *
* @author Philip Milne * @author Philip Milne
*/ */
@SuppressWarnings("serial")
public final class TableSorter extends TableMap {
import java.util.*; int indexes[];
List<Integer> sortingColumns = new ArrayList<Integer>();
import javax.swing.table.TableModel; boolean ascending = true;
import javax.swing.event.TableModelEvent;
// Imports for picking up mouse events from the JTable.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class TableSorter extends TableMap
{
int indexes[];
Vector sortingColumns = new Vector();
boolean ascending = true;
int compares; int compares;
public TableSorter() public TableSorter() {
{
indexes = new int[0]; // For consistency. indexes = new int[0]; // For consistency.
} }
public TableSorter(TableModel model) public TableSorter(TableModel model) {
{
setModel(model); setModel(model);
} }
@Override
public void setModel(TableModel model) { public void setModel(TableModel model) {
super.setModel(model); super.setModel(model);
reallocateIndexes(); reallocateIndexes();
} }
public int compareRowsByColumn(int row1, int row2, int column) public int compareRowsByColumn(int row1, int row2, int column) {
{
Class type = model.getColumnClass(column); Class type = model.getColumnClass(column);
TableModel data = model; TableModel data = model;
...@@ -99,104 +93,100 @@ public class TableSorter extends TableMap ...@@ -99,104 +93,100 @@ public class TableSorter extends TableMap
// If both values are null return 0 // If both values are null return 0
if (o1 == null && o2 == null) { if (o1 == null && o2 == null) {
return 0; return 0;
} } else if (o1 == null) { // Define null less than everything.
else if (o1 == null) { // Define null less than everything.
return -1; return -1;
} } else if (o2 == null) {
else if (o2 == null) {
return 1; return 1;
} }
/* We copy all returned values from the getValue call in case /* We copy all returned values from the getValue call in case
an optimised model is reusing one object to return many values. an optimised model is reusing one object to return many values.
The Number subclasses in the JDK are immutable and so will not be used in The Number subclasses in the JDK are immutable and so will not be used
this way but other subclasses of Number might want to do this to save in this way but other subclasses of Number might want to do this to save
space and avoid unnecessary heap allocation. space and avoid unnecessary heap allocation.
*/ */
if (type.getSuperclass() == java.lang.Number.class) if (type.getSuperclass() == java.lang.Number.class) {
{ Number n1 = (Number) data.getValueAt(row1, column);
Number n1 = (Number)data.getValueAt(row1, column); double d1 = n1.doubleValue();
double d1 = n1.doubleValue(); Number n2 = (Number) data.getValueAt(row2, column);
Number n2 = (Number)data.getValueAt(row2, column); double d2 = n2.doubleValue();
double d2 = n2.doubleValue();
if (d1 < d2) {
if (d1 < d2) return -1;
return -1; } else if (d1 > d2) {
else if (d1 > d2) return 1;
return 1; } else {
else return 0;
return 0;
} }
else if (type == java.util.Date.class) } else if (type == java.util.Date.class) {
{ Date d1 = (Date) data.getValueAt(row1, column);
Date d1 = (Date)data.getValueAt(row1, column); long n1 = d1.getTime();
long n1 = d1.getTime(); Date d2 = (Date) data.getValueAt(row2, column);
Date d2 = (Date)data.getValueAt(row2, column); long n2 = d2.getTime();
long n2 = d2.getTime();
if (n1 < n2) {
if (n1 < n2) return -1;
return -1; } else if (n1 > n2) {
else if (n1 > n2) return 1;
return 1; } else {
else return 0; return 0;
} }
else if (type == String.class) } else if (type == String.class) {
{ String s1 = (String) data.getValueAt(row1, column);
String s1 = (String)data.getValueAt(row1, column); String s2 = (String) data.getValueAt(row2, column);
String s2 = (String)data.getValueAt(row2, column); int result = s1.compareTo(s2);
int result = s1.compareTo(s2);
if (result < 0) {
if (result < 0) return -1;
return -1; } else if (result > 0) {
else if (result > 0) return 1;
return 1; } else {
else return 0; return 0;
} }
else if (type == Boolean.class) } else if (type == Boolean.class) {
Boolean bool1 = (Boolean) data.getValueAt(row1, column);
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean) data.getValueAt(row2, column);
boolean b2 = bool2.booleanValue();
if (b1 == b2) {
return 0;
} else if (b1) // Define false < true
{ {
Boolean bool1 = (Boolean)data.getValueAt(row1, column); return 1;
boolean b1 = bool1.booleanValue(); } else {
Boolean bool2 = (Boolean)data.getValueAt(row2, column); return -1;
boolean b2 = bool2.booleanValue();
if (b1 == b2)
return 0;
else if (b1) // Define false < true
return 1;
else
return -1;
} }
else } else {
{ Object v1 = data.getValueAt(row1, column);
Object v1 = data.getValueAt(row1, column); String s1 = v1.toString();
String s1 = v1.toString(); Object v2 = data.getValueAt(row2, column);
Object v2 = data.getValueAt(row2, column); String s2 = v2.toString();
String s2 = v2.toString(); int result = s1.compareTo(s2);
int result = s1.compareTo(s2);
if (result < 0) {
if (result < 0) return -1;
return -1; } else if (result > 0) {
else if (result > 0) return 1;
return 1; } else {
else return 0; return 0;
} }
}
} }
public int compare(int row1, int row2) public int compare(int row1, int row2) {
{
compares++; compares++;
for(int level = 0; level < sortingColumns.size(); level++) for (int level = 0; level < sortingColumns.size(); level++) {
{ Integer column = sortingColumns.get(level);
Integer column = (Integer)sortingColumns.elementAt(level); int result = compareRowsByColumn(row1, row2, column.intValue());
int result = compareRowsByColumn(row1, row2, column.intValue()); if (result != 0) {
if (result != 0) return ascending ? result : -result;
return ascending ? result : -result;
} }
}
return 0; return 0;
} }
public void reallocateIndexes() public void reallocateIndexes() {
{
int rowCount = model.getRowCount(); int rowCount = model.getRowCount();
// Set up a new array of indexes with the right number of elements // Set up a new array of indexes with the right number of elements
...@@ -204,39 +194,38 @@ space and avoid unnecessary heap allocation. ...@@ -204,39 +194,38 @@ space and avoid unnecessary heap allocation.
indexes = new int[rowCount]; indexes = new int[rowCount];
// Initialise with the identity mapping. // Initialise with the identity mapping.
for(int row = 0; row < rowCount; row++) for (int row = 0; row < rowCount; row++) {
indexes[row] = row; indexes[row] = row;
}
} }
public void tableChanged(TableModelEvent e) @Override
{ public void tableChanged(TableModelEvent e) {
System.out.println("Sorter: tableChanged"); System.out.println("Sorter: tableChanged");
reallocateIndexes(); reallocateIndexes();
super.tableChanged(e); super.tableChanged(e);
} }
public void checkModel() public void checkModel() {
{
if (indexes.length != model.getRowCount()) { if (indexes.length != model.getRowCount()) {
System.err.println("Sorter not informed of a change in model."); System.err.println("Sorter not informed of a change in model.");
} }
} }
public void sort(Object sender) public void sort(Object sender) {
{
checkModel(); checkModel();
compares = 0; compares = 0;
// n2sort(); // n2sort();
// qsort(0, indexes.length-1); // qsort(0, indexes.length-1);
shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length); shuttlesort(indexes.clone(), indexes, 0, indexes.length);
System.out.println("Compares: "+compares); System.out.println("Compares: " + compares);
} }
public void n2sort() { public void n2sort() {
for(int i = 0; i < getRowCount(); i++) { for (int i = 0; i < getRowCount(); i++) {
for(int j = i+1; j < getRowCount(); j++) { for (int j = i + 1; j < getRowCount(); j++) {
if (compare(indexes[i], indexes[j]) == -1) { if (compare(indexes[i], indexes[j]) == -1) {
swap(i, j); swap(i, j);
} }
...@@ -255,7 +244,7 @@ space and avoid unnecessary heap allocation. ...@@ -255,7 +244,7 @@ space and avoid unnecessary heap allocation.
if (high - low < 2) { if (high - low < 2) {
return; return;
} }
int middle = (low + high)/2; int middle = (low + high) / 2;
shuttlesort(to, from, low, middle); shuttlesort(to, from, low, middle);
shuttlesort(to, from, middle, high); shuttlesort(to, from, middle, high);
...@@ -277,20 +266,17 @@ space and avoid unnecessary heap allocation. ...@@ -277,20 +266,17 @@ space and avoid unnecessary heap allocation.
find out how the performance drops to Nlog(N) as the initial find out how the performance drops to Nlog(N) as the initial
order diminishes - it may drop very quickly. */ order diminishes - it may drop very quickly. */
if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { if (high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
for (int i = low; i < high; i++) { System.arraycopy(from, low, to, low, high - low);
to[i] = from[i];
}
return; return;
} }
// A normal merge. // A normal merge.
for(int i = low; i < high; i++) { for (int i = low; i < high; i++) {
if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
to[i] = from[p++]; to[i] = from[p++];
} } else {
else {
to[i] = from[q++]; to[i] = from[q++];
} }
} }
...@@ -304,15 +290,14 @@ space and avoid unnecessary heap allocation. ...@@ -304,15 +290,14 @@ space and avoid unnecessary heap allocation.
// The mapping only affects the contents of the data rows. // The mapping only affects the contents of the data rows.
// Pass all requests to these rows through the mapping array: "indexes". // Pass all requests to these rows through the mapping array: "indexes".
@Override
public Object getValueAt(int aRow, int aColumn) public Object getValueAt(int aRow, int aColumn) {
{
checkModel(); checkModel();
return model.getValueAt(indexes[aRow], aColumn); return model.getValueAt(indexes[aRow], aColumn);
} }
public void setValueAt(Object aValue, int aRow, int aColumn) @Override
{ public void setValueAt(Object aValue, int aRow, int aColumn) {
checkModel(); checkModel();
model.setValueAt(aValue, indexes[aRow], aColumn); model.setValueAt(aValue, indexes[aRow], aColumn);
} }
...@@ -323,8 +308,8 @@ space and avoid unnecessary heap allocation. ...@@ -323,8 +308,8 @@ space and avoid unnecessary heap allocation.
public void sortByColumn(int column, boolean ascending) { public void sortByColumn(int column, boolean ascending) {
this.ascending = ascending; this.ascending = ascending;
sortingColumns.removeAllElements(); sortingColumns.clear();
sortingColumns.addElement(new Integer(column)); sortingColumns.add(column);
sort(this); sort(this);
super.tableChanged(new TableModelEvent(this)); super.tableChanged(new TableModelEvent(this));
} }
...@@ -337,22 +322,21 @@ space and avoid unnecessary heap allocation. ...@@ -337,22 +322,21 @@ space and avoid unnecessary heap allocation.
final JTable tableView = table; final JTable tableView = table;
tableView.setColumnSelectionAllowed(false); tableView.setColumnSelectionAllowed(false);
MouseAdapter listMouseListener = new MouseAdapter() { MouseAdapter listMouseListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
TableColumnModel columnModel = tableView.getColumnModel(); TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX()); int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel(viewColumn); int column = tableView.convertColumnIndexToModel(viewColumn);
if(e.getClickCount() == 1 && column != -1) { if (e.getClickCount() == 1 && column != -1) {
System.out.println("Sorting ..."); System.out.println("Sorting ...");
int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
boolean ascending = (shiftPressed == 0); boolean ascending = (shiftPressed == 0);
sorter.sortByColumn(column, ascending); sorter.sortByColumn(column, ascending);
} }
} }
}; };
JTableHeader th = tableView.getTableHeader(); JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener); th.addMouseListener(listMouseListener);
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册