【问题标题】:Can't get ListCellRenderer to function properly无法让 ListCellRenderer 正常运行
【发布时间】:2013-12-24 15:29:18
【问题描述】:

我今天早些时候发布了一个问题,并被 MadProgrammer 指示使用 ListCellRenderer 来实现预期的结果。我几乎可以使用它,但是它在组合框中两次显示相同的条目,我不知道为什么。请帮我解开这个谜。代码:

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

public class NotWorking extends JPanel {
    private JPanel editPanel;
    private JComboBox<String> editComboLevel;
    private JComboBox editCombo;
    private String[] levels = {"Level 1", "Level 2", "Level 3"}; 
    private static ArrayList<NotWorking> course = new ArrayList<NotWorking>();
    public static String courseNum, courseTitle, courseLevel;

    public JPanel createContentPane (){

        Integer[] intArray = new Integer[course.size()];
        for (int i = 0; i < course.size(); i++) {
            intArray[i] = new Integer(i);
        }

        editPanel = new JPanel(new GridLayout(4,2));
        editPanel.setPreferredSize(new Dimension(100,75));
        editPanel.add(editCombo = new JComboBox(intArray));
        ComboBoxRenderer renderer= new ComboBoxRenderer();
        editCombo.setRenderer(renderer);

        return editPanel;
        }

        NotWorking() {}
        NotWorking(String courseNum, String courseTitle, String courseLevel) {
            this.courseNum = courseNum;
            this.courseTitle = courseTitle;
            this.courseLevel = courseLevel;
        }
        @Override
        public String toString() {
            String courseInfo = getCourseNum() + ", " + getCourseTitle() + ", " + getCourseLevel();
            return courseInfo; 
        }
        public String getCourseNum() {
            return this.courseNum;          
        }
        public String getCourseTitle() {
            return this.courseTitle;
        }
        public String getCourseLevel() {
            return this.courseLevel;
        }
        public void setCourseNum(String courseNum) {
            this.courseNum = courseNum;
        }
        public void setCourseTitle(String courseTitle) {
            this.courseTitle = courseTitle; 
        }
        public void setCourseLevel(String courseLevel) {
            this.courseLevel = courseLevel;
        }

        private static void createAndShowGUI() {
            JFrame frame = new JFrame("Example of Code Snippet");
            NotWorking myCourse = new NotWorking();
            frame.setContentPane(myCourse.createContentPane());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.pack();
            frame.setVisible(true);
        }

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
            course.add(new NotWorking("Course1", "Course1 desc", "Level 1"));
            course.add(new NotWorking("Course2", "Course2 desc", "Level 2"));
            createAndShowGUI();
            for(NotWorking item : course)
                System.out.println(item);
            }
        });
    }
    class ComboBoxRenderer extends JLabel
                           implements ListCellRenderer {
        public ComboBoxRenderer() {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
        }

        public Component getListCellRendererComponent(
                                           JList list,
                                           Object value,
                                           int index,
                                           boolean isSelected,
                                           boolean cellHasFocus) {
            int selectedIndex = ((Integer)value).intValue();

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            setText(getCourseNum());

            return this;
        }
    }
}

如您所见,ArrayList 有 2 个附加项。我将组合框中的显示限制为仅显示课程编号,但是 Course2 显示了两次,当我打印出 ArrayList 的内容时,我看到 Course2 的所有详细信息显示了两次,而 Course1 则没有。任何帮助将不胜感激。干杯

【问题讨论】:

    标签: java swing arraylist jcombobox listcellrenderer


    【解决方案1】:

    使用自定义渲染器只是解决方案的一半。自定义渲染器将使用组合框的键盘破坏默认项目选择。请参阅Combo Box With Custom Renderer 了解更多信息和更完整的解决方案。

    您的代码的主要问题是 NotWorking 类。此类不应扩展 JPanel。它只是一个用于保存类的 3 个属性的类。课程编号、标题和级别不应是静态变量。不应引用 Swing 组件。

    您的设计应该是一个类用于 NotWorking 类,另一个类用于创建 GUI。

    How to Use Combo Boxes 上的 Swing 教程部分开始,以获得更好的设计。然后自定义教程中的 ComboBoxDemo.java 示例代码,将 NotWorking 类添加到组合框中,而不是添加字符串数据。

    【讨论】:

    • 感谢您的回复。我已经阅读了如何使用组合框,但我承认我并不完全理解它。我添加的用于创建渲染器的代码来自该教程。我最大的问题是我严重缺乏经验。目前我有大约 7 或 8 周的时间在 Java 编程中。我就读于农村地区的一所小型技术学院。大部分教学来自谷歌搜索并希望获得最好的结果。我会试着整理一下。干杯
    • My biggest problem is my gross lack of experience. - 这就是为什么我建议您从工作示例代码开始并对该代码进行更改。您正在尝试将应该仅用于显示 Swing 组件的 JPanel 与您的类结合起来以保存课程数据。你真的应该创建一个名为Course 的类来保存课程数据。然后创建 Course 类的实例以添加到组合框中。
    • 我会这样做的。我非常感谢您的帮助并指导我以不同的方式做事。我会试一试。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多