提交 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
* modification, are permitted provided that the following conditions
......@@ -29,26 +29,32 @@
* 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.
*
* @author Philip Milne
*/
import java.util.Vector;
import java.sql.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.TableModelEvent;
@SuppressWarnings("serial")
public class JDBCAdapter extends AbstractTableModel {
Connection connection;
Statement statement;
ResultSet resultSet;
String[] columnNames = {};
Vector rows = new Vector();
List<List<Object>> rows = new ArrayList<List<Object>>();
ResultSetMetaData metaData;
public JDBCAdapter(String url, String driverName,
......@@ -59,12 +65,10 @@ public class JDBCAdapter extends AbstractTableModel {
connection = DriverManager.getConnection(url, user, passwd);
statement = connection.createStatement();
}
catch (ClassNotFoundException ex) {
} catch (ClassNotFoundException ex) {
System.err.println("Cannot find the database driver classes.");
System.err.println(ex);
}
catch (SQLException ex) {
} catch (SQLException ex) {
System.err.println("Cannot connect to this database.");
System.err.println(ex);
}
......@@ -83,23 +87,24 @@ public class JDBCAdapter extends AbstractTableModel {
columnNames = new String[numberOfColumns];
// Get the column names and cache them.
// Then we can close the connection.
for(int column = 0; column < numberOfColumns; column++) {
columnNames[column] = metaData.getColumnLabel(column+1);
for (int column = 0; column < numberOfColumns; column++) {
columnNames[column] = metaData.getColumnLabel(column + 1);
}
// Get all rows.
rows = new Vector();
rows = new ArrayList<List<Object>>();
while (resultSet.next()) {
Vector newRow = new Vector();
List<Object> newRow = new ArrayList<Object>();
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.
fireTableChanged(null); // Tell the listeners a new table has arrived.
}
catch (SQLException ex) {
// Tell the listeners a new table has arrived.
fireTableChanged(null);
} catch (SQLException ex) {
System.err.println(ex);
}
}
......@@ -111,6 +116,7 @@ public class JDBCAdapter extends AbstractTableModel {
connection.close();
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
......@@ -121,9 +127,8 @@ public class JDBCAdapter extends AbstractTableModel {
// Implementation of the TableModel Interface
//
//////////////////////////////////////////////////////////////////////////
// MetaData
@Override
public String getColumnName(int column) {
if (columnNames[column] != null) {
return columnNames[column];
......@@ -132,16 +137,16 @@ public class JDBCAdapter extends AbstractTableModel {
}
}
public Class getColumnClass(int column) {
@Override
public Class<?> getColumnClass(int column) {
int type;
try {
type = metaData.getColumnType(column+1);
}
catch (SQLException e) {
type = metaData.getColumnType(column + 1);
} catch (SQLException e) {
return super.getColumnClass(column);
}
switch(type) {
switch (type) {
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
......@@ -170,11 +175,11 @@ public class JDBCAdapter extends AbstractTableModel {
}
}
@Override
public boolean isCellEditable(int row, int column) {
try {
return metaData.isWritable(column+1);
}
catch (SQLException e) {
return metaData.isWritable(column + 1);
} catch (SQLException e) {
return false;
}
}
......@@ -184,14 +189,13 @@ public class JDBCAdapter extends AbstractTableModel {
}
// Data methods
public int getRowCount() {
return rows.size();
}
public Object getValueAt(int aRow, int aColumn) {
Vector row = (Vector)rows.elementAt(aRow);
return row.elementAt(aColumn);
List<Object> row = rows.get(aRow);
return row.get(aColumn);
}
public String dbRepresentation(int column, Object value) {
......@@ -202,43 +206,42 @@ public class JDBCAdapter extends AbstractTableModel {
}
try {
type = metaData.getColumnType(column+1);
}
catch (SQLException e) {
type = metaData.getColumnType(column + 1);
} catch (SQLException e) {
return value.toString();
}
switch(type) {
switch (type) {
case Types.INTEGER:
case Types.DOUBLE:
case Types.FLOAT:
return value.toString();
case Types.BIT:
return ((Boolean)value).booleanValue() ? "1" : "0";
return ((Boolean) value).booleanValue() ? "1" : "0";
case Types.DATE:
return value.toString(); // This will need some conversion.
default:
return "\""+value.toString()+"\"";
return "\"" + value.toString() + "\"";
}
}
@Override
public void setValueAt(Object value, int row, int column) {
try {
String tableName = metaData.getTableName(column+1);
String tableName = metaData.getTableName(column + 1);
// Some of the drivers seem buggy, tableName should not be null.
if (tableName == null) {
System.out.println("Table name returned null.");
}
String columnName = getColumnName(column);
String query =
"update "+tableName+
" set "+columnName+" = "+dbRepresentation(column, value)+
" where ";
"update " + tableName + " set " + columnName + " = "
+ dbRepresentation(column, value) + " where ";
// 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
// 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);
if (colName.equals("")) {
continue;
......@@ -246,19 +249,18 @@ public class JDBCAdapter extends AbstractTableModel {
if (col != 0) {
query = query + " and ";
}
query = query + colName +" = "+
dbRepresentation(col, getValueAt(row, col));
query = query + colName + " = " + dbRepresentation(col,
getValueAt(row, col));
}
System.out.println(query);
System.out.println("Not sending update to database");
// statement.executeQuery(query);
}
catch (SQLException e) {
} catch (SQLException e) {
// e.printStackTrace();
System.err.println("Update failed");
}
Vector dataRow = (Vector)rows.elementAt(row);
dataRow.setElementAt(value, column);
List<Object> dataRow = rows.get(row);
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
* modification, are permitted provided that the following conditions
......@@ -29,28 +29,26 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
import java.lang.Thread;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.table.*;
import java.util.EventObject;
import java.util.List;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
/**
* The OldJTable is an unsupported class containing some methods that were
* deleted from the JTable between releases 0.6 and 0.7
*/
@SuppressWarnings("serial")
public class OldJTable extends JTable
{
/*
* A new convenience method returning the index of the column in the co-ordinate
* space of the view.
* A new convenience method returning the index of the column in the
* co-ordinate space of the view.
*/
public int getColumnIndex(Object identifier) {
return getColumnModel().getColumnIndex(identifier);
......@@ -65,7 +63,7 @@ public class OldJTable extends JTable
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);
}
......@@ -79,16 +77,17 @@ public class OldJTable extends JTable
public TableColumn addColumn(Object columnIdentifier, int width,
TableCellRenderer renderer,
TableCellEditor editor, Vector columnData) {
TableCellEditor editor, List columnData) {
checkDefaultTableModel();
// Set up the model side first
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
// 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);
return newColumn;
}
......@@ -104,9 +103,9 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).addRow(rowData);
}
public void addRow(Vector rowData) {
public void addRow(List rowData) {
checkDefaultTableModel();
((DefaultTableModel)getModel()).addRow(rowData);
((DefaultTableModel)getModel()).addRow(rowData.toArray());
}
public void removeRow(int rowIndex) {
......@@ -124,9 +123,9 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).insertRow(rowIndex, rowData);
}
public void insertRow(int rowIndex, Vector rowData) {
public void insertRow(int rowIndex, List rowData) {
checkDefaultTableModel();
((DefaultTableModel)getModel()).insertRow(rowIndex, rowData);
((DefaultTableModel)getModel()).insertRow(rowIndex, rowData.toArray());
}
public void setNumRows(int newSize) {
......@@ -134,9 +133,10 @@ public class OldJTable extends JTable
((DefaultTableModel)getModel()).setNumRows(newSize);
}
public void setDataVector(Vector newData, Vector columnIds) {
public void setDataVector(Object[][] newData, List columnIds) {
checkDefaultTableModel();
((DefaultTableModel)getModel()).setDataVector(newData, columnIds);
((DefaultTableModel)getModel()).setDataVector(
newData, columnIds.toArray());
}
public void setDataVector(Object[][] newData, Object[] columnIds) {
......@@ -217,7 +217,8 @@ public class OldJTable extends JTable
public TableColumn addColumn(int modelColumn, int width,
TableCellRenderer renderer,
TableCellEditor editor) {
TableColumn newColumn = new TableColumn(modelColumn, width, renderer, editor);
TableColumn newColumn = new TableColumn(
modelColumn, width, renderer, editor);
addColumn(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
* modification, are permitted provided that the following conditions
......@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
/**
* A a UI around the JDBCAdaptor, allowing database data to be interactively
......@@ -41,27 +39,44 @@
*
* @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 ConnectTitle = "Connection Information";
Dimension origin = new Dimension(0, 0);
JButton fetchButton;
JButton showConnectionInfoButton;
JPanel connectionPanel;
JFrame frame; // The query/results window.
JLabel userNameLabel;
JTextField userNameField;
JLabel passwordLabel;
......@@ -73,9 +88,7 @@ public class TableExample implements LayoutManager {
JTextField serverField;
JLabel driverLabel;
JTextField driverField;
JPanel mainPanel;
TableSorter sorter;
JDBCAdapter dataBase;
JScrollPane tableAggregate;
......@@ -85,15 +98,16 @@ public class TableExample implements LayoutManager {
* If the user clicks on the 'Connect' button the connection is reset.
*/
void activateConnectionDialog() {
if(JOptionPane.showOptionDialog(tableAggregate, connectionPanel, ConnectTitle,
if (JOptionPane.showOptionDialog(tableAggregate, connectionPanel,
ConnectTitle,
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, ConnectOptionNames, ConnectOptionNames[0]) == 0) {
connect();
frame.setVisible(true);
}
else if(!frame.isVisible())
} else if (!frame.isVisible()) {
System.exit(0);
}
}
/**
* Creates the connectionPanel, which will contain all the fields for
......@@ -102,16 +116,16 @@ public class TableExample implements LayoutManager {
public void createConnectionDialog() {
// Create the labels and text fields.
userNameLabel = new JLabel("User name: ", JLabel.RIGHT);
userNameField = new JTextField("guest");
userNameField = new JTextField("app");
passwordLabel = new JLabel("Password: ", JLabel.RIGHT);
passwordField = new JTextField("trustworthy");
passwordField = new JTextField("app");
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);
driverField = new JTextField("connect.sybase.SybaseDriver");
driverField = new JTextField("org.apache.derby.jdbc.ClientDriver");
connectionPanel = new JPanel(false);
......@@ -145,22 +159,22 @@ public class TableExample implements LayoutManager {
// Create the buttons.
showConnectionInfoButton = new JButton("Configuration");
showConnectionInfoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
activateConnectionDialog();
}
}
);
});
fetchButton = new JButton("Fetch");
fetchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fetch();
}
}
);
});
// 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.setBorder(new BevelBorder(BevelBorder.LOWERED));
......@@ -178,7 +192,12 @@ public class TableExample implements LayoutManager {
// Create a Frame and put the main panel in it.
frame = new JFrame("TableExample");
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.getContentPane().add(mainPanel);
frame.pack();
......@@ -221,25 +240,48 @@ public class TableExample implements LayoutManager {
}
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();
}
public Dimension preferredLayoutSize(Container c){return origin;}
public Dimension minimumLayoutSize(Container c){return origin;}
public void addLayoutComponent(String s, Component c) {}
public void removeLayoutComponent(Component c) {}
public Dimension preferredLayoutSize(Container c) {
return origin;
}
public Dimension minimumLayoutSize(Container c) {
return origin;
}
public void addLayoutComponent(String s, Component c) {
}
public void removeLayoutComponent(Component c) {
}
public void layoutContainer(Container c) {
Rectangle b = c.getBounds();
int topHeight = 90;
int inset = 4;
showConnectionInfoButton.setBounds(b.width-2*inset-120, inset, 120, 25);
fetchButton.setBounds(b.width-2*inset-120, 60, 120, 25);
showConnectionInfoButton.setBounds(b.width - 2 * inset - 120, inset, 120,
25);
fetchButton.setBounds(b.width - 2 * inset - 120, 60, 120, 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,
inset + topHeight,
b.width-2*inset,
b.height-2*inset - topHeight));
b.width - 2 * inset,
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
* modification, are permitted provided that the following conditions
......@@ -29,28 +29,36 @@
* 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.
*
* @author Philip Milne
*/
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Dimension;
public class TableExample2 {
public TableExample2(String URL, String driver, String user,
String passwd, String query) {
JFrame frame = new JFrame("Table");
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);
dt.executeQuery(query);
......@@ -68,9 +76,26 @@ public class TableExample2 {
public static void main(String[] args) {
if (args.length != 5) {
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;
}
// 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]);
}
}
/*
* 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
* modification, are permitted provided that the following conditions
......@@ -29,16 +29,6 @@
* 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.table.*;
......@@ -46,61 +36,102 @@ import javax.swing.table.*;
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.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 TableExample3() {
JFrame frame = new JFrame("Table");
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.
final String[] names = {"First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian"};
final String[] names = { "First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian" };
final Object[][] data = {
{"Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE},
{"Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE},
{"Alan", "Chung", "Green", new Integer(838), Boolean.FALSE},
{"Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE},
{"Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE},
{"Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE},
{"James", "Gosling", "Pink", new Integer(21), Boolean.FALSE},
{"David", "Karlton", "Red", new Integer(1), Boolean.FALSE},
{"Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE},
{"Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE},
{"Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE},
{"Dave", "Moore", "Green", new Integer(88), Boolean.FALSE},
{"Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE},
{"Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE},
{"Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE},
{"Chester", "Rose", "Black", new Integer(0), Boolean.FALSE},
{"Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE},
{"Georges", "Saab", "Red", new Integer(4), Boolean.FALSE},
{"Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE},
{"Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE},
{"Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE}
{ "Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE },
{ "Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE },
{ "Alan", "Chung", "Green", new Integer(838), Boolean.FALSE },
{ "Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE },
{ "Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE },
{ "Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE },
{ "James", "Gosling", "Pink", new Integer(21), Boolean.FALSE },
{ "David", "Karlton", "Red", new Integer(1), Boolean.FALSE },
{ "Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE },
{ "Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE },
{ "Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE },
{ "Dave", "Moore", "Green", new Integer(88), Boolean.FALSE },
{ "Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE },
{ "Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE },
{ "Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE },
{ "Chester", "Rose", "Black", new Integer(0), Boolean.FALSE },
{ "Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE },
{ "Georges", "Saab", "Red", new Integer(4), Boolean.FALSE },
{ "Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE },
{ "Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE },
{ "Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE }
};
// Create a model of the data.
@SuppressWarnings("serial")
TableModel dataModel = new AbstractTableModel() {
// These methods always need to be implemented.
public int getColumnCount() { return names.length; }
public int getRowCount() { return data.length;}
public Object getValueAt(int row, int col) {return data[row][col];}
public int getColumnCount() {
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
// AbstractTableModel would work, but we can refine them.
public String getColumnName(int column) {return names[column];}
public Class getColumnClass(int col) {return getValueAt(0,col).getClass();}
public boolean isCellEditable(int row, int col) {return (col==4);}
@Override
public String getColumnName(int column) {
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) {
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);
// 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
// above.
TableSorter sorter = new TableSorter(dataModel);
JTable tableView = new JTable(sorter);
sorter.addMouseListenerToHeaderInTable(tableView);
......@@ -114,6 +145,18 @@ public class TableExample3 {
}
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();
}
}
/*
* 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
* modification, are permitted provided that the following conditions
......@@ -29,73 +29,101 @@
* 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.table.*;
import javax.swing.border.*;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
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 TableExample4() {
JFrame frame = new JFrame("Table");
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.
final String[] names = {"First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian"};
final String[] names = { "First Name", "Last Name", "Favorite Color",
"Favorite Number", "Vegetarian" };
final Object[][] data = {
{"Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE},
{"Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE},
{"Alan", "Chung", "Green", new Integer(838), Boolean.FALSE},
{"Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE},
{"Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE},
{"Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE},
{"James", "Gosling", "Pink", new Integer(21), Boolean.FALSE},
{"David", "Karlton", "Red", new Integer(1), Boolean.FALSE},
{"Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE},
{"Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE},
{"Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE},
{"Dave", "Moore", "Green", new Integer(88), Boolean.FALSE},
{"Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE},
{"Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE},
{"Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE},
{"Chester", "Rose", "Black", new Integer(0), Boolean.FALSE},
{"Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE},
{"Georges", "Saab", "Red", new Integer(4), Boolean.FALSE},
{"Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE},
{"Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE},
{"Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE}
{ "Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE },
{ "Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE },
{ "Alan", "Chung", "Green", new Integer(838), Boolean.FALSE },
{ "Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE },
{ "Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE },
{ "Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE },
{ "James", "Gosling", "Pink", new Integer(21), Boolean.FALSE },
{ "David", "Karlton", "Red", new Integer(1), Boolean.FALSE },
{ "Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE },
{ "Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE },
{ "Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE },
{ "Dave", "Moore", "Green", new Integer(88), Boolean.FALSE },
{ "Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE },
{ "Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE },
{ "Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE },
{ "Chester", "Rose", "Black", new Integer(0), Boolean.FALSE },
{ "Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE },
{ "Georges", "Saab", "Red", new Integer(4), Boolean.FALSE },
{ "Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE },
{ "Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE },
{ "Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE }
};
// Create a model of the data.
@SuppressWarnings("serial")
TableModel dataModel = new AbstractTableModel() {
// These methods always need to be implemented.
public int getColumnCount() { return names.length; }
public int getRowCount() { return data.length;}
public Object getValueAt(int row, int col) {return data[row][col];}
public int getColumnCount() {
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
// AbstractTableModel would work, but we can refine them.
public String getColumnName(int column) {return names[column];}
public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
public boolean isCellEditable(int row, int col) {return true;}
@Override
public String getColumnName(int column) {
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) {
System.out.println("Setting value to: " + aValue);
data[row][column] = aValue;
......@@ -104,8 +132,9 @@ public class TableExample4 {
// Create the table
JTable tableView = new JTable(dataModel);
// Turn off auto-resizing so that we can set column sizes programmatically.
// In this mode, all columns will get their preferred widths, as set blow.
// Turn off auto-resizing so that we can set column sizes
// programmatically. In this mode, all columns will get their preferred
// widths, as set blow.
tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Create a combo box to show that you can use one in a table.
......@@ -123,15 +152,18 @@ public class TableExample4 {
colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
// Set a pink background and tooltip for the Color column renderer.
DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer();
DefaultTableCellRenderer colorColumnRenderer =
new DefaultTableCellRenderer();
colorColumnRenderer.setBackground(Color.pink);
colorColumnRenderer.setToolTipText("Click for combo box");
colorColumn.setCellRenderer(colorColumnRenderer);
// Set a tooltip for the header of the colors column.
TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
if (headerRenderer instanceof DefaultTableCellRenderer)
((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!");
if (headerRenderer instanceof DefaultTableCellRenderer) {
((DefaultTableCellRenderer) headerRenderer).setToolTipText(
"Hi Mom!");
}
// Set the width of the "Vegetarian" column.
TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
......@@ -139,9 +171,14 @@ public class TableExample4 {
// Show the values in the "Favorite Number" column in different colors.
TableColumn numbersColumn = tableView.getColumn("Favorite Number");
DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() {
@SuppressWarnings("serial")
DefaultTableCellRenderer numberColumnRenderer
= new DefaultTableCellRenderer() {
@Override
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);
setText((value == null) ? "" : value.toString());
}
......@@ -160,6 +197,19 @@ public class TableExample4 {
}
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();
}
}
/*
* 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
* modification, are permitted provided that the following conditions
......@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
/**
* In a chain of data manipulators some behaviour is common. TableMap
......@@ -41,14 +39,16 @@
* a TableMap which has not been subclassed into a chain of table filters
* should have no effect.
*
* @author Philip Milne */
* @author Philip Milne
*/
import javax.swing.table.*;
import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;
public class TableMap extends AbstractTableModel implements TableModelListener
{
@SuppressWarnings("serial")
public class TableMap extends AbstractTableModel implements TableModelListener {
protected TableModel model;
public TableModel getModel() {
......@@ -62,11 +62,11 @@ public class TableMap extends AbstractTableModel implements TableModelListener
// By default, Implement TableModel by forwarding all messages
// to the model.
public Object getValueAt(int aRow, int aColumn) {
return model.getValueAt(aRow, aColumn);
}
@Override
public void setValueAt(Object aValue, int aRow, int aColumn) {
model.setValueAt(aValue, aRow, aColumn);
}
......@@ -79,14 +79,17 @@ public class TableMap extends AbstractTableModel implements TableModelListener
return (model == null) ? 0 : model.getColumnCount();
}
@Override
public String getColumnName(int aColumn) {
return model.getColumnName(aColumn);
}
@Override
public Class getColumnClass(int aColumn) {
return model.getColumnClass(aColumn);
}
@Override
public boolean isCellEditable(int row, int column) {
return model.isCellEditable(row, column);
}
......
/*
* 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
* modification, are permitted provided that the following conditions
......@@ -29,8 +29,19 @@
* 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)
......@@ -48,46 +59,29 @@
*
* @author Philip Milne
*/
@SuppressWarnings("serial")
public final class TableSorter extends TableMap {
import java.util.*;
import javax.swing.table.TableModel;
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();
List<Integer> sortingColumns = new ArrayList<Integer>();
boolean ascending = true;
int compares;
public TableSorter()
{
public TableSorter() {
indexes = new int[0]; // For consistency.
}
public TableSorter(TableModel model)
{
public TableSorter(TableModel model) {
setModel(model);
}
@Override
public void setModel(TableModel model) {
super.setModel(model);
reallocateIndexes();
}
public int compareRowsByColumn(int row1, int row2, int column)
{
public int compareRowsByColumn(int row1, int row2, int column) {
Class type = model.getColumnClass(column);
TableModel data = model;
......@@ -99,104 +93,100 @@ public class TableSorter extends TableMap
// If both values are null return 0
if (o1 == null && o2 == null) {
return 0;
}
else if (o1 == null) { // Define null less than everything.
} else if (o1 == null) { // Define null less than everything.
return -1;
}
else if (o2 == null) {
} else if (o2 == null) {
return 1;
}
/* We copy all returned values from the getValue call in case
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
this way but other subclasses of Number might want to do this to save
space and avoid unnecessary heap allocation.
*/
if (type.getSuperclass() == java.lang.Number.class)
{
Number n1 = (Number)data.getValueAt(row1, column);
/* We copy all returned values from the getValue call in case
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 this way but other subclasses of Number might want to do this to save
space and avoid unnecessary heap allocation.
*/
if (type.getSuperclass() == java.lang.Number.class) {
Number n1 = (Number) data.getValueAt(row1, column);
double d1 = n1.doubleValue();
Number n2 = (Number)data.getValueAt(row2, column);
Number n2 = (Number) data.getValueAt(row2, column);
double d2 = n2.doubleValue();
if (d1 < d2)
if (d1 < d2) {
return -1;
else if (d1 > d2)
} else if (d1 > d2) {
return 1;
else
} else {
return 0;
}
else if (type == java.util.Date.class)
{
Date d1 = (Date)data.getValueAt(row1, column);
} else if (type == java.util.Date.class) {
Date d1 = (Date) data.getValueAt(row1, column);
long n1 = d1.getTime();
Date d2 = (Date)data.getValueAt(row2, column);
Date d2 = (Date) data.getValueAt(row2, column);
long n2 = d2.getTime();
if (n1 < n2)
if (n1 < n2) {
return -1;
else if (n1 > n2)
} else if (n1 > n2) {
return 1;
else return 0;
} else {
return 0;
}
else if (type == String.class)
{
String s1 = (String)data.getValueAt(row1, column);
String s2 = (String)data.getValueAt(row2, column);
} else if (type == String.class) {
String s1 = (String) data.getValueAt(row1, column);
String s2 = (String) data.getValueAt(row2, column);
int result = s1.compareTo(s2);
if (result < 0)
if (result < 0) {
return -1;
else if (result > 0)
} else if (result > 0) {
return 1;
else return 0;
} else {
return 0;
}
else if (type == Boolean.class)
{
Boolean bool1 = (Boolean)data.getValueAt(row1, column);
} else if (type == Boolean.class) {
Boolean bool1 = (Boolean) data.getValueAt(row1, column);
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean)data.getValueAt(row2, column);
Boolean bool2 = (Boolean) data.getValueAt(row2, column);
boolean b2 = bool2.booleanValue();
if (b1 == b2)
if (b1 == b2) {
return 0;
else if (b1) // Define false < true
} else if (b1) // Define false < true
{
return 1;
else
} else {
return -1;
}
else
{
} else {
Object v1 = data.getValueAt(row1, column);
String s1 = v1.toString();
Object v2 = data.getValueAt(row2, column);
String s2 = v2.toString();
int result = s1.compareTo(s2);
if (result < 0)
if (result < 0) {
return -1;
else if (result > 0)
} else if (result > 0) {
return 1;
else return 0;
} else {
return 0;
}
}
}
public int compare(int row1, int row2)
{
public int compare(int row1, int row2) {
compares++;
for(int level = 0; level < sortingColumns.size(); level++)
{
Integer column = (Integer)sortingColumns.elementAt(level);
for (int level = 0; level < sortingColumns.size(); level++) {
Integer column = sortingColumns.get(level);
int result = compareRowsByColumn(row1, row2, column.intValue());
if (result != 0)
if (result != 0) {
return ascending ? result : -result;
}
}
return 0;
}
public void reallocateIndexes()
{
public void reallocateIndexes() {
int rowCount = model.getRowCount();
// Set up a new array of indexes with the right number of elements
......@@ -204,39 +194,38 @@ space and avoid unnecessary heap allocation.
indexes = new int[rowCount];
// Initialise with the identity mapping.
for(int row = 0; row < rowCount; row++)
for (int row = 0; row < rowCount; row++) {
indexes[row] = row;
}
}
public void tableChanged(TableModelEvent e)
{
@Override
public void tableChanged(TableModelEvent e) {
System.out.println("Sorter: tableChanged");
reallocateIndexes();
super.tableChanged(e);
}
public void checkModel()
{
public void checkModel() {
if (indexes.length != model.getRowCount()) {
System.err.println("Sorter not informed of a change in model.");
}
}
public void sort(Object sender)
{
public void sort(Object sender) {
checkModel();
compares = 0;
// n2sort();
// qsort(0, indexes.length-1);
shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length);
System.out.println("Compares: "+compares);
shuttlesort(indexes.clone(), indexes, 0, indexes.length);
System.out.println("Compares: " + compares);
}
public void n2sort() {
for(int i = 0; i < getRowCount(); i++) {
for(int j = i+1; j < getRowCount(); j++) {
for (int i = 0; i < getRowCount(); i++) {
for (int j = i + 1; j < getRowCount(); j++) {
if (compare(indexes[i], indexes[j]) == -1) {
swap(i, j);
}
......@@ -255,7 +244,7 @@ space and avoid unnecessary heap allocation.
if (high - low < 2) {
return;
}
int middle = (low + high)/2;
int middle = (low + high) / 2;
shuttlesort(to, from, low, middle);
shuttlesort(to, from, middle, high);
......@@ -277,20 +266,17 @@ space and avoid unnecessary heap allocation.
find out how the performance drops to Nlog(N) as the initial
order diminishes - it may drop very quickly. */
if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) {
for (int i = low; i < high; i++) {
to[i] = from[i];
}
if (high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
System.arraycopy(from, low, to, low, high - low);
return;
}
// 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)) {
to[i] = from[p++];
}
else {
} else {
to[i] = from[q++];
}
}
......@@ -304,15 +290,14 @@ space and avoid unnecessary heap allocation.
// The mapping only affects the contents of the data rows.
// Pass all requests to these rows through the mapping array: "indexes".
public Object getValueAt(int aRow, int aColumn)
{
@Override
public Object getValueAt(int aRow, int aColumn) {
checkModel();
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();
model.setValueAt(aValue, indexes[aRow], aColumn);
}
......@@ -323,8 +308,8 @@ space and avoid unnecessary heap allocation.
public void sortByColumn(int column, boolean ascending) {
this.ascending = ascending;
sortingColumns.removeAllElements();
sortingColumns.addElement(new Integer(column));
sortingColumns.clear();
sortingColumns.add(column);
sort(this);
super.tableChanged(new TableModelEvent(this));
}
......@@ -337,13 +322,15 @@ space and avoid unnecessary heap allocation.
final JTable tableView = table;
tableView.setColumnSelectionAllowed(false);
MouseAdapter listMouseListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel(viewColumn);
if(e.getClickCount() == 1 && column != -1) {
if (e.getClickCount() == 1 && column != -1) {
System.out.println("Sorting ...");
int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
boolean ascending = (shiftPressed == 0);
sorter.sortByColumn(column, ascending);
}
......@@ -352,7 +339,4 @@ space and avoid unnecessary heap allocation.
JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册