Java 过滤JTable后的问题
我对我正在做的一个项目有意见。简单地解释一下,我有一个包含多个列和行的JTable。更改值时,特定列具有可编辑字段,其他列值根据输入的数据进行更改。但是,当我在JTable中添加了一个filter选项时,对一个可编辑列所做的更改不会在应用过滤器后按预期更改其他列的值。我附上了一些图片来说明这个问题 第一幅图显示未过滤的表工作正常。更改折扣列值将使GPL列中存储的相应价格降低输入折扣的百分比,并显示在SP列的相应行中。更改“数量”列的值会将相应的SP列价格与输入的数量相乘,并显示在“总计”列的相应行中 第二幅图显示过滤后的表未按预期工作。更改折扣或数量列中的值不会更改预期列 我在下面添加了SSCCE代码,其中包含2个类。第一个是表本身,第二个是表的侦听器 编辑我根据camickr的答案更改了课程代码,现在完全可以使用了 TableCellChange类Java 过滤JTable后的问题,java,swing,jtable,rowfilter,Java,Swing,Jtable,Rowfilter,我对我正在做的一个项目有意见。简单地解释一下,我有一个包含多个列和行的JTable。更改值时,特定列具有可编辑字段,其他列值根据输入的数据进行更改。但是,当我在JTable中添加了一个filter选项时,对一个可编辑列所做的更改不会在应用过滤器后按预期更改其他列的值。我附上了一些图片来说明这个问题 第一幅图显示未过滤的表工作正常。更改折扣列值将使GPL列中存储的相应价格降低输入折扣的百分比,并显示在SP列的相应行中。更改“数量”列的值会将相应的SP列价格与输入的数量相乘,并显示在“总计”列的相应
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.Locale;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
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.JTextField;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public final class TableCellChange extends JPanel {
private static JFrame frameTableCellChange;
private JPanel panelTable, panelButtons;
private JButton buttonResetDiscounts, buttonResetQuantities, buttonExit;
private JTextField textFilterBox, quantityField, discountField;
private JLabel labelFilter;
private DefaultTableModel tableModel;
private JTable table;
private TableRowSorter<DefaultTableModel> sorter;
private TableColumn columnDiscount, columnTotal, columnQuantity;
private TableCellListener tableCellListener;
private String checkForNull;
private DecimalFormat decimalFormatUS;
private Locale localeUSFormat;
private BigDecimal valueDiscount, valueGPL, resultDiscount, resultSP, resultTotal,
backupDiscount = new BigDecimal("0");
private int selectedColumnIndex, selectedRowIndex, valueQuantity, backupQuantity = 1;
public TableCellChange() {
super();
panelTable = new JPanel();
panelButtons = new JPanel();
setLayout(new BorderLayout());
createTable();
createButtons();
add(panelTable, BorderLayout.NORTH);
add(panelButtons, BorderLayout.CENTER);
// Always focus on the JTextField when opening the window
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textFilterBox.requestFocusInWindow();
}
});
} // -> TableCellChange()
// Create the buttons for the query result window
public void createButtons() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints gridcons = new GridBagConstraints();
gridcons.fill = GridBagConstraints.HORIZONTAL;
panelButtons.setLayout(gridbag);
labelFilter = new JLabel("Quick search:");
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 0;
gridcons.gridwidth = 2;
gridbag.setConstraints(labelFilter, gridcons);
labelFilter.setHorizontalAlignment(JLabel.CENTER);
panelButtons.add(labelFilter);
// Create text field for filtering
textFilterBox = new JTextField();
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 1;
gridcons.gridwidth = 2;
gridbag.setConstraints(textFilterBox, gridcons);
textFilterBox.getDocument().addDocumentListener(
new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
tableFilter();
}
@Override
public void insertUpdate(DocumentEvent e) {
tableFilter();
}
@Override
public void removeUpdate(DocumentEvent e) {
tableFilter();
}
}); // -> DocumentListener()
panelButtons.add(textFilterBox);
// Create the button to reset the discount column to 0%
buttonResetDiscounts = new JButton("Reset all discounts");
buttonResetDiscounts.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
BigDecimal valueGPL, valueTotal;
int valueQuantity;
for (int i = 0; i < table.getModel().getRowCount(); i++) {
valueGPL = new BigDecimal( table.getModel().
getValueAt(i, 2).toString().replaceAll("[$,]", "") );
table.getModel().setValueAt("0%", i, 3);
table.getModel().setValueAt(DecimalFormat
.getCurrencyInstance(localeUSFormat).format(valueGPL), i, 4);
valueQuantity = Integer.parseInt( table.getModel().
getValueAt(i, 5).toString() );
valueTotal = valueGPL.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
table.getModel().setValueAt(DecimalFormat
.getCurrencyInstance(localeUSFormat).format(valueTotal), i, 6);
}
}
});
gridcons.insets = new Insets(10,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 3;
gridcons.gridwidth = 1;
gridbag.setConstraints(buttonResetDiscounts, gridcons);
panelButtons.add(buttonResetDiscounts);
// Create button to reset the quantity column to 1
buttonResetQuantities = new JButton("Reset all quantities");
buttonResetQuantities.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
BigDecimal valueSP;
for (int i = 0; i < table.getModel().getRowCount(); i++) {
valueSP = new BigDecimal( table.getModel().
getValueAt(i, 4).toString().replaceAll("[$,]", "") );
table.getModel().setValueAt("1", i, 5);
table.getModel().setValueAt(DecimalFormat.
getCurrencyInstance(localeUSFormat).format(valueSP), i, 6);
}
}
});
gridcons.insets = new Insets(10,0,0,0);
gridcons.gridx = 1;
gridcons.gridy = 3;
gridcons.gridwidth = 1;
gridbag.setConstraints(buttonResetQuantities, gridcons);
panelButtons.add(buttonResetQuantities);
// Create button for closing the window and releasing resources
buttonExit = new JButton("Exit");
buttonExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 5;
gridcons.gridwidth = 2;
gridbag.setConstraints(buttonExit, gridcons);
panelButtons.add(buttonExit);
} // -> createButtons()
// Filters the JTable based on user input
private void tableFilter() {
RowFilter<DefaultTableModel, Object> tableRowFilter;// = null;
// If current expression doesn't parse, don't update
try {
tableRowFilter = RowFilter.regexFilter("(?i)" + textFilterBox.
getText(), 0, 1, 2);
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(tableRowFilter);
} // -> tableFilter
// Method that creates the JTable
public void createTable() {
// Create listener for selecting all text when a text field gains focus
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getNewValue() instanceof JTextField) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTextField textField = (JTextField)e.getNewValue();
textField.selectAll();
}
});
}
}
});
String[] columnNames = {"Model", "Description", "GPL", "Discount", "SP",
"Quantity", "Total"};
Object[][] data = {
{"MR16", "desc1", "$649.00", "0%", "$649.00", new Integer(1), "$649.00"},
{"MR24", "desc2", "$1,199.00", "0%", "$1,199.00", new Integer(1), "1,199.00"},
{"MR62", "desc3", "$699.00", "0%", "$699.00", new Integer(1), "$699.00"},
{"MR66", "desc4", "$1,299.00", "0%", "$1,299.00", new Integer(1), "$1,299.00"},
{"MX80", "desc5", "$1,995.00", "0%", "$1,995.00", new Integer(1), "$1,995.00"},
{"MX90", "desc6", "$3,995.00", "0%", "$3,995.00", new Integer(1), "$3,995.00"},
{"MX400", "desc7", "$15,995.00", "0%", "$15,995.00", new Integer(1), "$15,995.00"},
{"MX600", "desc8", "$31,995.00", "0%", "$31,995.00", new Integer(1), "$31,995.00"},
{"MS22-HW", "desc9", "$1,999.00", "0%", "$1,999.00", new Integer(1), "$1,999.00"},
{"MS42-HW", "desc10", "$3,499.00", "0%", "$3,499.00", new Integer(1), "$3,499.00"},
};
// Create the TableModel and populate it
tableModel = new DefaultTableModel(data, columnNames) {
Class [] classes = {String.class, String.class, String.class,
String.class, String.class, int.class, String.class, Boolean.class};
@Override
public Class getColumnClass(int column) {
return classes[column];
}
};
// Create a JTable and populate it with the content of the TableModel
table = new JTable(tableModel) {
@Override
public boolean isCellEditable(int row, int column) {
if (column == 0 || column == 1 || column == 2 || column == 4 ||
column == 6) {
return false;
}
return true;
}
};
// This sorter is used for text filtering
sorter = new TableRowSorter<>(tableModel);
for (int column = 3; column < 6; column++) {
sorter.setSortable(column, false);
}
table.setRowSorter(sorter);
columnTotal= table.getColumnModel().getColumn(6);
columnTotal.setPreferredWidth(100);
// Filter user input in the quantity text field to only allow digits
discountField =new JTextField();
discountField.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e)
{
if(!Character.isDigit(e.getKeyChar()) && e.getKeyChar() !=KeyEvent.VK_BACK_SPACE) {
discountField.setEditable(false);
discountField.setBackground(Color.WHITE);
} else {
discountField.setEditable(true);
}
}
});
// Set the text field to the cells of the quantity column
columnQuantity = table.getColumnModel().getColumn(5);
columnQuantity.setCellEditor(new DefaultCellEditor (discountField));
// Filter user input in the discount text field to only allow digits
quantityField =new JTextField();
quantityField.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e)
{
if(!Character.isDigit(e.getKeyChar()) && e.getKeyChar() !=KeyEvent.VK_BACK_SPACE) {
quantityField.setEditable(false);
quantityField.setBackground(Color.WHITE);
//JOptionPane.showMessageDialog(null,"Only digit input is allowed!");
} else {
quantityField.setEditable(true);
}
}
});
// Set the text field to the cells of the quantity column
columnDiscount = table.getColumnModel().getColumn(3);
columnDiscount.setCellEditor(new DefaultCellEditor(discountField));
// Create an US number format
localeUSFormat = Locale.US;
decimalFormatUS = (DecimalFormat) DecimalFormat.getInstance(localeUSFormat);
decimalFormatUS.setMaximumFractionDigits(2);
// Create abstract action which listens for changes made in the JTable
Action actionTableListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
TableCellListener tcl = (TableCellListener)e.getSource();
// Get the current row and column index of the table
selectedRowIndex = tcl.getRow();
selectedColumnIndex = tcl.getColumn();
TableModel model = tcl.getTable().getModel();
// Have a string variable check for null cell value
checkForNull = model.getValueAt(selectedRowIndex,selectedColumnIndex).toString();
// Change the discounted and total price values
if (selectedColumnIndex == 3) {
// Check if the discount value is null and replace with
// last used value if true
if (checkForNull.equals("")) {
model.setValueAt(backupDiscount + "%",selectedRowIndex, selectedColumnIndex);
return;
}
// Get the discount value and replace the '%' with nothing
valueDiscount = new BigDecimal(( model
.getValueAt(selectedRowIndex,selectedColumnIndex)
.toString().replaceAll("[%]","") ));
//
model.setValueAt(valueDiscount + "%",selectedRowIndex, selectedColumnIndex);
// Check if the discount value is greater than 100
if ( (valueDiscount.compareTo(new BigDecimal(100)) == 1 ) ) {
model.setValueAt(backupDiscount + "%",selectedRowIndex, selectedColumnIndex);
JOptionPane.showMessageDialog(null,"Discount cannot be more than 100%.");
} else {
backupDiscount = valueDiscount;
valueDiscount = valueDiscount.divide(new BigDecimal(100)
, 2, BigDecimal.ROUND_HALF_EVEN);
// Calculate SP and Total values based on the discount input
valueGPL = new BigDecimal( ( model
.getValueAt(selectedRowIndex,selectedColumnIndex - 1)
.toString().replaceAll("[$,]","") ) );
// Get the quantity value
valueQuantity = Integer.parseInt( ( model
.getValueAt(selectedRowIndex,selectedColumnIndex + 2)
.toString() ) );
// Calculate the new discount value
resultDiscount = valueGPL.multiply(valueDiscount,
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Calculate the new SP value
resultSP = valueGPL.subtract(resultDiscount,
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Calculate the new result value
resultTotal = resultSP.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Display the new SP value
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultSP),selectedRowIndex, selectedColumnIndex + 1);
// Display the new Total value
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultTotal),selectedRowIndex, selectedColumnIndex + 3);
}
}
// Change the total price values based on the quantity column
if (selectedColumnIndex == 5) {
// Check if the quantity value is null and replace with
// last used value if true
if (checkForNull.equals("")) {
model.setValueAt(backupQuantity,selectedRowIndex, selectedColumnIndex);
return;
}
// Change total price value based on the quantity column
resultSP = new BigDecimal( ( model.
getValueAt(selectedRowIndex,
selectedColumnIndex - 1).toString().replaceAll("[$,]","") ) );
valueQuantity = Integer.parseInt( ( model.getValueAt(selectedRowIndex,
selectedColumnIndex).toString() ) );
// Check if the value quantity is over a certain limit
if (valueQuantity <= 0 || valueQuantity >= 999999) {
model.setValueAt(backupQuantity,selectedRowIndex, selectedColumnIndex);
JOptionPane.showMessageDialog(null,"Quantity value is too high or invalid!");
} else {
// If the value is under the limit: backup the new quantity
// value, calculate the new total value and display it
backupQuantity = valueQuantity;
resultTotal = resultSP.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultTotal), selectedRowIndex, selectedColumnIndex + 1);
}
}
}
}; // -> AbstractAction()
tableCellListener = new TableCellListener(table, actionTableListener);
table.setPreferredScrollableViewportSize(table.
getPreferredSize());
table.setRowHeight(22);
setVisibleRowCount(table,10);
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table.setFillsViewportHeight(true);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(false);
panelTable.add(new JScrollPane(table));
} // -> createTable()
// Method to display a fixed number of rows in the JTable viewport
public static void setVisibleRowCount(JTable table, int rows){
int height = 0;
for(int row=0; row<rows; row++) {
height += table.getRowHeight(row);
}
table.setPreferredScrollableViewportSize(new Dimension(
table.getPreferredScrollableViewportSize().width, height ));
}
// Create and display the contents of the frame
public static void showGUI() {
// Disable boldface controls
UIManager.put("swing.boldMetal", Boolean.FALSE);
// Create the frame
frameTableCellChange = new JFrame("Table frame");
frameTableCellChange.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameTableCellChange.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// Create and set up the content pane.
TableCellChange newContentPane = new TableCellChange();
newContentPane.setOpaque(true); //content panes must be opaque
frameTableCellChange.setContentPane(newContentPane);
// Arrange and display the window.
frameTableCellChange.pack(); //must be called first
frameTableCellChange.setLocationRelativeTo(null); //center window
frameTableCellChange.setResizable(false);
frameTableCellChange.setVisible(true);
} //-> showQueryResultGUI()
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.
UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException |
javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TableCellChange.class.getName()).
log(java.util.logging.Level.SEVERE, null, ex);
}
// Display the frame and it's contents
TableCellChange.showGUI();
}
});
} //-> main(String[] args)
} //-> TableCellChange class
我知道在筛选表时,表视图的索引会发生变化,并且必须与基础模型的索引同步。如何才能使筛选后的表正常工作?您可能需要执行从视图到模型的转换。查看“如何使用表格”教程的一部分: 当表格使用分拣机时,用户看到的数据可能在一个表格中 与数据模型指定的顺序不同,并且可能不会 包括数据模型指定的所有行。用户可以使用数据 “实际查看”称为“视图”,它有自己的一组 协调。JTable提供了从模型转换的方法 要查看坐标的坐标-convertColumnIndexToView和 convertRowIndexToView-将视图坐标转换为 模型坐标-convertColumnIndexToModel和 convertRowIndexToModel 编辑:从视图(表格)转换为模型: 替换这些行:
row = table.convertRowIndexToView(table.getEditingRow());
row = table.getEditingRow();
与:
row = table.convertRowIndexToModel(table.getEditingRow());
您错误地实现了TableCellListener的操作。无法使用选定的行/列,因为这些值位于表视图中。TableCellListener在模型上工作 查看随附的示例操作。要获取已更改的行/列,必须引用TableCellListener本身 编辑: 下面是我的简单文本示例。更改“价格”时,“价格更改”和“价值”列将自动更新
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableCellListenerTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
String[] columnNames = {"Stock", "Shares", "Price", "Price Change", "Value"};
Object[][] data =
{
{"IBM", new Integer(100), new Double(85), new Double(0), new Double(8500)},
{"Apple", new Integer(300), new Double(30), new Double(0), new Double(9000)},
{"Sun", new Integer(1500), new Double(5), new Double(0), new Double(7500)},
{"Google", new Integer(100), new Double(100), new Double(0), new Double(10000)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
public boolean isCellEditable(int row, int column)
{
return column == 2;
}
};
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
// Add a sorter
TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
// Filter
try
{
RowFilter<DefaultTableModel, Object> rf = RowFilter.regexFilter("l", 0);
sorter.setRowFilter(rf);
}
catch (java.util.regex.PatternSyntaxException e) {}
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener tcl = (TableCellListener)e.getSource();
int column = tcl.getColumn();
if (column == 2)
{
int row = tcl.getRow();
double oldPrice = ((Double)tcl.getOldValue()).doubleValue();
double newPrice = ((Double)tcl.getNewValue()).doubleValue();
TableModel model = tcl.getTable().getModel();
double priceChange = new Double(newPrice - oldPrice);
model.setValueAt(priceChange, row, 3);
double shares = ((Integer)model.getValueAt(row, 1)).doubleValue();
Double value = new Double(shares * newPrice);
model.setValueAt(value, row, 4);
}
}
};
TableCellListener tcl = new TableCellListener(table, action);
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Table Cell Listener");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( scrollPane );
frame.setSize(400, 160);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
import java.awt.*;
导入java.awt.event.*;
导入java.io.*;
导入java.net。*;
导入javax.swing.*;
导入javax.swing.table.*;
公共类TableCellListenerTest
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGUI();
}
});
}
公共静态void createAndShowGUI()
{
String[]columnNames={“股票”、“股票”、“价格”、“价格变化”、“价值”};
对象[][]数据=
{
{“IBM”、新整数(100)、新双精度(85)、新双精度(0)、新双精度(8500)},
{“苹果”、新整数(300)、新双精度(30)、新双精度(0)、新双精度(9000)},
{“Sun”、新整数(1500)、新双精度(5)、新双精度(0)、新双精度(7500)},
{“谷歌”,新整数(100),新双精度(100),新双精度(0),新双精度(10000)}
};
DefaultTableModel=新的DefaultTableModel(数据、列名)
{
公共类getColumnClass(int列)
{
返回getValueAt(0,列).getClass();
}
公共布尔值可编辑(int行,int列)
{
返回列==2;
}
};
JTable table=新的JTable(模型);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane=新的JScrollPane(表);
//添加一个分拣机
TableRowSorter分拣机=新的TableRowSorter(型号);
表.SetRow分拣机(分拣机);
//滤器
尝试
{
RowFilter rf=RowFilter.regexFilter(“l”,0);
分拣机。设置行过滤器(rf);
}
catch(java.util.regex.PatternSyntaxException e){}
Action Action=newAbstractAction()
{
已执行的公共无效操作(操作事件e)
{
TableCellListener tcl=(TableCellListener)e.getSource();
int column=tcl.getColumn();
如果(列==2)
{
int row=tcl.getRow();
double-oldPrice=((double)tcl.getOldValue()).doubleValue();
double newPrice=((double)tcl.getNewValue()).doubleValue();
TableModel model=tcl.getTable().getModel();
双倍价格变动=新双倍(新价格-旧价格);
model.setValueAt(价格变化,第3行);
double shares=((整数)model.getValueAt(行,1)).doubleValue();
双倍价值=新的双倍(股票*新价格);
model.setValueAt(值,第4行);
}
}
};
TableCellListener tcl=新的TableCellListener(表,动作);
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame=新的JFrame(“表格单元格侦听器”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(滚动窗格);
框架设置尺寸(400160);
frame.setLocationRelativeTo(空);
frame.setVisi
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableCellListenerTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
String[] columnNames = {"Stock", "Shares", "Price", "Price Change", "Value"};
Object[][] data =
{
{"IBM", new Integer(100), new Double(85), new Double(0), new Double(8500)},
{"Apple", new Integer(300), new Double(30), new Double(0), new Double(9000)},
{"Sun", new Integer(1500), new Double(5), new Double(0), new Double(7500)},
{"Google", new Integer(100), new Double(100), new Double(0), new Double(10000)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
public boolean isCellEditable(int row, int column)
{
return column == 2;
}
};
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
// Add a sorter
TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
// Filter
try
{
RowFilter<DefaultTableModel, Object> rf = RowFilter.regexFilter("l", 0);
sorter.setRowFilter(rf);
}
catch (java.util.regex.PatternSyntaxException e) {}
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener tcl = (TableCellListener)e.getSource();
int column = tcl.getColumn();
if (column == 2)
{
int row = tcl.getRow();
double oldPrice = ((Double)tcl.getOldValue()).doubleValue();
double newPrice = ((Double)tcl.getNewValue()).doubleValue();
TableModel model = tcl.getTable().getModel();
double priceChange = new Double(newPrice - oldPrice);
model.setValueAt(priceChange, row, 3);
double shares = ((Integer)model.getValueAt(row, 1)).doubleValue();
Double value = new Double(shares * newPrice);
model.setValueAt(value, row, 4);
}
}
};
TableCellListener tcl = new TableCellListener(table, action);
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Table Cell Listener");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( scrollPane );
frame.setSize(400, 160);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}