我对 Swing 很陌生,并尝试使用 JTable 编写属性表,但看到一些奇怪的行为。我搁置了 NetBeans,并对这个小 gem 进行了编码,看看基础知识是否有效。如果您想知道,我的真实应用程序对 JTextField 进行子类化并提供对话框来帮助用户指定一些值; ImportField 就是这些类之一。
该程序显示 JTable,但它只有列标题。 JTable 从不调用 getValueAt,因此不会显示任何数据。
谁能帮助我理解这种行为?
import java.awt.*;
import java.awt.event.*;
import java.util.StringTokenizer;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.TableModelEvent;
public class Y extends JFrame {
public Y() {
super("Y");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final Model model = new Model();
JTable table = new JTable();
table.setModel(model);
JScrollPane scrollpane = new JScrollPane(table);
JButton button = new JButton("Click Me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
model.setValueAt(model.getValueAt(0, 1), 0, 1);
}
});
JPanel panel = new JPanel(new BorderLayout());
panel.add(scrollpane, BorderLayout.CENTER);
panel.add(button, BorderLayout.SOUTH);
setContentPane(panel);
pack();
}
public static void main (String[] args) throws Exception {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Y().setVisible(true);
}
});
}
}
class ImportField extends JTextField implements FocusListener {
public ImportField() {
super();
this.setInputVerifier(new ImportVerifier());
this.addFocusListener(this);
this.setBorder(null);
}
@Override
public void focusGained(FocusEvent e) {
// We only want to do this ONCE
this.removeFocusListener(this);
System.out.println("Text field gained focus.");
}
@Override
public void focusLost(FocusEvent e) {
// IGNORE
}
class ImportVerifier extends InputVerifier {
@Override
public boolean verify(JComponent input) {
boolean valid = true;
JTextField fld = (JTextField) input;
if (fld.getText().length() > 0) {
StringTokenizer tok = new StringTokenizer(fld.getText(), ", ");
while (tok.hasMoreTokens()) {
String token = tok.nextToken().toLowerCase();
if ( ! token.equals("insert") && ! token.equals("update") &&
! token.equals("ignore") && ! token.equals("abort") &&
! token.equals("none") && ! token.equals("all")) {
valid = false;
}
}
}
return valid;
}
}
}
class Model extends DefaultTableModel {
private String[] colNames = { "Key", "Value" };
private Object[][] data = { { "item 1", "something" },
{ "item 2", "something else" },
{ "item 3", "other thing" } };
@Override
public Class<?> getColumnClass(int columnIndex) {
System.out.format("%-15s %s\n", "getColumnClass", "String");
return String.class;
}
@Override
public int getColumnCount() {
System.out.format("%-15s %d\n", "getColumnCount", colNames.length);
return colNames.length;
}
@Override
public String getColumnName(int columnIndex) {
System.out.format("%-15s %s\n", "getColumnName", colNames[columnIndex]);
return colNames[columnIndex];
}
public int geRowlumnCount() {
System.out.format("%-15s %d\n", "getRowName", data.length);
return data.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
System.out.format("%-15s %s\n", "getValueAt", data[rowIndex][columnIndex]);
return data[rowIndex][columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
System.out.format("%-15s %s\n", "isCellEditable", rowIndex == 1);
return rowIndex == 1;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
System.out.format("%-15s %s\n", "setValueAt", aValue);
data[rowIndex][columnIndex] = aValue;
fireTableChanged(new TableModelEvent(this));
}
}
我们将非常感谢您的帮助。
最佳答案
试试这个,设置模型后,调用:
((DefaultTableModel)table.getModel()).fireTableDataChanged();
关于JTable 不调用 getValueAt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30197850/