Results 1 to 12 of 12
  1. #1
    geforce2000 is offline Member
    Join Date
    Dec 2009
    Posts
    9
    Rep Power
    0

    Default Custom renderer (almost works)

    I'm creating a custom JComboBox renderer. What I want it to do is display text next to a colored box. Everything works except for the default value were Its not showing the text. Anyone see the problem? Or is there a better way of doing this? Iíve included the code below:

    (Renderer: ComboBoxRenderer.java)
    Java Code:
    import java.awt.*;
    import java.util.ArrayList;
    import javax.swing.*;
    
    class ComboBoxRenderer extends JLabel implements ListCellRenderer
    {
        String[] _textLabels = {"Red", "Green", "Blue", "Orange", "Yellow", "Cyan"};
        private ArrayList _colors = null;
        private JPanel _coloredBox = null;
        private JPanel _container = null;
        private JLabel _label = null;
    
        public ComboBoxRenderer()
        {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
    
            // Text container (can't get text to show without it being contained inside another jpanel. Why is this?)
            _container = new JPanel();
            Dimension holderSize = new Dimension(80, 20);
            _container.setLocation(22, 0);
            _container.setSize(holderSize);
            _container.setOpaque(false);
            _container.setLayout(new BorderLayout());
            this.add(_container, BorderLayout.WEST);
    
            // Text
            _label = new JLabel("Disabled");
            Dimension textSize = new Dimension(80, 20);
            _label.setForeground(Color.black);
            _label.setPreferredSize(textSize);
            _label.setHorizontalAlignment(JTextField.LEFT);
            _container.add(_label, BorderLayout.WEST);
            
            // Colored box
            _coloredBox = new JPanel();
            Dimension preferredSize = new Dimension(16, 16);
            _coloredBox.setLocation(2, 2);
            _coloredBox.setSize(preferredSize);
            _coloredBox.setOpaque(true);
            this.add(_coloredBox, BorderLayout.WEST);
    
            // Initialize color list
            _colors = new ArrayList();
            _colors.add(new Color(255, 0, 0));
            _colors.add(new Color(0, 255, 0));
            _colors.add(new Color(0, 0, 255));
            _colors.add(new Color(255, 215, 0));
            _colors.add(new Color(255, 255, 0));
            _colors.add(new Color(0, 255, 255));
        }
    
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            // Get the selected index.
            int selectedIndex = ((Integer)value).intValue();
    
            // Set the background color for each element
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
    
            // Set text
            String text = _textLabels[selectedIndex];
            _label.setText(text);
            _label.setFont(list.getFont());
    
            // Set box
            Color current = (Color) _colors.get(selectedIndex);
            _coloredBox.setBackground(current);
    
            return this;
        }
    }
    (Main: CustomComboBoxDemo.java)
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    
    public class CustomComboBoxDemo extends JPanel
    {
        public CustomComboBoxDemo()
        {
            super(new BorderLayout());
    
            // Combo list
            Integer[] intArray = new Integer[6];
            for (int i = 0; i < 6; i++) intArray[i] = new Integer(i);
    
            // Create the combo box.
            JComboBox colorList = new JComboBox(intArray);
            ComboBoxRenderer renderer= new ComboBoxRenderer();
            renderer.setPreferredSize(new Dimension(120, 20));
            colorList.setRenderer(renderer);
            colorList.setMaximumRowCount(5);
            colorList.setSelectedIndex(2);
    
            // Lay out the demo.
            add(colorList, BorderLayout.PAGE_START);
            setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
        }
    
        private static void CreateAndShowGUI()
        {
            // Create and set up the window.
            JFrame frame = new JFrame("CustomComboBoxDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Create and set up the content pane
            JComponent newContentPane = new CustomComboBoxDemo();
            newContentPane.setOpaque(true);
            frame.setContentPane(newContentPane);
    
            // Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args)
        {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    CreateAndShowGUI();
                }
            });
        }
    }

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

  3. #3
    geforce2000 is offline Member
    Join Date
    Dec 2009
    Posts
    9
    Rep Power
    0

    Default

    I fixed it.

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    I fixed it.
    Congratulations.

    My other concern is that your design here is broken as your renderer is holding data, and this shouldn't be; that's the list model's job. If you want to add colors, you can't do that by changing the data held by the list's model and this hog-ties your app.

    For e.g., the text displayed in each label of the listbox renderer should be derived from your Object's toString value. If you want it to show more, such as an associated color, I'd create a class that holds string and color and fill my model with objects of this class. I'd then have the renderer cast the object parameter to this class's type that can return a Color (an interface would work nicely here). Then your model can hold as many or as few objects as necessary, and you can change the number of items in the list without having to fiddle each time with renderer code.
    Last edited by Fubarable; 12-13-2009 at 03:48 PM.

  5. #5
    geforce2000 is offline Member
    Join Date
    Dec 2009
    Posts
    9
    Rep Power
    0

    Default

    Thanks for your input

    When I fixed it I moved my data back over. Sometimes I consolidate my code in one class to spot the error. This is what my code actually looks like. Is what I have not acceptable? (the design)

    (Renderer: ComboBoxRenderer.java)
    Java Code:
    import java.awt.Component;
    import java.awt.Dimension;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.ListCellRenderer;
    
    public class ComboBoxRenderer extends JLabel implements ListCellRenderer
    {
        private JPanel _coloredBox = null;
        private JLabel _label = null;
    
        public ComboBoxRenderer()
        {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
    
            this.setLayout(null);
    
            // Text label
            _label = new JLabel();
            Dimension textSize = new Dimension(80, 20);
            _label.setLocation(22, 0);
            _label.setSize(textSize);
            _label.setHorizontalAlignment(JTextField.LEFT);
            _label.setOpaque(false);
            this.add(_label);
    
            // Colored box
            _coloredBox = new JPanel();
            Dimension preferredSize = new Dimension(16, 16);
            _coloredBox.setLocation(2, 2);
            _coloredBox.setSize(preferredSize);
            _coloredBox.setOpaque(true);
            this.add(_coloredBox);
        }
    
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            CustomRowObject current = (CustomRowObject) value;
            int selectedIndex = current.GetIndex();
    
            // Set cell size
            Dimension size = this.getPreferredSize();
            this.setPreferredSize(new Dimension(size.width, current.GetCellHeight()));
    
            // Set the background color for each element
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
    
            // Set text and colored box
            _label.setText(current.GetColorString());
            _label.setFont(list.getFont());
            _coloredBox.setBackground(current.GetColor());
    
            return this;
        }
    }

    (Main: CustomComboBoxDemo.java)
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    
    public class CustomComboBoxDemo extends JPanel
    {
        private DefaultComboBoxModel _comboBoxModel = null;
    
        public CustomComboBoxDemo()
        {
            super(new BorderLayout());
    
            // Fill data
            _comboBoxModel = new DefaultComboBoxModel();
            FillComboBox();
    
            // Create the combo box.
            JComboBox colorList = new JComboBox();
            colorList.setModel(_comboBoxModel);
            ComboBoxRenderer renderer= new ComboBoxRenderer();
            renderer.setPreferredSize(new Dimension(120, 20));
            colorList.setRenderer(renderer);
            colorList.setMaximumRowCount(5);
            colorList.setSelectedIndex(2);
    
            // Lay out the demo.
            add(colorList, BorderLayout.PAGE_START);
            setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
        }
    
        private void FillComboBox()
        {
            // Red
            CustomRowObject red = new CustomRowObject();
            red.SetColor(Color.red);
            red.SetColorString("Red");
            red.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(red);
    
            // Green
            CustomRowObject green = new CustomRowObject();
            green.SetColor(Color.green);
            green.SetColorString("Green");
            green.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(green);
    
            // Blue
            CustomRowObject blue = new CustomRowObject();
            blue.SetColor(Color.blue);
            blue.SetColorString("Blue");
            blue.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(blue);
    
            // Orange
            CustomRowObject orange = new CustomRowObject();
            orange.SetColor(new Color(255, 215, 0));
            orange.SetColorString("Orange");
            orange.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(orange);
    
            // Yellow
            CustomRowObject yellow = new CustomRowObject();
            yellow.SetColor(new Color(255, 255, 0));
            yellow.SetColorString("Yellow");
            yellow.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(yellow);
    
            // Cyan
            CustomRowObject cyan = new CustomRowObject();
            cyan.SetColor(new Color(0, 255, 255));
            cyan.SetColorString("Cyan");
            cyan.SetIndex(_comboBoxModel.getSize());
            _comboBoxModel.addElement(cyan);
        }
    
        private static void CreateAndShowGUI()
        {
            // Create and set up the window.
            JFrame frame = new JFrame("CustomComboBoxDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Create and set up the content pane
            JComponent newContentPane = new CustomComboBoxDemo();
            newContentPane.setOpaque(true);
            frame.setContentPane(newContentPane);
    
            // Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args)
        {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    CreateAndShowGUI();
                }
            });
        }
    }

    (Custom Object: CustomRowObject.java)
    Java Code:
    import java.awt.Color;
    
    public class CustomRowObject
    {
        private String _colorString = "";
        private Color _color = null;
        private int _index;
        private int _cellHeight = 20;
    
        public CustomRowObject() {}
        public void SetCellHeight(int value) { _cellHeight = value; }
        public void SetColorString(String colorString) { _colorString = colorString; }
        public void SetColor(Color color) { _color = color; }
        public void SetIndex(int value) { _index = value;}
        public int GetCellHeight() { return _cellHeight;}
        public String GetColorString() { return _colorString; }
        public Color GetColor() { return _color; }
        public int GetIndex() { return _index;}
    
        @Override
        public String toString() { return _colorString; }
    }
    Last edited by geforce2000; 12-13-2009 at 06:38 PM.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Yes, that looks much better to me. Thanks for providing us with an update!

  7. #7
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

    Default

    The method names in the CustomRowObject to not follow Java naming standards.

    Method names should NOT start with an upper case character.

  8. #8
    geforce2000 is offline Member
    Join Date
    Dec 2009
    Posts
    9
    Rep Power
    0

    Default

    The method names in the CustomRowObject to not follow Java naming standards.

    Method names should NOT start with an upper case character.
    Habit I carried over from programming in C++ :)

    I kindof have my own programming style that I've stuck with since I code with more then one language (C, C++, C#, PHP, VB, etc.) With Java and ActionScript being the newest additions.

  9. #9
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    The advantages of sticking to conventions are most noticeable here, when you ask others for advice: Others will find it much easier to read and understand your code if it follows conventions that they are familiar with. Makes sense to me.

  10. #10
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    6

    Default

    Reading the above, I wondered if it could be made simpler with Icons in the JLabels.
    It seems it can, as demonstrated below.

    Storing the item data in a JLabel isn't the same as the above
    infelicity where the colors were stored in the renderer.
    The JLabel is at the level of the data model;
    there is a separate JLabelUI for rendering it.

    That the renderer is inside CustomRowObject is a matter of taste.
    A renderer is a good example of a need to pass a methods as a parameter.
    Java cannot (for good reasons) and so the renderer must be in some class.
    It is convenient to have it in the class of the objects it is to render.

    Incidentally, note the proper placement of curly braces:
    • left curly braces go at the right of a line and
    • right curly braces go at the left.


    Java Code:
    import java.awt.*;
    import javax.swing.*;
    
    public class CustomComboBoxDemo extends JPanel {
    
    	public CustomComboBoxDemo() {
    		super(new BorderLayout());
    
    		JComboBox colorList = new JComboBox();
    			colorList.addItem(new CustomRowObject("Red", Color.red));
    			colorList.addItem(new CustomRowObject("Green", Color.green));
    			colorList.addItem(new CustomRowObject("Blue", Color.blue));
    			colorList.addItem(new CustomRowObject("Orange", Color.orange));
    			colorList.addItem(new CustomRowObject("Yellow", Color.yellow));
    			colorList.addItem(new CustomRowObject("Cyan", Color.cyan));
    		colorList.setRenderer(new CustomRowObject("dummy", Color.black));
    		colorList.setSelectedIndex(2);
    
    		// Lay out the demo.
    		add(colorList, BorderLayout.PAGE_START);
    		setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    	}
    
    	public static class ColorIcon implements Icon {
    		final static int DIM = 16;
    		Color myColor;
    		public ColorIcon (Color c) {
    			myColor = c;
    		}
    		public void paintIcon(Component c, Graphics g, int x, int y) {
    			g.setColor(myColor);
    			g.fillRect(x, y, DIM, DIM);
    		}
    		public int getIconWidth() { return DIM; }
    		public int getIconHeight() { return DIM; }
    	}
    
    	public static class CustomRowObject extends JLabel implements ListCellRenderer  {
    		public CustomRowObject(String name, Color c) {
    			setText(name);
    			setIcon(new ColorIcon(c));
    			this.setOpaque(true);
    			setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    			setPreferredSize(new Dimension(120, 20));
    		}
    		@Override
    		public String toString() { return getText(); }
    
    		public Component getListCellRendererComponent(
    				JList list, Object value, int index, 
    				boolean isSelected, boolean cellHasFocus) {
    			CustomRowObject current = (CustomRowObject) value;
    
    			if (isSelected) {
    				current.setBackground(list.getSelectionBackground());
    				current.setForeground(list.getSelectionForeground());
    			} else {
    				current.setBackground(list.getBackground());
    				current.setForeground(list.getForeground());
    			}
    			return current;
    		}
        }
    
        private static void createAndShowGUI() {
            // Create and set up the window.
            JFrame frame = new JFrame("CustomComboBoxDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Create and set up the content pane
            JComponent newContentPane = new CustomComboBoxDemo();
            newContentPane.setOpaque(true);
            frame.setContentPane(newContentPane);
    
            // Display the window.
            frame.pack();
            frame.setVisible(true);
        }
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }

  11. #11
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Nice solution! :)

  12. #12
    geforce2000 is offline Member
    Join Date
    Dec 2009
    Posts
    9
    Rep Power
    0

    Default

    Reading the above, I wondered if it could be made simpler with Icons in the JLabels.
    Apparently it can :D

Similar Threads

  1. Complet details of jtable and renderer
    By anilkumar_vist in forum AWT / Swing
    Replies: 1
    Last Post: 12-12-2009, 02:10 PM
  2. Anyone know how GroupLayout works?
    By ProgrammingPup in forum Advanced Java
    Replies: 5
    Last Post: 12-02-2009, 12:12 AM
  3. jtable cell renderer
    By ankitmcgill in forum New To Java
    Replies: 2
    Last Post: 05-22-2009, 02:08 AM
  4. how to use renderer in JTable
    By sunilpatel28 in forum Advanced Java
    Replies: 0
    Last Post: 12-09-2008, 09:01 AM
  5. how compareTo Method works
    By nanaji in forum Advanced Java
    Replies: 1
    Last Post: 06-22-2008, 08:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •