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
InsetFixedCellHeight()
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;
}
}