如何刷新 JTable 中的数据我正在使用 TableModel

2024-04-06

Hi,

我已经创建了 TableModel,并希望在添加新行后刷新 JTable。应该向监听器添加什么来“刷新”JTable?

public class MyTableModel implements TableModel  {
    private Set<TableModelListener> listeners = new HashSet<TableModelListener>();

    //List<Staff> staffs = Factory.getInstance().getStaffDAO().getAllStaff();
    private List<Staff> staffs;

    public MyTableModel(List<Staff> staffs){
        this.staffs = staffs;
    }

    @Override
    public int getRowCount() {
        return staffs.size();
    }

    @Override
    public int getColumnCount() {
        return 5;  
    }

    @Override
    public String getColumnName(int columnIndex) {
        switch (columnIndex){
            case 0:
                return "First Name";
            case 1:
                return "Second Name";
            case 2:
                return "Date";
            case 3:
                return "Position";
            case 4:
                return "Salary";
        }
        return "";  
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return Object.class;  
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;  
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Staff staff = staffs.get(rowIndex);
        switch (columnIndex){
            case 0:
                return staff.getName();
            case 1:
                return staff.getSurname();
            case 2:
                return staff.getDate();
            case 3:
                return staff.getPosition();
            case 4:
                return staff.getSalary();
        }
        return "";  
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    }

    @Override
    public void addTableModelListener(TableModelListener l) {
    }

    @Override
    public void removeTableModelListener(TableModelListener l) {
    }
}

这是我的添加行按钮的监听器:

 @Override
    public void actionPerformed(ActionEvent e) {
        Staff staff = new Staff();
        staff.setName(JOptionPane.showInputDialog("Enter First Name"));
        staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
        staff.setDate(JOptionPane.showInputDialog("Enter Date"));
        staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
        staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
        try {
            Factory.getInstance().getStaffDAO().addStaff(staff);
        } catch (SQLException e1) {
            e1.printStackTrace();  
        }
!!!Here should be some code that will be firing my table after adding new row!!!
}

我尝试在我的actionPerformed()中使用AbstractTableModel的firetabledatachanged()方法,但不幸的是,出现了ClassCastException。

UPDATE 1

WorkPlaceGui.java

public class WorkPlaceGui extends JFrame implements ActionListener {

    AbstractTableModel model;
    JTable jTable;
    JScrollPane jScrollPane;

    public WorkPlaceGui()throws SQLException{


        List<Staff> staffs = Factory.getInstance().getStaffDAO().getAllStaff();
        for(int i = 0; i < 0; i++) {
                staffs.add(new Staff("First Name " + staffs.get(i).getName(), "Second Name " + staffs.get(i).getSurname(), "Date " + staffs.get(i).getDate(), "Position " + staffs.get(i).getPosition(), "Salary " + staffs.get(i).getSalary()));
        }

        model = new MyTableModel(staffs);
        jTable = new JTable(model);
        JButton jBtnAdd = new JButton("Добавить");
        JButton jBtnDel = new JButton("Удалить");
        JButton jBtnUpd = new JButton("Обновить");
        JButton jBtnAdmin = new JButton("Админка");
        JPanel panelNorth = new JPanel();
        JPanel panelCenter = new JPanel();
        JPanel panelSouth = new JPanel();
        jTable.setPreferredScrollableViewportSize(new Dimension(350, 150));
        jScrollPane = new JScrollPane(jTable);


        panelNorth.setLayout(new FlowLayout());
        panelNorth.add(jBtnAdd);
        panelNorth.add(jBtnDel);
        panelNorth.add(jBtnUpd);
        panelNorth.add(jBtnAdmin);
        panelCenter.add(jScrollPane);

        setLayout(new BorderLayout());
        add(panelNorth, BorderLayout.NORTH);
        add(panelCenter, BorderLayout.CENTER);

        jBtnAdd.addActionListener(this);

        setPreferredSize(new Dimension(550, 300));
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("Staff data base");
        pack();
        setVisible(true);
        setLocationRelativeTo(null);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Staff staff = new Staff();
        staff.setName(JOptionPane.showInputDialog("Enter First Name"));
        staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
        staff.setDate(JOptionPane.showInputDialog("Enter Date"));
        staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
        staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
        try {
            Factory.getInstance().getStaffDAO().addStaff(staff);
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        model.fireTableDataChanged();
    }
}

MyTableModel.java

public class MyTableModel extends AbstractTableModel {

