Custom CellRender from JList

2

I would like to make a cell render with JPanel so they look like this:

It would be composed of a JPanel , another JPanel inside that would have the background changed and two JTextField or JLabel

I tried to understand how CellRender works but nobody explains it right

public class CustomContactCellRender extends JPanel implements ListCellRenderer<Object>{

    private static Contact_Info cinfo;
    JLabel name;
    JLabel msg;

    public CustomContactCellRender() {

        setOpaque(true);
        setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));

        JPanel overallPanel = new JPanel();
        overallPanel.setLayout(new BoxLayout(overallPanel , BoxLayout.X_AXIS));
        overallPanel.setPreferredSize(new Dimension(40,400));
        add(overallPanel);

        JPanel firstPanel = new JPanel();
        firstPanel.setPreferredSize(new Dimension(40,40));
        firstPanel.setLayout(new BorderLayout());
        overallPanel.add(firstPanel);

        JPanel statusPanel = new JPanel();
        statusPanel.setPreferredSize(new Dimension(37,37));
        statusPanel.setLayout(new BorderLayout());

        firstPanel.add(statusPanel , BorderLayout.CENTER);
        firstPanel.add(Box.createRigidArea(new Dimension(3,40)) , BorderLayout.LINE_START);
        firstPanel.add(Box.createRigidArea(new Dimension(3,40)) , BorderLayout.LINE_END);
        firstPanel.add(Box.createRigidArea(new Dimension(40,3)) , BorderLayout.PAGE_END);
        firstPanel.add(Box.createRigidArea(new Dimension(40,3)) , BorderLayout.PAGE_START);

        JPanel photoPanel = new JPanel();
        photoPanel.setPreferredSize(new Dimension(32,32));
        photoPanel.setLayout(null);
        statusPanel.add(photoPanel);

        JPanel secondPanel = new JPanel();
        secondPanel.setLayout(new BoxLayout(secondPanel , BoxLayout.Y_AXIS));
        overallPanel.add(secondPanel);

        secondPanel.add(Box.createRigidArea(new Dimension(3,this.getWidth())));

        name = new JLabel();
        name.setPreferredSize(new Dimension(100,15));
        secondPanel.add(name);

        secondPanel.add(Box.createRigidArea(new Dimension(4,this.getWidth())));

        msg = new JLabel();
        msg.setPreferredSize(new Dimension(this.getWidth(),15));
        secondPanel.add(msg);

        secondPanel.add(Box.createRigidArea(new Dimension(4,this.getWidth())));
    };

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {

        cinfo = Contact_Info.getInstance();

        name.setText(cinfo.getFirst_name(1));

        return this;
    }

EDIT: Updated Code

Where is the design of the cell? in CustomContactCellRender() or getListCellRendererComponent ?

If someone has a tip also accepted

EDIT 2

I think you're right ... how would you name the names and add% to JList ?

    
asked by anonymous 24.07.2014 / 21:01

1 answer

1

Lucas, making my comments an answer as promised.

Yes you are on the right path. There is an article about% in the official Java tutorial . You can find the example source code here (it customizes a ListCellRender , but there is not much difference in practice).

About where to put each thing:

  • JComboBox is the renderer constructor , you can put everything that is fixed here; the layout of your dashboard, its components and everything else that is relevant.

  • CustomContactCellRender() is the method that will return the component for each item. Fine adjustments and display of model values should all be done in this method, since only in it will you have access to the list object ( getListCellRendererComponent ), element position ( value ), etc.

  • About how to set the name

    Always remember the separation between model and renderer . What feeds the list with values is index (if you started the combo with an array or ListModel java built an anonymous model that inherits from AbstractListModel for you).

    Well, if you have Vector of objects of type ListModel , values of Contact must also deal with Renderer (you can specify the type in the declaration: Contact ). p>

    Once done, the only thing renderer should do is to feed its component with the received values:

    public Component getListCellRendererComponent(JList list, Contact value,
            int index, boolean isSelected, boolean cellHasFocus) {
    
        name.setText(value.getNome());
        msg.setText(value.getMensagem()); 
    
        return this;
    }
    

    Of course in an actual application you should also have some visual indicative of focus and selection; for example, change the color of the background or draw a border):

    if (isSelected) {
        setBackground(list.getSelectionBackground());
        setForeground(list.getSelectionForeground());
    } else {
        setBackground(list.getBackground());
        setForeground(list.getForeground());
    }
    
    if (cellHasFocus) {
       setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
    } else
       setBorder(new EmptyBorder(1, 1, 1, 1));
    } 
    

    To fine-tune this type of detail, it's a good idea to look at the source code of the DefaultListCellRenderer (this varies greatly depending on the JDK version).

    The set working together:

    Contact[] myContacts = new Contact[] {
        new Contact("Hans Solo", "Do not call him Harrison Ford"),
        new Contact("Jabba the Hutt", "Not Pizza Hut")
    };
    JList<Contact> list = new JList<>(myContacts);
    list.setCellRenderer(new CustomContactCellRender());
    
        
    25.07.2014 / 19:32