I'm trying to display Panel in a JList by modifying the render.
I tried an example with JLabel (https://www.codejava.net/java-se/swing/jlist-custom-renderer-example) and it's works perfectly (see picture)
So I tried to adapt it for JPanel (instead of JLabel) but I got an interesting problem and I really don't know how to solve it.
As you can see, instead of appearing only one time, every country and his associated image are displayed on every line and I can't understand why. (There are 8 lines because there are 8 countries)
Here is the code I made :
CountryRenderer.java
import java.awt.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class CountryRenderer extends JPanel implements ListCellRenderer<Country> {
@Override
public Component getListCellRendererComponent(JList<? extends Country> list, Country country, int index,
boolean isSelected, boolean cellHasFocus) {
String code = country.getCode();
// to load and resize the image
Image imgSettings = null;
try {
imgSettings = ImageIO.read(getClass().getResource("./images/" + code + "1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
imgSettings = imgSettings.getScaledInstance(25, 25, imgSettings.SCALE_SMOOTH);
// create the button and put the image on it
JButton buttontest = new JButton() ;
buttontest.setIcon(new ImageIcon(imgSettings));
add(buttontest);
// create the text (name of the country)
JTextField txtest = new JTextField();
txtest.setText(country.getName());
add(txtest);
return this;
}
}
and in case you need the 2 other files to make this run, they are on the link I put above or here :
Country.java
public class Country {
private String name;
private String code;
public Country(String name, String code) {
this.name = name;
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return name;
}
}
And here is the file you can run : JListCustomRendererExample.java
import javax.swing.*;
public class JListCustomRendererExample extends JFrame {
public JListCustomRendererExample() {
Country us = new Country("USA", "1");
Country in = new Country("India", "2");
Country vn = new Country("Vietnam", "3");
Country ca = new Country("Canada", "4");
Country de = new Country("Denmark", "5");
Country fr = new Country("France", "6");
Country gb = new Country("Great Britain", "7");
Country jp = new Country("Japan", "8");
//create the model and add elements
DefaultListModel<Country> listModel = new DefaultListModel<>();
listModel.addElement(us);
listModel.addElement(in);
listModel.addElement(vn);
listModel.addElement(ca);
listModel.addElement(de);
listModel.addElement(fr);
listModel.addElement(gb);
listModel.addElement(jp);
//create the list
JList<Country> countryList = new JList<>(listModel);
add(new JScrollPane(countryList));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JList Renderer Example");
this.setSize(200, 200);
this.setLocationRelativeTo(null);
this.setVisible(true);
countryList.setCellRenderer(new CountryRenderer());
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JListCustomRendererExample();
}
});
}
}
EDIT
I tried with the answer of @Gilbert le blanc but I still have a problem, I tried to add new element to this label, like a button and I wanted these button to have the same text on it that the name of the country row it's on. Example : on the row USA, I want the button to have "USA" on it.
So I added these 4 lines in the public Component getListCellRendererComponent
:
label.setLayout(null);
JButton test = new JButton(country.getName());
test.setBounds(10,10,50,50);
label.add(test);
And I got this :
That's not what was expected and that's kinda the same problem that I had with the first question, do you know why ? And is there a solution ?
Well I managed to solve myself by creating a JPanel with listener so it was like a JList but I can put the object I wanted in it so it even work better.