    private List<Staff> staffs;

    public MyTableModel(List<Staff> staffs){
        this.staffs = staffs;
    }

    @Override
    public int getRowCount() {
        return staffs.size();
    }

    @Override
    public int getColumnCount() {
        return 5;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Staff staff = staffs.get(rowIndex);
        switch (columnIndex){
            case 0:
                return staff.getName();
            case 1:
                return staff.getSurname();
            case 2:
                return staff.getDate();
            case 3:
                return staff.getPosition();
            case 4:
                return staff.getSalary();
        }
        return "";
    }
}

你已经用艰难的方式做到了。

首先,您直接从TableModel其次,您未能实现侦听器的要求......

相反,尝试从AbstractTableModel http://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html相反,它已经包含监听器注册和通知的实现。

您需要提供一种方法,允许您向表模型添加行。在此方法中,您需要使用fireTableRowsInserted http://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html#fireTableRowsInserted%28int,%20int%29方法将通知使用该模型的任何表,已添加新行...

更新示例

这是非常非常基本的例子。它的唯一目的是演示使用fireTableRowsInserted。它使用了 SwingTimer每 125 毫秒添加一个新行,直到您杀死它;)

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class DynamicTable {

    public static void main(String[] args) {
        new DynamicTable();
    }

    public DynamicTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                
                final MyTableModel model = new MyTableModel();
                JTable table = new JTable(model);
                
                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                
                Timer timer = new Timer(125, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        model.addRow();
                    }
                });
                timer.start();
            }
        });
    }
    
    public class MyTableModel extends AbstractTableModel {

        private List<String[]> rows;

        public MyTableModel() {
            rows = new ArrayList<>(25);
        }
        
        @Override
        public int getRowCount() {
            return rows.size();
        }

        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return String.class;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            String[] row = rows.get(rowIndex);
            return row[columnIndex];
        }
        
        public void addRow() {
            int rowCount = getRowCount();
            String[] row = new String[getColumnCount()];
            for (int index = 0; index < getColumnCount(); index++) {
                row[index] = rowCount + "x" + index;
            }
            rows.add(row);
            fireTableRowsInserted(rowCount, rowCount);
        }            
    }                    
}

更新了另一个例子

因为你的表模型有它自己的支持List,它与您的工厂没有任何联系。它不知道您何时向其中添加或删除对象。这意味着您将负责更新模型:

public class MyTableModel extends AbstractTableModel {

    private List<Staff> staffs;

    public MyTableModel(List<Staff> staffs){
        this.staffs = staffs;
    }

    @Override
    public int getRowCount() {
        return staffs.size();
    }

    @Override
    public int getColumnCount() {
        return 5;
    }
    
    public void add(Staff staff) {
        int size = getSize();
        staffs.add(staff);
        fireTableRowsInserted(size, size);
    }

