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

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

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

  1. public class MainView extends JFrame {
  2. private static UserService userService = new UserService();
  3. private static ItemService itemService = new ItemService();
  4. private static JTable table;
  5. private static JScrollPane tableScrollPane;
  6. private static NewTableModel model = new NewTableModel(null);
  7. private static JTextArea textArea = new JTextArea();
  8. public MainView() {
  9. }
  10. public void addFrm() {
  11. //here's where the main view window and listeners were put, this function will be called when the window needs to be displayed
  12. }
  13. }

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

  1. table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
  2. @Override
  3. public void valueChanged(ListSelectionEvent e) {
  4. if (!e.getValueIsAdjusting()) {
  5. if ((table.getSelectedRow() > table.getRowCount()) || (table.getSelectedRow() < 0)) {
  6. textArea.setText("");
  7. }//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
  8. else {
  9. textArea.setText(model.getNote(table.convertRowIndexToModel(table.getSelectedRow())));
  10. }
  11. }
  12. }
  13. });

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

  1. jb1.addActionListener(new ActionListener() {//Add some items
  2. @Override
  3. public void actionPerformed(ActionEvent actionEvent) {
  4. AddView addView = new AddView("adder");
  5. addView.addFrm();//new Window was stored in the other class
  6. addView.addWindowListener(new WindowAdapter() {
  7. @Override
  8. public void windowClosing(WindowEvent e) {
  9. update();
  10. super.windowClosing(e);
  11. }
  12. });
  13. }
  14. });

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

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

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

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

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

  1. import com.Model.ItemInfo;
  2. import javax.swing.table.AbstractTableModel;
  3. import java.util.List;
  4. public class NewTableModel extends AbstractTableModel {
  5. private List<ItemInfo> itemInfo;
  6. private String[] column = new String[]{"Id","Name","Type","Number","Exp_Date","Adder","Exp.(day)","Added_Date"};
  7. public NewTableModel(List<ItemInfo> itemInfo){
  8. this.itemInfo = itemInfo;
  9. }
  10. public void setItemInfo(List<ItemInfo> itemInfo) {
  11. this.itemInfo = itemInfo;
  12. }
  13. @Override
  14. public int getRowCount() {
  15. return itemInfo.size();
  16. }
  17. @Override
  18. public int getColumnCount() {
  19. return column.length;
  20. }
  21. @Override
  22. public Object getValueAt(int r, int c) {
  23. Object data = "";
  24. switch (c){
  25. case 0:
  26. data = itemInfo.get(r).getItem_id().toString();
  27. break;
  28. case 1:
  29. data = itemInfo.get(r).getItem_name();
  30. break;
  31. case 2:
  32. data = itemInfo.get(r).getItem_type();
  33. break;
  34. case 3:
  35. data = itemInfo.get(r).getItem_number().toString();
  36. break;
  37. case 4:
  38. if(itemInfo.get(r).getItem_date() == null){
  39. return "Not Available";
  40. }
  41. data = itemInfo.get(r).getItem_date().toString();
  42. break;
  43. case 5:
  44. data = itemInfo.get(r).getItem_adder();
  45. break;
  46. case 6:
  47. data = itemInfo.get(r).getItem_expDay();
  48. break;
  49. case 7:
  50. data = itemInfo.get(r).getItem_add_date();
  51. }
  52. return data;
  53. }
  54. @Override
  55. public String getColumnName(int column) {
  56. return this.column[column];
  57. }
  58. @Override
  59. public boolean isCellEditable(int rowIndex, int columnIndex) {
  60. return false;
  61. }
  62. public String getNote(int row){
  63. return itemInfo.get(row).getItem_notes();
  64. }
  65. public int getId(int row){
  66. return itemInfo.get(row).getItem_id();
  67. }
  68. }

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

  1. Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index 19 out of bounds for length 19
  2. at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
  3. at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
  4. at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
  5. at java.base/java.util.Objects.checkIndex(Objects.java:372)
  6. at java.base/java.util.ArrayList.get(ArrayList.java:458)
  7. at com.Other.NewTableModel.getNote(NewTableModel.java:76)
  8. at com.View.MainView$2.valueChanged(MainView.java:163)
  9. at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:219)
  10. at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:186)
  11. at java.desktop/javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:723)
  12. at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.setValueIsAdjusting(BasicTableUI.java:972)
  13. at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(BasicTableUI.java:1185)
  14. at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
  15. at java.desktop/java.awt.Component.processMouseEvent(Component.java:6651)
  16. at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
  17. at java.desktop/java.awt.Component.processEvent(Component.java:6416)
  18. at java.desktop/java.awt.Container.processEvent(Container.java:2263)
  19. at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5026)
  20. at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
  21. at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
  22. at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
  23. at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
  24. at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
  25. at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
  26. at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2773)
  27. at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
  28. at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
  29. at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
  30. at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
  31. at java.base/java.security.AccessController.doPrivileged(Native Method)
  32. at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
  33. at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
  34. at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
  35. at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
  36. at java.base/java.security.AccessController.doPrivileged(Native Method)
  37. at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
  38. at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
  39. at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
  40. at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
  41. at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
  42. at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
  43. at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
  44. at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
gj3fmq9x

gj3fmq9x1#

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

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

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

zte4gxcn

zte4gxcn2#

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

相关问题