AbstractDataTable fireTableDataChanged() does not refresh jt



在向jtable中添加数据时遇到困难。它首先从集合中加载数据,使用jtextfield我添加了一个新数据,当然数据是在集合中添加的,调试了它,但我不能在jtable中显示新添加的日期。我已经尝试了所有可能的方法,但都没能成功。下面的代码是我工作的一部分。

感谢

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.example.gui;
import com.example.service.CustomerService;
import com.example.service.VehicleService;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
/**
 *
 * @author Tugrul
 */
public class VehicleTypes extends JFrame {
    private JLabel lblVehicleType;
    private JTextField txtVehicleType;
    private JButton btnCreateVehicleType;
    private JButton btnClearField;
    private JTable jtDataTable;
    private JPanel formPanel;
    private JPanel dataPanel;
    private JPanel buttonPanel;
    private JMenu jmFile;
    private JMenu jmCustomer;
    private JMenu jmServiceDesk;
    private JMenuBar appMenuBar;
    private JMenuItem jmiMainMenu;
    private JMenuItem jmiExit;
    private JMenuItem jmiPlaceBooking;
    private JMenuItem jmiRegister;
    private JMenuItem jmiVehicleTypes;
    private JMenuItem jmiCustomerType;
    private JMenuItem jmiVehicles;
    private JMenuItem jmiCustomers;
    private JMenuItem jmiManageBookings;
    private CustomDataTable customDataTable;
    public VehicleTypes() {
        drawForm();
    }
    public void drawForm() {
        customDataTable = new CustomDataTable();
        jtDataTable = new JTable(customDataTable);
        /*Drawing root menu*/
        jmFile = new JMenu("File");
        jmCustomer = new JMenu("Customer");
        jmServiceDesk = new JMenu("Service Desk");
        appMenuBar = new JMenuBar();
        /*Drawing File Menu*/
        jmiMainMenu = new JMenuItem("Main Menu");
        jmiExit = new JMenuItem("Exit");
        jmFile.add(jmiMainMenu);
        jmFile.add(jmiExit);
        /*Drawing Customer Menu*/
        jmiPlaceBooking = new JMenuItem("Place Booking");
        jmiRegister = new JMenuItem("Register");
        jmCustomer.add(jmiPlaceBooking);
        jmCustomer.add(jmiRegister);
        /*Drawing Service Desk Menu*/
        jmiVehicleTypes = new JMenuItem("Vehicle Types");
        jmiCustomerType = new JMenuItem("Customer Types");
        jmiVehicles = new JMenuItem("Vehicles");
        jmiCustomers = new JMenuItem("Customers");
        jmiManageBookings = new JMenuItem("Manage Bookings");
        jmServiceDesk.add(jmiVehicleTypes);
        jmServiceDesk.add(jmiCustomerType);
        jmServiceDesk.add(jmiVehicles);
        jmServiceDesk.add(jmiCustomers);
        jmServiceDesk.add(jmiManageBookings);
        /*Add menus to menubar*/
        appMenuBar.add(jmFile);
        appMenuBar.add(jmCustomer);
        appMenuBar.add(jmServiceDesk);
        /*Adding listeners for each element*/
        jmiMainMenu.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiExit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiPlaceBooking.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiRegister.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiVehicleTypes.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiCustomerType.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiVehicles.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiCustomers.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        jmiManageBookings.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        lblVehicleType = new JLabel("Vehicle Type");
        txtVehicleType = new JTextField();
        btnCreateVehicleType = new JButton("Create");
        btnClearField = new JButton("Clear Fields");
        formPanel = new JPanel();
        dataPanel = new JPanel();
        buttonPanel = new JPanel();
        setSize(800, 600);
        setTitle("Vehicle Types");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //Centering the application on screen
        Toolkit toolkit = getToolkit();
        Dimension size = toolkit.getScreenSize();
        setLocation(size.width / 2 - getWidth() / 2,
                size.height / 2 - getHeight() / 2);
        formPanel.add(lblVehicleType);
        formPanel.add(txtVehicleType);
        dataPanel.add(new JScrollPane(jtDataTable));
        buttonPanel.add(btnCreateVehicleType);
        buttonPanel.add(btnClearField);
        /*Setting layouts for panels*/
        formPanel.setLayout(new GridLayout(1, 1, 0, 0));
        dataPanel.setLayout(new GridLayout(1, 2, 10, 10));
        buttonPanel.setLayout(new GridLayout(2, 1, 5, 5));
        /*Adding panels to main jframe*/
        add(dataPanel, BorderLayout.NORTH);
        add(formPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
        setJMenuBar(appMenuBar);
        //Adding buttons to listeners
        btnCreateVehicleType.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
        btnClearField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formListener(e);
            }
        });
    }
    private class CustomDataTable extends AbstractTableModel {
        private VehicleService vehicleService = new VehicleService();
        int rowCount = vehicleService.retrieveVehicleTypes().size();
        private String[] columnNames = {"Vehicle Type"};
        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }
        @Override
        public int getRowCount() {
            return rowCount;
        }
        @Override
        public int getColumnCount() {
            return columnNames.length;
        }
        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Object val = (Object) vehicleService.retrieveVehicleTypes().get(rowIndex);
            return val;
        }
        public void insertData(String values) {
            vehicleService.createVehicleType(values);
            fireTableDataChanged();
            System.out.println("affected data" + vehicleService.retrieveVehicleTypes().toString());
        }
    }
    public void clearFields() {
        txtVehicleType.setText("");
    }
    public void formListener(ActionEvent e) {
        VehicleService vehicleService = new VehicleService();
        String clickedItem = e.getActionCommand();
        String vehicleType = txtVehicleType.getText().toString();
        if (clickedItem.equals("Create")) {
            if (vehicleService.checkVehicleTypeAvailability(vehicleType)) {
                JOptionPane.showMessageDialog(null, vehicleType + "  Vehicle type already exists in Database",
                        "Vehicle Warning",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                customDataTable.insertData(vehicleType);
                this.invalidate();
                this.validate();
                this.repaint();
                this.revalidate();
                jtDataTable.revalidate();
                jtDataTable.repaint();
            }
        }
        if (clickedItem.equals("Clear Fields")) {
            //clear field code
            clearFields();
        }
        //Jmenu listener
        if (clickedItem.equals("Main Menu")) {
            VehicleTypes customerTypes = new VehicleTypes();
            CustomerManagement customerManagement = new CustomerManagement();
            customerTypes.setVisible(false);
            customerManagement.setVisible(true);
        }
        if (clickedItem.equals("Exit")) {
            int dialogButton = JOptionPane.YES_NO_OPTION;
            int dialogResult = JOptionPane.showConfirmDialog(null, "Are you sure to leave the application", "Confim Process", dialogButton);
            if (dialogResult == 0) {
                System.exit(1);
            }
        }
        if (clickedItem.equals("Place Booking")) {
        }
        if (clickedItem.equals("Register")) {
        }
        if (clickedItem.equals("Vehicle Types")) {
            //dont do anything
        }
        if (clickedItem.equals("Customer Types")) {
            CustomerTypes customerTypes = new CustomerTypes();
            this.setVisible(false);
            customerTypes.setVisible(true);
        }
        if (clickedItem.equals("Vehicles")) {
        }
        if (clickedItem.equals("Customers")) {
        }
        if (clickedItem.equals("Manage Bookings")) {
        }
    }//Action listener end curly brace
    public static void main(String[] args) {
        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 ex) {
            System.out.println("Exception Caught " + ex);
        } catch (InstantiationException ex) {
            System.out.println("Exception Caught " + ex);
        } catch (IllegalAccessException ex) {
            System.out.println("Exception Caught " + ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            System.out.println("Exception Caught " + ex);
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new VehicleTypes().setVisible(true);
            }
        });
    }
}

此方法没有很好地实现:

public void insertData(String values) {
    vehicleService.createVehicleType(values);
    fireTableDataChanged(); // No, call fireTableRowsInserted(...) instead
    ...
}

调用fireTableDateChanged()在这一点上是多余和不必要的,因为您似乎在表中添加了一行。正确的实现应该调用fireTableRowsInserted(int firstRow,int lastRow),如下所示:

public void insertData(String values) {
    vehicleService.createVehicleType(values);
    int lastIndex = vehicleService.retrieveVehicleTypes().size() - 1;
    fireTableRowsInserted(lastIndex, lastIndex); // first and last indices are the same
}

此外,在向表模型添加新行之后,不需要revalidate()repaint()。只需通知监听器就足够了:JTable是自己模型的监听器,并将相应地在TableModelEvents上重新绘制自己。

最新更新