从 DefaultTableModel 更新 JTable

Update JTable from DefaultTableModel

所以我想做的是在按下按钮时更新 JTable。我使用 DefaultTableModel 作为源。 Table class:

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import java.awt.Dimension;

public class TableDemo extends JPanel {
    String[] columnNames = {"Tipo","Cantidad"};
    DefaultTableModel dtm = new DefaultTableModel(null,columnNames);
    final JTable table = new JTable(dtm);

 public TableDemo() {
    table.setPreferredScrollableViewportSize(new Dimension(500, 700));
    table.setFillsViewportHeight(true);
    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane);
 }

 public void addRow(Object [] row)
 {
     dtm.addRow(row);
 }

}

形式class:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;

public class MyForm extends JFrame {

JPanel panel;
JLabel label;
JTextField txtName;
JTextField txtSurname;
JButton btnAccept;
TableDemo tb  = new TableDemo();

public MyForm(){
    initControls();
}

private void initControls() {
    setTitle("Form Example");
    setSize(600, 400);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocationRelativeTo(null);

    panel = new JPanel();       
    panel.setLayout(null);

    label = new JLabel("Welcome to Swing");
    label.setBounds(50, 10, 200, 30);

    txtName = new JTextField();
    txtName.setBounds(50, 50, 200, 30);

    txtSurname = new JTextField();
    txtSurname.setBounds(270, 50, 200, 30);

    btnAccept = new JButton("Add");
    btnAccept.setBounds(120, 100, 150, 30);

    onAcceptClick();
    TableDemo tablePanel = new TableDemo();

    panel.add(label);
    panel.add(txtName);
    panel.add(txtSurname);
    panel.add(btnAccept);

    JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
            tablePanel,panel );
    splitPane.setDividerLocation(205);
    splitPane.setEnabled(false);

    getContentPane().add(splitPane);
}

private void onAcceptClick() {
    btnAccept.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            tb.addRow(new Object[]{"taza",txtName.getText()});

        }
    });
public static void main(String[] args) {
    //Initilizer init = new Initilizer();

    Runnable init = new Runnable() {

        @Override
        public void run() {
            MyForm form = new MyForm();
            form.setVisible(true);
        }
    };

    SwingUtilities.invokeLater(init);   
}
}

如您所见,我调用了 addRow 函数,但在 JTable 中从不更新,我缺少什么?谢谢

您正在创建两个 TableDemo 对象 -- 一个添加到 GUI,tablePanel,另一个添加一行,待定;

// ...

TableDemo tb  = new TableDemo();  // TableDemo #1. Never displayed

private void initControls() {
    // ...

    TableDemo tablePanel = new TableDemo();   // TableDemo #2

    // ...

    //  TableDemo #2 is here added to the GUI
    JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tablePanel,panel );

    // ...
}

btnAccept.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {

        // here you add a row to the non-displayed TableDemo #1
        tb.addRow(new Object[]{"taza",txtName.getText()});
    }
});

解决方案:不要这样做(显然)!只使用一个 TableDemo 实例,显示它并对其进行更改。所以去掉 tablePanel 变量,只使用 tb 变量。

其他问题:

  • 您正在使用 null 布局。虽然空布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单和最好的方法,但您创建的 Swing GUI 越多,您在使用它们时就会 运行 遇到更严重的困难。它们不会在 GUI 调整大小时调整组件的大小,它们是皇家 来增强或维护的,当放置在滚动窗格中时它们完全失败,当在所有平台或不同的屏幕分辨率上查看时它们看起来很糟糕从原来的。