DefaultListModel.clear 错误

发布于 2024-10-20 12:54:36 字数 1878 浏览 4 评论 0原文

我正在尝试显示项目列表,并且当用户单击某个项目时,清除该列表并显示另一个列表。

如果我运行它并单击显示列表上的第一个条目,程序就会因一长串运行时异常而终止。如果我删除clear()行(下面注释),它运行正常。添加 try/catch 没有透露任何对我有用的信息。对长代码表示歉意,但我不知道如何缩短并仍然生成错误。

我做错了什么?

import java.util.*;

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class ListGui extends JPanel implements ListSelectionListener {

    private static JList list;
    private static DefaultListModel listModel = new DefaultListModel();

    public ListGui() {
        super(new BorderLayout());
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(this);
        JScrollPane listScrollPane = new JScrollPane(list);
        add(listScrollPane, BorderLayout.CENTER);
    }

    public static void Populate(List<String> lines) {
        listModel.clear();
        for(String line : lines) {
            listModel.addElement(line);
        }
    }

    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting() == false) {
            List<String> out = new ArrayList<String>();
            out.add("three");
            out.add("four");
            Populate(out);
        }
    } 
}

public class TestClear {

    static JComponent newContentPane = new ListGui();

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("toast");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) { 

        List<String> out = new ArrayList<String>();

        createAndShowGUI();

        out.add("one");
        out.add("two");
        ListGui.Populate(out);               
    }
}

I'm trying to display a list of items and, when the user clicks on an item, to clear the list and display another list.

If I run this and click on the first entry on the displayed list, the program dies with a long trail of runtime exceptions. If I remove the clear() line (commented below), it runs fine. Adding try/catch didn't reveal any information useful to me. Apologies for the long code, but I couldn't figure out how to shorten and still generate the errors.

What at I doing wrong?

import java.util.*;

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class ListGui extends JPanel implements ListSelectionListener {

    private static JList list;
    private static DefaultListModel listModel = new DefaultListModel();

    public ListGui() {
        super(new BorderLayout());
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(this);
        JScrollPane listScrollPane = new JScrollPane(list);
        add(listScrollPane, BorderLayout.CENTER);
    }

    public static void Populate(List<String> lines) {
        listModel.clear();
        for(String line : lines) {
            listModel.addElement(line);
        }
    }

    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting() == false) {
            List<String> out = new ArrayList<String>();
            out.add("three");
            out.add("four");
            Populate(out);
        }
    } 
}

public class TestClear {

    static JComponent newContentPane = new ListGui();

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("toast");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) { 

        List<String> out = new ArrayList<String>();

        createAndShowGUI();

        out.add("one");
        out.add("two");
        ListGui.Populate(out);               
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静若繁花 2024-10-27 12:54:36

我正在尝试显示一个项目列表,当用户单击某个项目时,清除该列表并显示另一个列表。

对我来说这听起来不是最好的设计。每当您单击某个项目或使用箭头键在列表中向上或向下移动时,选择都会发生变化。我确信对于喜欢使用键盘的用户来说,您不希望每次使用箭头键时列表都会更改。

正常的设计是通过“双击”或当用户从键盘上“输入”时调用列表上的操作。使用列表操作概念可以轻松实现这一点。

但是,如果您确实想更新每个选择的列表,那么我会使用如下代码:

list.removeListSelectionListener( this );
populate(...);
list.addListSelectionListener(this); 

I'm trying to display a list of items and, when the user clicks on an item, to clear the list and display another list.

That doesn't sound like the best design to me. The selection will change whenever you click on an item or when you use the arrow keys to move up or down the list. I'm sure for users that like to use the keyboard you don't want the list to change every time you use an arrow key.

The normal design would be to invoke an Action on the list on a "double click" or when the user users "Enter" from the keboard. This is easily implemente using the List Action concept.

However, if you really do want to update the list on every selection then I would use code like:

list.removeListSelectionListener( this );
populate(...);
list.addListSelectionListener(this); 
脸赞 2024-10-27 12:54:36

问题是您在 valueChanged() 中调用 Populate() ,这会触发 valueChanged() ,从而触发堆栈溢出。

最简单的解决方案是设置一个标志来防止重入。

 boolean busy = false;
    public void valueChanged(ListSelectionEvent e) {

        if (e.getValueIsAdjusting() == false && !busy) {
            busy = true;
            List<String> out = new ArrayList<String>();
            out.add("three");
            out.add("four");
            Populate(out);
            busy = false;
        }
    } 

如果您的代码可以由多个线程访问,您应该查看 可重入锁

The problem is that you are calling Populate() in valueChanged() which triggers valueChanged() and hence the stackoverflow.

The simplest solution is to have a flag to prevent reentry.

 boolean busy = false;
    public void valueChanged(ListSelectionEvent e) {

        if (e.getValueIsAdjusting() == false && !busy) {
            busy = true;
            List<String> out = new ArrayList<String>();
            out.add("three");
            out.add("four");
            Populate(out);
            busy = false;
        }
    } 

If your code could be accessed by multiple threads, you should be looking into ReentrantLock

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文