java—侦听器中的变量不会更改

2j4z5cfb  于 2021-08-20  发布在  Java
关注(0)|答案(2)|浏览(480)

我正在尝试设计一个包含jdbc和swing的小java软件。我当前的问题是,我在一个按钮侦听器中更改了模型和表,但在另一个用于表的侦听器中,这两个变量仍然保持不变。模型和表都是静态的,可以从类中的任何位置访问。我查看了调试器,它显示变量在监听器外部发生了更改,但在监听器内部,变量仍然没有更改。为什么会发生这种情况?如何解决?
这个描述可能不够清楚,下面是一个更详细的问题产生过程:
表和模型存储在这里,它们是全局和静态的:

public class MainView extends JFrame {

    private static UserService userService = new UserService();
    private static ItemService itemService = new ItemService();
    private static JTable table;
    private static JScrollPane tableScrollPane;
    private static NewTableModel model = new NewTableModel(null);
    private static JTextArea textArea = new JTextArea();
    public MainView() {

    }
    public void addFrm() {
      //here's where the main view window and listeners were put, this function will be called when the window needs to be displayed
    }
}

下面是一个表侦听器,它可以查找选定的行,并可以提取选定行的文本。每行对应一个类,该类存储一段文本。

table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (!e.getValueIsAdjusting()) {
            if ((table.getSelectedRow() > table.getRowCount()) || (table.getSelectedRow() < 0)) {
                textArea.setText("");
            }//every time after the table changed, the model will be changed, sometimes the row that user selected before the table might become unavailable which could cause invalid index
            else {
                textArea.setText(model.getNote(table.convertRowIndexToModel(table.getSelectedRow())));
            }
        }
    }
});

这是我前面提到的按钮侦听器,当单击此按钮时,将显示一个新窗口,用户可以在该新窗口中操作mysql数据库。这部分应该没有问题,因为数据可以正确写入mysql数据库。关闭此窗口后,窗口中会有一个窗口侦听器,它将调用 update() 新窗口关闭时的函数。

jb1.addActionListener(new ActionListener() {//Add some items
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        AddView addView = new AddView("adder");
        addView.addFrm();//new Window was stored in the other class
        addView.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                update();
                super.windowClosing(e);
            }
        });
    }
});

这是我的建议 update() 功能:

public static void update(){
    String item = Objects.requireNonNull(comboBox.getSelectedItem()).toString();
     //this is used to select different item from catagories
    List<ItemInfo> list = itemService.getSelectedItem(item);
     //this is used to get a item list from database
    model.setItemInfo(list);//model has been override, it has a item list that stores list
    model.fireTableDataChanged();
    model.fireTableStructureChanged();
    table.setModel(model);//give a new model to the table
    table.validate();//update the table
    table.updateUI();
    tableScrollPane.validate();//table is put in a scrollpane, so update it as well
    tableScrollPane.updateUI();
    table.clearSelection();
}

问题是,如果我从表中选择一行,然后单击按钮并打开一个新窗口来添加内容。在我关闭新窗口后,该内容被正确添加。模型也通过更新功能更新,但在我关闭新窗口后会出现异常。它显示indexoutofboundsexception。

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index 18 out of bounds for length 18
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:372)
    at java.base/java.util.ArrayList.get(ArrayList.java:458)
    at com.Other.NewTableModel.getValueAt(NewTableModel.java:35)

但是,如果我只单击了按钮,但没有选择表中的任何行,程序将正常工作:新窗口关闭后,表也将刷新。
我检查了调试器,发现这是由于在我调用了 update() ,模型已在任何位置更新,侦听器中的零件除外。此侦听器中的模型保持不变,没有更改。这怎么会发生?只有一个模型是完全相同的变量,它是静态的和全局的。有人能帮我吗?
有些描述可能不清楚,因为我不会说英语,但如果你要求更多,我可以解释。
一些新增代码newtablemodel:

import com.Model.ItemInfo;
import javax.swing.table.AbstractTableModel;
import java.util.List;

public class NewTableModel extends AbstractTableModel {

    private List<ItemInfo> itemInfo;
    private String[] column = new String[]{"Id","Name","Type","Number","Exp_Date","Adder","Exp.(day)","Added_Date"};

    public NewTableModel(List<ItemInfo> itemInfo){
        this.itemInfo = itemInfo;
    }

    public void setItemInfo(List<ItemInfo> itemInfo) {
        this.itemInfo = itemInfo;
    }

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

    @Override
    public int getColumnCount() {
        return column.length;
    }

    @Override
    public Object getValueAt(int r, int c) {
        Object data = "";
        switch (c){
            case 0:
                data = itemInfo.get(r).getItem_id().toString();
                break;
            case 1:
                data = itemInfo.get(r).getItem_name();
                break;
            case 2:
                data = itemInfo.get(r).getItem_type();
                break;
            case 3:
                data = itemInfo.get(r).getItem_number().toString();
                break;
            case 4:
                if(itemInfo.get(r).getItem_date() == null){
                    return "Not Available";
                }
                data = itemInfo.get(r).getItem_date().toString();
                break;
            case 5:
                data = itemInfo.get(r).getItem_adder();
                break;
            case 6:
                data = itemInfo.get(r).getItem_expDay();
                break;
            case 7:
                data = itemInfo.get(r).getItem_add_date();
        }
        return data;

    }

    @Override
    public String getColumnName(int column) {
        return this.column[column];
    }

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

    public String getNote(int row){
        return itemInfo.get(row).getItem_notes();
    }

    public int getId(int row){
        return itemInfo.get(row).getItem_id();
    }
}

这里有完整的斯塔克追踪:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index 19 out of bounds for length 19
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:372)
    at java.base/java.util.ArrayList.get(ArrayList.java:458)
    at com.Other.NewTableModel.getNote(NewTableModel.java:76)
    at com.View.MainView$2.valueChanged(MainView.java:163)
    at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:219)
    at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:186)
    at java.desktop/javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:723)
    at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.setValueIsAdjusting(BasicTableUI.java:972)
    at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(BasicTableUI.java:1185)
    at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6651)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6416)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5026)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2773)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
gj3fmq9x

gj3fmq9x1#

从[full]堆栈跟踪,方法 valueChanged 是调用方法吗 getNote(int) 并传递参数的无效值(根据堆栈跟踪,传递的值为19,并且 itemInfo 是19岁)。
调用 getNote :

textArea.setText(model.getNote(table.convertRowIndexToModel(table.getSelectedRow())));

你需要调试你的代码,看看有什么价值 table.getSelectedRow() 他回来了。然后你需要看看什么是价值 table.convertRowIndexToModel(table.getSelectedRow()) 他回来了。然后,您需要找出它返回无效值的原因。
如果您希望我帮助您调试代码,那么您需要发布一个最小的、可复制的示例。

zte4gxcn

zte4gxcn2#

我刚刚解决了这个问题,我想这是由一些过时的库引起的,我更新了它们,但是bug还是消失了。谢谢你帮助我。

相关问题