我正在尝试设计一个包含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)
2条答案
按热度按时间gj3fmq9x1#
从[full]堆栈跟踪,方法
valueChanged
是调用方法吗getNote(int)
并传递参数的无效值(根据堆栈跟踪,传递的值为19,并且itemInfo
是19岁)。调用
getNote
:你需要调试你的代码,看看有什么价值
table.getSelectedRow()
他回来了。然后你需要看看什么是价值table.convertRowIndexToModel(table.getSelectedRow())
他回来了。然后,您需要找出它返回无效值的原因。如果您希望我帮助您调试代码,那么您需要发布一个最小的、可复制的示例。
zte4gxcn2#
我刚刚解决了这个问题,我想这是由一些过时的库引起的,我更新了它们,但是bug还是消失了。谢谢你帮助我。