RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 613738
Accepted
S. Oleg
S. Oleg
Asked:2020-01-12 18:03:56 +0000 UTC2020-01-12 18:03:56 +0000 UTC 2020-01-12 18:03:56 +0000 UTC

为什么AbstractListModel会出现IndexOutOfBoundsException

  • 772

如果我在线程中运行它会出现异常,但如果没有线程它似乎不会出现。如何修复它以使其没有错误。


线程“AWT- EventQueue -0”中的异常 java.lang.IndexOutOfBoundsException:索引:1,大小
:
0 MyListModel.getElementAt(MyListModel.java:31)
在 ta.MyListModel.getElementAt(MyListModel.java:1)
在 javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
在 javax.swing.plaf.basic.BasicListUI。 maybeUpdateLayoutState(未知来源)
在 javax.swing.plaf.basic.BasicListUI.getPreferredSize(未知来源)
在 javax.swing.JComponent.getPreferredSize(未知来源)
在 javax.swing.ScrollPaneLayout.layoutContainer(未知来源)
在 java.awt.Container.layout(未知来源)
在 java.awt.Container.doLayout(未知来源)
在 java.awt.Container.validateTree(未知来源)
在 java.awt.Container.validate(未知来源)
在 javax .swing.RepaintManager$3.run(未知来源)
在 javax.swing.RepaintManager$3.run(未知来源)
在 java.security.AccessController.doPrivileged(本地方法)
在 java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(未知来源)
在 javax.swing.RepaintManager.validateInvalidComponents(未知来源)
在 javax.swing.RepaintManager$ProcessingRunnable.run(未知来源)
在 java.awt.event.InvocationEvent.dispatch(未知来源)
在 java.awt.EventQueue.dispatchEventImpl(未知来源)
在 java.awt.EventQueue.access$500(未知来源)
在 java.awt.EventQueue$3.run(未知来源)在 java.awt.EventQueue
$3.run(未知来源) 在
java.security.AccessController.doPrivileged(本机方法)未知来源) 在 java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForFilter(未知来源)




在 java.awt.EventDispatchThread.pumpEventsForHierarchy(未知来源)
在 java.awt.EventDispatchThread.pumpEvents(
未知来源)
在 java.awt.EventDispatchThread.pumpEvents(未知来源)

模型类

package ta;

import java.math.BigDecimal;
import java.util.LinkedList;

import javax.swing.AbstractListModel;

public class MyListModel extends AbstractListModel<String>{

private static final long serialVersionUID = 1L;
private LinkedList<BigDecimal> listBets;

public LinkedList<BigDecimal> getListBets() {
    return listBets;
}

public void setListBets(LinkedList<BigDecimal> listBets) {
    this.listBets = listBets;
}

public MyListModel(LinkedList<BigDecimal> list) {
    setList(list);
}

public void add(BigDecimal value){
    getList().add(value);
    refresh();      
}

public String getElementAt(int index) {
    return String.format("%.8f", getList().get(index));
}

public int getSize() {
    return getList().size();
}

public LinkedList<BigDecimal> getList(){
    return listBets;
}

public void setList(LinkedList<BigDecimal> list){
    this.listBets = list;
    refresh();
}

public void clear() {
    getList().clear();
    refresh();
}

public void removeSide() {
        getList().removeLast();
        getList().removeFirst();
        refresh();
}

void removeLast(){
    getList().removeLast();
    refresh();
}

public void refresh() {
        fireContentsChanged(this, 0, getSize());
}
}

有主要方法的类

package ta;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;

import javax.swing.JTextArea;

import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.text.ParseException;
import java.awt.event.ActionEvent;

public class TA {

private JFrame frame;
private MyListModel listModelBets;
private JList<String> list;
private JTextArea textArea;
private final String defaultBets = "0.00000001\n0.00000001\n0.00000001\n0.00000001\n0.00000001";
private final boolean win = true;
private final boolean lose = false;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                TA window = new TA();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public TA() {
    listModelBets = new MyListModel(new LinkedList<>());
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new BorderLayout(0, 0));

