【问题标题】:Difficulty populating a JComboBox难以填充 JComboBox
【发布时间】:2019-08-13 01:33:41
【问题描述】:

几周前我开始为一个个人项目编程(MKUltra 在美国政治运动中通过潜意识信息学习编码),所以不要犹豫,像野兽一样撕开我的愚蠢错误,撕开最嫩的嫩芽。

我正在尝试从 ArrayList 填充 JComboBox,我已经在这里解决了一堆可能的解决方案和类似问题,并得出了一个看起来应该可行的解决方案 - 从 ArrayList 填充模型和然后用该模型实例化 ComboBox - 但没有。这是sn-p:

public class Window {   

    public Window() {
        JFrame frame = new JFrame();        
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);      
        frame.getContentPane().setForeground(Color.DARK_GRAY);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ArrayList<String> yearList = new ArrayList<String>();
        yearList.add("2019");
        StackExchangeQ.setYears(yearList);
        StackExchangeQ fakePanel = new StackExchangeQ();        
        frame.add(fakePanel);       
        frame.pack();       
        frame.setVisible(true);
    }
}
public class StackExchangeQ extends JPanel {
private static ArrayList<String> yearList = new ArrayList<String>();

    public static void setYears(ArrayList<String> userYears) {     
        for(int i = 0; i < userYears.size(); i++) {
            yearList.add(userYears.get(i));         
        }
    }

    public void StackExchangeQ() {
        this.setLayout(new BorderLayout());
        JPanel menuPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));     
        this.add(menuPanel, BorderLayout.PAGE_START); 

        DefaultComboBoxModel<String> yearModel = new DefaultComboBoxModel<>();
        yearModel.addElement("All");
        for(int i = 1; i < yearList.size(); i++) {
            yearModel.addElement(yearList.get(i));
            System.out.println(yearModel.getElementAt(i));
        }
        JComboBox<String> yearSelect = new JComboBox<String>(yearModel);     
        menuPanel.add(yearSelect, BorderLayout.PAGE_START);
    }
}

基本上,它应该显示从文本字段输入中获取并输入到 yearList ArrayList 的年份列表。在填充模型之前,我已经检查了信息流 (?),但在我尝试填充组合框时它失败了。

***OKAY 在编辑这个以创建一个最小的可重现示例时,我发现似乎是问题所在,因为一周前当我真正开始时,我无法将 ArrayList 正确传递给 StackExchangeQ 对象原因和我的 hack 是在后者中将其设为静态字段,并在创建实例之前调用静态方法 setYears(),正如您在上面的示例 lmao 中看到的那样。使 ArrayList 成为一个非静态字段并正确传递它似乎使 ComboBox 以某种方式工作(但它对我来说仍然是一个黑盒子)。

【问题讨论】:

  • 在我尝试填充组合框时它失败了 - 我不知道“失败”对你意味着什么。 1) 您是否看到 System.out.println(...) 中的值? 2)您正在使用 FlowLayout,但您尝试使用 BorderLayout.PAGE_START 约束。您不能在另一个布局管理器中使用来自特定布局管理器的约束。 3) 当您将组件添加到可见 GUI 时,您需要 revalidate() 将组件添加到的面板。 4)您在此处发布的代码仅显示如何将组合框添加到面板,您没有显示面板添加到框架的位置。发布minimal reproducible example
  • 抱歉,“失败”是指我可以使用 System.out.println 看到模型的值,但组合框仍然为空。我的布局似乎没有任何问题 - “StackExchangeQ”面板被添加到调用“StackExchangeQ”的类中的框架中,并且我正在添加带有 FlowLayout 的“menuPanel”JPanel ,到“StackExchangeQ”的PAGE_START(扩展JPanel),这样我就可以在这个区域放置多个组件。不要认为这是一个错误,但感谢您提供有关 revalidate() 的提示,我将对其进行编辑,使其成为一个可重现的最小示例。

标签: java swing jcombobox


【解决方案1】:

问题在这里:public void StackExchangeQ()。不应该是public StackExchangeQ() (构造函数),以便在创建对象时启动面板?否则,您将不得不:

StackExchangeQ fakePanel = new StackExchangeQ();
fakePanel.StackExchangeQ();
frame.add(fakePanel);

另外,您不需要将yearList 声明为static。实际上,您甚至不必拥有yearList。只需将组合框的模型声明为字段并将字符串填充到模型中即可。

这就是我的意思:

public class Window {
    public static class StackExchangeQ extends JPanel {
        private DefaultComboBoxModel<String> yearModel;

        public void setYears(ArrayList<String> userYears) {
            yearModel.removeAllElements();
            userYears.forEach(yearModel::addElement);
        }

        public StackExchangeQ() {
            this.setLayout(new BorderLayout());
            JPanel menuPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            this.add(menuPanel, BorderLayout.PAGE_START);

            yearModel = new DefaultComboBoxModel<>();
            JComboBox<String> yearSelect = new JComboBox<String>(yearModel);
            menuPanel.add(yearSelect, BorderLayout.PAGE_START);
        }
    }

    public Window() {
        JFrame frame = new JFrame();
        frame.getContentPane().setForeground(Color.DARK_GRAY);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ArrayList<String> yearList = new ArrayList<String>();
        yearList.add("All");
        yearList.add("2019");
        StackExchangeQ fakePanel = new StackExchangeQ();
        fakePanel.setYears(yearList);
        frame.add(fakePanel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Window());
    }
}

【讨论】:

  • 问题确实是缺少构造函数以及由此导致的Static的误用。至于ArrayList,我从一个JTextField 中获取值,对于我来说以最小化的形式将它包含在此处有点太复杂了。感谢您的宝贵时间!
  • 只是好奇,将DefaultComboBoxModel 添加为字段的原因是什么?
  • @mudeffigy 如果没有将模型作为字段,我将无法在 setYears 方法中访问它并填充数据。 (实际上,我会,但以一种愚蠢的非必需方式)。
猜你喜欢
  • 1970-01-01
  • 2014-10-03
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 2019-08-14
相关资源
最近更新 更多