JTable 不调用 getValueAt

标签 jtable

我对 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/

相关文章:

java - 向 JTable 添加新行

java - 排序 JTable 行问题

java - 通过 JTable 删除 MySQL 数据库中的选定行

Java Swing : How to refresh JTable Model from another page button

java - 删除重复的项目java gui

java - 使光标在 JTable 内的 JTextField 中可见,无需左键单击

java - 合并 JTable 的两个行过滤器

java - 对 unicode 数字进行数学运算

java - 如何更新 JTable

java - 有没有人想出如何使 javafx tableview 像 jtable 一样工作?