Can't get ListCellRenderer to function properly

296 views Asked by At

I posted a question earlier today and was directed by MadProgrammer to use ListCellRenderer to achieve the desired results. I have it almost working, but it is showing the same entry twice in the combobox and I don't know why. Please help me solve this riddle. The code:

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;
        }
    }
}

As you can see there are 2 additions to the ArrayList. I am limiting the display in the combobox to only show the course number, but Course2 is showing up twice and when I print out the contents of the ArrayList I see all the details for Course2 shown twice and none for Course1. Any help would be greatly appreciated. Cheers

1

There are 1 answers

3
camickr On BEST ANSWER

Using a custom renderer is only half of the solution. A custom renderer will break the default items selection by using the keyboard of a combo box. See Combo Box With Custom Renderer for more information and a more complete solution.

The main problem with your code is the NotWorking class. This class should NOT extend JPanel. It is just a class that is used to hold the 3 properties of the class. The course number, title and level should NOT be static variables. There should be no reference to Swing components.

Your design should be one class for the NotWorking class and another class to create the GUI.

Start with the section from the Swing tutorial on How to Use Combo Boxes for a better design. Then customize the ComboBoxDemo.java example code from the tutorial to add your NotWorking class to the combo box instead of adding String data.