【问题标题】:Java JList and list problemsJava JList 和列表问题
【发布时间】:2013-08-06 09:45:11
【问题描述】:

我将列表项添加到 JList

numbersList.add("first example");
numbersList.add("second example");
numbersList.add("third example");

当我向字段添加新文本或数字时,它将被添加到列表中并显示在 JList 中。这是我的代码,当我按下按钮时,新元素出现在 JList fullList 中,来自列表numberList,这是从文本字段numberTxtFld 添加的。

p.s 我删除了一些不必要的代码。

package average;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

public class Surface extends JLabel{
    private JTextField numberTxtFld;
    private JLabel topLabel;
    private JLabel sumLabel;
    private JLabel avgLabel;
    private JLabel maxLabel;
    private JLabel minLabel;
    private JLabel amountLabel;
    private JLabel listLabel;
    private JLabel resultLabel;
    private JLabel sumAnswerFld;
    private JLabel avgAnswerFld;
    private JLabel maxAnswerFld;
    private JLabel minAnswerFld;
    private JLabel amountAnswerFld;
    private JLabel fullListLabel;
    private JList fullList;
    final List<String> numbersList = new ArrayList<String>();
    private JButton submitBtn;
    private JButton closeBtn;
    private JPanel panel;

    private int arrayIndex = 0;// used for components adding into array

    public Surface(){
        panel = new JPanel();
        panel.setBackground(Color.WHITE);
        panel.setSize(300, 300);

        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;


        topLabel = new JLabel("Enter your number and push submit");
        gbc.gridwidth = 3;
        gbc.gridx = 0; // column 
        gbc.gridy = 0; // row
        panel.add(topLabel, gbc);
        gbc.gridwidth = 1; // setting grid column with to default

        fullListLabel = new JLabel("Full list");
        gbc.gridx = 2;
        gbc.gridy = 1;
        panel.add(fullListLabel, gbc);          

        amountLabel = new JLabel("Amount");
        gbc.gridx = 0;
        gbc.gridy = 5;
        panel.add(amountLabel, gbc);

        amountAnswerFld = new JLabel("0");
        gbc.gridx = 1;
        gbc.gridy = 5;
        panel.add(amountAnswerFld, gbc);



        numberTxtFld = new JTextField();
        numberTxtFld.setColumns(10);
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel.add(numberTxtFld, gbc);       

        submitBtn = new JButton("Submit");
        gbc.gridx = 1;
        gbc.gridy = 1;
        submitBtn.addActionListener(
                new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent event) {

                        String text = numberTxtFld.getText();
                        numbersList.add(text);


                    }                   
                }
        );      
        panel.add(submitBtn, gbc);

        numbersList.add("first example");
        numbersList.add("second example");
        numbersList.add("third example");

        fullList = new JList(numbersList.toArray());
        fullList.setVisibleRowCount(6);
        fullList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        gbc.gridheight = 6;
        gbc.gridx = 2;
        gbc.gridy = 2;
        panel.add(new JScrollPane(fullList), gbc);
        gbc.gridheight = 1; // setting grid column with to default

        add(panel);


    }
}

【问题讨论】:

  • 我有点好奇您为什么要将面板添加到 JLabel。为什么不简单地扩展 JPanel?

标签: java swing list jlist


【解决方案1】:

您将需要创建一个 ListModel。由于您所做的非常简单,您可以使用 DefaultListModel。

你需要声明

private DefaultListModel defaultListModel;

并实例化它

defaultListModel = new DefaultListModel();

然后将它附加到 JLists 构造函数中的 JList

fullList = new JList(defaultListModel);

然后您需要将您的项目添加到 defaultListModel,可能是在一个循环中

for (Object o : numbersList) {
   defaultListModel.addElement(o);
}

最后,在您的动作监听器中,您现在需要调用 defaultListModel 上的 addElement 方法

String text = numberTxtFld.getText();
defaultListModel.add(text);

然后,您应该让一切按您的意愿工作,并且所有更新事件都为您处理。

【讨论】:

    【解决方案2】:

    当你这样做时:

    fullList = new JList(numbersList.toArray());
    

    您并没有将 JList 神奇地附加到 numbersList,您只是在此时使用 numbersList 的内容填充 JList,当然,其中不包括稍后按下按钮时添加的任何项目。

    您至少有三个选择:

    最基本的解决方案是在您的 submitBtn 操作侦听器中显式地将新项目添加到 fullList。你有很多选择。您可以从 submitBtn 中将新项目添加到 fullList,这很简单,并且在您的应用程序中可能就足够了。为此,请确保列表的模型是 DefaultListModel,然后您可以使用 ((DefaultListModel)getModel()).addElement() 添加项目。

    DefaultListModel model = new DefaultListModel();
    fullList.setModel(model);
    
    // to add an element (during initial population, and action listener):
    model.addElement("the element");
    

    更强大的解决方案是根据 numbersList 的当前内容完全重新填充 fullList,并从您的操作侦听器执行此操作以将 GUI 重新同步到数据。由于其他原因,这可能是不可取的,例如首先清除列表可能不可接受,因为它会影响当前项目选择等。取决于您的要求。您可以为此使用 JList 的 setListData()

    // any time you want to repopulate the list:
    fullList.setListData(numbersList.toArray());
    

    但请记住,这会将列表模型设置为 只读 模型,以后您将无法使用 getModel().addElement()。

    一个更健壮且通常首选的解决方案是实现一个反映 numbersList 内容的 ListModel,并将该 ListModel 分配给您的 JList。这可以产生非常干净的代码,让您可以在列表中执行您想要的任何操作,同时保持 GUI 和数据同步。无需在此处重新发布代码,您可以在 the answer to this question 中找到一个简单的实现。

    希望对您有所帮助。

    【讨论】:

    • 我刚刚查看了 JList 构造函数的代码,并不能保证该模型将是构造函数中的 DefaultListModel,它只是创建了一个 AbstractListModel 并覆盖了所需的方法
    • 没错,没有保证。这就是为什么我说“确保列表的模型是 DefaultListModel”。我已经用示例代码更新了答案,使其清楚。
    • 也感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2021-12-11
    • 2015-09-14
    • 2012-01-30
    • 2012-10-12
    相关资源
    最近更新 更多