0

I have a JList and I have added an instance of ListCellRenderer as the cell renderer of JList as

myList.setCellRenderer(new ListItemPanel());

Here myList is the JList with a list model with type String. Implementation of ListItemPanel is as follows.

public class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{
    public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
        nameLabel.setText(value.toString());
        if(isSelected){
            setBackground(Color.YELLOW);
            setPreferredSize(new Dimension(list.getWidth(), 40));
        }else{
            setBackground(Color.PINK);
            setPreferredSize(new Dimension(list.getWidth(), 18));
        }
        return this;
    }
}

Using the above piece of code, I was expecting to change the color and the height of the selected item in JList. But only the color change is happening. The height of the list items are seems to be 18 at starting. When I change 18 to some other value, height of the items change to that value. But no change happens when an item is selected.

nameLabel is a JLabel that is on the JPanel.

I tried revalidating and repainting list, JPanel, and nameLabel. And used the method setPreferredSize both in JPanel and JLabel.
But nothing is changing the height of the list items when selected. Hope if someone can help..!

Edit

What I need is to change the height of the items when selected.

In here it is talking about changing the height of each item according to the text in them. But there, after the text is added, the height is fixed. That is not what I need..
Thank you for your attention everyone..

SSCCE for the Question

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

public class A  extends javax.swing.JFrame {

    private DefaultListModel<String> myListModel = new DefaultListModel<>();
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JList myList;

    public A(){
        //Setting the GUI
        jScrollPane1 = new javax.swing.JScrollPane();
        myList = new javax.swing.JList();
        myList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(myList);
        add(jScrollPane1);
        setSize(300,400);
        setLocationRelativeTo(null);

        //Add model, renderer and elements to the list
        myList.setModel(myListModel);
        myList.setCellRenderer(new ListItemPanel());
        myListModel.addElement("ABCD");
        myListModel.addElement("1234567890");
        myListModel.addElement("q121we34rt56yu7");
        myListModel.addElement("ABC 123 #$%");
        myListModel.addElement("11 11 22 22 33 33");
        myListModel.addElement("321 ewq A1");
    }

    //Execute the program
    public static void main(String[] args) throws Exception{
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new A().setVisible(true);
            }
        });
    }

}

//Customized ListCellRenderer
class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{

    private javax.swing.JLabel nameLabel;

    public ListItemPanel() {
        nameLabel = new javax.swing.JLabel();
        setLayout(new BorderLayout());
        add(nameLabel);
    }

    public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
        nameLabel.setText(value.toString());
        if(isSelected){
            setBackground(Color.YELLOW);
            setPreferredSize(new Dimension(list.getWidth(), 40));   //If selected, set the height to 40
        }else{
            setBackground(Color.PINK);
            setPreferredSize(new Dimension(list.getWidth(), 18));   //If not selected, set the height to 18
        }
        return this;
    }
}



Answer to the Question

In setFixedCellHeight() method, it is said that,

...cell heights are computed in the ListUI by applying getPreferredSize ....

So, if the the values can be changed inside ListUI, my task is possible..

The values are stored in a variable cellHeights and as I saw in source code, that variable is updated only once. So, I change my code so that cellHeights is changed every time I select an item.

SSCCE for the Answer

import javax.swing.*;
import java.awt.*;
import javax.swing.plaf.basic.BasicListUI;

public class A  extends javax.swing.JFrame {

    private DefaultListModel<String> myListModel = new DefaultListModel<>();
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JList myList;