    public void remove(Staff staff) {
        if (staffs.contains(staff) {
            int index = stafff.indexOf(staff);
            staffs.remove(staff);
            fireTableRowsDeleted(index, index);
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Staff staff = staffs.get(rowIndex);
        switch (columnIndex){
            case 0:
                return staff.getName();
            case 1:
                return staff.getSurname();
            case 2:
                return staff.getDate();
            case 3:
                return staff.getPosition();
            case 4:
                return staff.getSalary();
        }
        return "";
    }
}

和你的actionPerformed:

@Override
public void actionPerformed(ActionEvent e) {
    Staff staff = new Staff();
    staff.setName(JOptionPane.showInputDialog("Enter First Name"));
    staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
    staff.setDate(JOptionPane.showInputDialog("Enter Date"));
    staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
    staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
    try {
        Factory.getInstance().getStaffDAO().addStaff(staff);
        ((MyTableModel)model).add(staff);
    } catch (SQLException e1) {
        e1.printStackTrace();  
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何刷新 JTable 中的数据我正在使用 TableModel 的相关文章

  • 检查从 arrayadapter 获取的复选框

    我有标题清单 CheckBox 我想控制默认检查哪一个 所以我试图获得正确的视图并检查它 但由于某种原因它不起作用 知道为什么吗 form checkbox item xml
  • 使用 JavaScript 与 Web 服务器通信的 Applet 是否可以迁移到 JWS?

    只是分享一些信息 希望对社区有用 由于各种浏览器停止支持插件 Applet 的可用性已经下降 Google 已决定停止对 NPAPI 插件的支持 EDGE 不支持插件 Firefox 也不鼓励使用插件 Mozilla 可能会跟进该套件 我们
  • Grails 项目 - Servlet 调用 - ClassNotFoundException:javax.servlet.AsyncContext

    我在用 IntelliJ IDEA 终极版 12 4 grails 2 2 0 BuildConfig groovy 文件中的 grails servlet version 2 5 并实现了简单的 servlet post 请求 使用 RE
  • 在 json 中解析尾随字符

    我正在尝试检查 json 是否有效 并且我遇到了奇怪的行为 当我将一些字符附加到可解析的 json 时 jackson 和 gson 都会解析它 并且它们会忽略尾随字符 我想检查 json 是否严格有效 请帮忙 我尝试了几个标志mapper
  • WSDL2Java 抛出无法找到主类:org.apache.axis.wsdl.WSDL2Java

    我正在尝试从远程 Web 服务创建 java 文件 我下载了axis 1 4 将lib文件夹复制到c data axis lib其中包含这些文件 axis jar 轴 ant jar commons discovery 0 2 jar co
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100
  • 如何在 Java 中使用 HTML 解析器和 Apache Tika 来提取所有 HTML 标签?

    我下载了 tika core 和 tika parser 库 但找不到将 HTML 文档解析为字符串的示例代码 我必须删除网页源的所有 html 标签 我能做些什么 如何使用 Apache Tika 进行编码 您想要 html 文件的纯文本
  • Java ArrayList 和 HashMap 动态

    有人可以提供一个创建Java的例子吗ArrayList and HashMap在飞行中 所以而不是做一个add or put 实际上在类实例化时为数组 哈希提供种子数据 举个例子 类似于 PHP 的例子 array array 3 1 2
  • 用于 Eclipse 的 Resharper [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Jersey 和 Spring 中的全局异常处理?

    我正在使用 Jersey 和 Spring 3 2 以及 Open CMIS 开发 RESTful Web 服务 我没有使用 Spring 的 MVC 模式 它只是 Spring IOC 和 Jersey SpringServlet 控制器
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算
  • Java DNSLookup MX 记录列表。类似于 MXToolBox

    我正在构建一个程序来列出域的所有 MX 记录 起初似乎工作正常 但与在线工具进行比较后http mxtoolbox com http mxtoolbox com 有些域程序无法获取 MX 记录 而 MXToolbox 可以 我不确定原因是什
  • Eclipse Juno 指标插件

    Eclipse JUNO 版本有哪些 Eclipse 指标插件 我尝试了一些通用指标插件 但没有一个能够在 Eclipse 的 JUNO 版本中正常运行 差点忘了 我们正在使用 Java 作为编程语言 我想要诸如圈复杂度 代码行数 方法长度
  • “强制更新快照/版本” - 这是什么意思

    在 Maven 项目中 选择 更新项目 时 有一个名为 强制更新快照 版本 的选项 它有什么作用 强制更新快照 版本 就像运行以下命令 mvn U install U 也可以用作 update snapshot 看here http boo
  • Web 服务客户端的 AXIS 与 JAX-WS

    我决定用Java 实现Web 服务客户端 我已经在 Eclipse 中生成了 Axis 客户端 并使用 wsimport 生成了 JAS WS 客户端 两种解决方案都有效 现在我必须选择一种来继续 在选择其中之一之前我应该 考虑什么 JAX
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 按钮悬停和按下效果 CSS Javafx

    我是 CSS 新手 为按钮定义了以下 CSS 样式 其中id并且应用了自定义样式 但不应用悬停和按下效果 bevel grey fx background color linear gradient f2f2f2 d6d6d6 linear
  • Eclipse 如何创建一个未解决编译问题的类?

    当我尝试使用 javac 编译此类时 出现编译错误并且未创建 Test class public class Test public static void main String args int x 1L lt this cannot
  • Volley 在第一次调用方法时返回 null

    我正在尝试使用 volley 从服务器检索数据 但是当我第一次调用此方法时 我收到服务器的响应 但该方法返回 null 如果我第二次调用它 我会得到最后的响应 public String retrieveDataFromServer Str
  • 需要在没有wsdl的情况下调用soap ws

    我是网络服务的新手 这个网络服务是由 siebel 提供的 我需要调用一项网络服务 我的客户向我提供了以下详细信息 这是 SOAP 对于产品 请使用它作为端点 Request

随机推荐