    JPanel panel_2 = new JPanel();
    frame.getContentPane().add(panel_2);
    panel_2.setLayout(new GridLayout(0, 2, 0, 0));

    JPanel panel_1 = new JPanel();
    panel_2.add(panel_1);
    panel_1.setLayout(new BorderLayout(0, 0));

    JScrollPane scrollPane = new JScrollPane();
    panel_1.add(scrollPane);

    textArea = new JTextArea(defaultBets);
    scrollPane.setViewportView(textArea);

    JPanel panel = new JPanel();
    panel_2.add(panel);
    panel.setLayout(new BorderLayout(0, 0));

    JScrollPane scrollPane_1 = new JScrollPane();
    panel.add(scrollPane_1);

    list = new JList<String>(listModelBets);
    scrollPane_1.setViewportView(list);

    JPanel panel_3 = new JPanel();
    frame.getContentPane().add(panel_3, BorderLayout.SOUTH);

    JButton btnNewButton_1 = new JButton("Clear");
    btnNewButton_1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            listModelBets.clear();
        }
    });
    panel_3.add(btnNewButton_1);

    JButton btnPlay = new JButton("Play");
    btnPlay.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            Thread th = new Thread(new Runnable() {

                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        boolean result = play();
                        if (result) {
                            if (listModelBets.getSize() == 1) {
                                listModelBets.removeLast();
                            } else if (listModelBets.getSize() > 1) {
                                listModelBets.removeSide();
                            }
                        } else {
                            listModelBets.add(getBet());
                        }
                    }
                }
            });
            th.start();
        }
    });
    panel_3.add(btnPlay);
}

void addBets() {
    Scanner sc = new Scanner(textArea.getText());
    sc.useDelimiter("\\n");
    while (sc.hasNext()) {
        String s = sc.next();
        if (s != null && !s.equals("")) {
            try {
                BigDecimal b = new BigDecimal(s);
                listModelBets.add(b);
            } catch (NumberFormatException ex) {
                // JOptionPane.showMessageDialog(frame, "Enter number
                // value.\nSample 0.00000001");
            }

        }
    }
    sc.close();
}

boolean play() {
    Random rnd = new Random();
    return rnd.nextBoolean();
}

BigDecimal getBet() {
    BigDecimal sum = null;
    if (listModelBets.getSize() > 0) {
        sum = calcSum();
    } else {
        addBets();
        sum = calcSum();
    }
    return sum;
}

BigDecimal calcSum() {
    BigDecimal sum = null;
    try {
        BigDecimal first = listModelBets.getList().getFirst();
        BigDecimal last = listModelBets.getList().getLast();
        sum = first.add(last);
    } catch (NoSuchElementException ex) {
        // stopGame();
        JOptionPane.showMessageDialog(frame, "Enter number value\nin editor bets.\nSample 0.00000001");
    }
    return sum;
}
}
java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Artem Konovalov
    2020-01-12T18:23:08Z2020-01-12T18:23:08Z

    您的问题是该模型MyListModel不是线程安全的。但是您同时从不同的线程使用它。

    在获取列表大小和获取元素时,另一个线程设法删除了这些元素。因此,发生错误。

    我看到了这个问题的几种解决方案:

    • 制作一个模型thread-safe,最简单的方法是LinkedList用包中的替代品替换它,java.util.concurrent或者声明synchronized。

    • 另一种解决方案是在一个线程中更改模型。因为 由于元素是从流中接收到的UI,因此应该从中进行删除。这需要按如下方式完成删除操作:

      for (int i = 0; i < 1000; i++) {
         boolean result = play();
         try {
               SwingUtilities.invokeAndWait(() -> {
                       if (result) {
                            if (listModelBets.getSize() == 1) {
                                listModelBets.removeLast();
                            } else if (listModelBets.getSize() > 1) {
                                listModelBets.removeSide();
                            }
                       } else {
                            listModelBets.add(getBet());
                       }
                });
         } catch (Exception e) {
               e.printStackTrace();
         }
      }
      
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5