    public A(){
        //Setting the GUI
        jScrollPane1 = new javax.swing.JScrollPane();
        myList = new javax.swing.JList();
        myList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(myList);
        add(jScrollPane1);
        setSize(300,400);
        setLocationRelativeTo(null);

        //Add model, renderer and elements to the list
        myList.setModel(myListModel);
        myList.setCellRenderer(new ListItemPanel());
        myList.setUI(new BasicListUI() {        //Update UI of JList

            @Override
            protected void paintCell(Graphics g, int row, Rectangle rowBounds, ListCellRenderer cellRenderer, ListModel dataModel, ListSelectionModel selModel, int leadIndex) {
                Object value = dataModel.getElementAt(row);
                boolean cellHasFocus = list.hasFocus() && (row == leadIndex);
                boolean isSelected = selModel.isSelectedIndex(row);
                ListItemPanel rendererComponent = (ListItemPanel)cellRenderer.getListCellRendererComponent(list, value, row, isSelected, cellHasFocus);
                int x = rendererComponent.getH();
                if(x != cellHeights[row]){
                    cellHeights[row] = x; //Change the height of the selected item
                    myList.repaint();   //Though repaint is called here, it will actualy be effected after this function call
                }
                super.paintCell(g, row, rowBounds, cellRenderer, dataModel, selModel, leadIndex);
            }

        });
        myListModel.addElement("ABCD");
        myListModel.addElement("1234567890");
        myListModel.addElement("q121we34rt56yu7");
        myListModel.addElement("ABC 123 #$%");
        myListModel.addElement("11 11 22 22 33 33");
        myListModel.addElement("321 ewq A1");
    }

    //Execute the program
    public static void main(String[] args) throws Exception{
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new A().setVisible(true);
            }
        });
    }

}

//Customized ListCellRenderer
class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{

    private int h;  //This variable is used to store the height of the component
    private javax.swing.JLabel nameLabel;

    public ListItemPanel() {
        nameLabel = new javax.swing.JLabel();
        setLayout(new BorderLayout());
        add(nameLabel);
    }

    public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
        nameLabel.setText(value.toString());
        if(isSelected){
            setBackground(Color.YELLOW);
            h = 40; //If selected, set the height to 40
        }else{
            setBackground(Color.PINK);
            h = 18; //If not selected, set the height to 18
        }
        return this;
    }

    public int getH(){
        return h;
    }
}
Community
  • 1
  • 1
Ramesh-X
  • 4,853
  • 6
  • 46
  • 67
  • 1
    It's probably a better strategy to leave the list items at the initial size and put extra details either in a tool tip, or in some fields beside the list. For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Dec 25 '15 at 15:36
  • 2
    Also look at [this similar question](http://stackoverflow.com/questions/7306295/swing-jlist-with-multiline-text-and-dynamic-height) and both kleopatra's and @AndrewThompson's great answers and code. – Hovercraft Full Of Eels Dec 25 '15 at 15:44
  • @AndrewThompson: I read the question and answers you suggested. In that post, it is talking about fixed height list components. (Although the list items are variable in height, the initial values are fixed during the runtime). But in I want the list heights to be vary during the runtime.. – Ramesh-X Dec 25 '15 at 16:42
  • @HovercraftFullOfEels and @AndrewThompson: I edited the question with `SSCCE` – Ramesh-X Dec 25 '15 at 17:15
  • 1
    *"In that post, it is talking about fixed height list components. (Although the list items are variable in height, the initial values are fixed during the runtime). But in I want the list heights to be vary during the runtime.."* Yup. That's why I suggested the alternate approaches. I think this is doomed to fail (and would have been a usability nightmare even if you managed it). Thanks to @HovercraftFullOfEels for reminding me of that other question though. I'd forgotten that little code adventure. :) – Andrew Thompson Dec 25 '15 at 17:18
  • @AndrewThompson: did you check out the [other link](http://stackoverflow.com/questions/7306295/swing-jlist-with-multiline-text-and-dynamic-height), the one used to close this question? – Hovercraft Full Of Eels Dec 25 '15 at 17:24
  • I finally found the answer to my question. Thank you everyone for your help. Although I found the answer, I also thought about an alternate approach as @AndrewThompson said.. I'm not sure whether my answer be failed.. – Ramesh-X Dec 25 '15 at 18:14

0 Answers0