The previous tutorial on Custom JList here covers the creation of a simple JList displaying a list of countries. This tutorial introduces the implementation of a custom cell renderer to achieve pretty cool stuff with the JList. Here, the list of countries appear with not just their names, but also their flags. First, we begin by modifying the Country model. We add a variable to hold the name of the country's flag. The flag is added in the same package as the view class. package com. coolcodingtutorials . model ; /** * * @author jaletechs */ public class Country { private String name; private int id; public Country ( int id, String name) { this . name = name; this . id = id; } public String getName () { return name; } public void setName (String name) { this . name = name; } public int getId () { return id; } public void setId ( int id) { this . id = i...
The previous tutorial on Custom JList here covers the creation of a simple JList displaying a list of countries. This tutorial introduces the implementation of a custom cell renderer to achieve pretty cool stuff with the JList. Here, the list of countries appear with not just their names, but also their flags.
First, we begin by modifying the Country model. We add a variable to hold the name of the country's flag. The flag is added in the same package as the view class.
package com.coolcodingtutorials.model; /** * * @author jaletechs */ public class Country { private String name; private int id; public Country(int id, String name) { this.name = name; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int hashCode() { int hash = 7; hash = 41 * hash + this.id; return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Country other = (Country) obj; if (this.id != other.id) { return false; } return true; } @Override public String toString(){ return name; } }
Next, we update the dummy country factory to reflect the constructor change
package com.coolcodingtutorials.model; import java.util.List; import java.util.ArrayList; /** * * @author jaletechs */ public class CountryFactory { public static List<Country> getCountries(){ ArrayList<Country> countries = new ArrayList<>(); countries.add(new Country(1, "Nigeria","nigeria.png")); countries.add(new Country(1, "USA","usa.png")); countries.add(new Country(3, "Belgium","belgium.png")); return countries; } }Note the names of the flag variable are simply strings with the appropriate file extensions e.g. "nigeria.png". Ensure to put the image files in the same package as the CountryCellRenderer.java file we would soon examine. Next, we add the Custom cell renderer (CountryCellRenderer.java)package com.coolcodingtutorials.view; import com.coolcodingtutorials.model.Country; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import javax.swing.*; import javax.swing.border.BevelBorder; import net.coobird.thumbnailator.Thumbnails; @SuppressWarnings({ "serial", "rawtypes" }) public class CountryCellRenderer extends JPanel implements ListCellRenderer { private final Color HIGHLIGHT_COLOR = new Color(0,200,255); private JLabel flag; private JLabel name; public CountryCellRenderer() { setLayout(new BorderLayout()); setBorder(new BevelBorder(BevelBorder.LOWERED)); flag = new JLabel(); flag.setPreferredSize(new Dimension(65,65)); flag.setBorder(BorderFactory.createLineBorder(Color.BLACK)); name = new JLabel(); name.setOpaque(true); JPanel centerPanel = new JPanel(); centerPanel.add(name); add(flag, BorderLayout.WEST); add(centerPanel, BorderLayout.CENTER); }//end constructor public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean hasNextFocus) { Country country = (Country) value; //deal with the Item Image ImageIcon icon = new ImageIcon(getClass().getResource(country.getImage())); BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB); Graphics g = bi.createGraphics(); //draw icon.paintIcon(null, g, 0, 0); g.dispose(); try { BufferedImage thumbnail = Thumbnails.of(bi).size(65,65).asBufferedImage(); icon = new ImageIcon(thumbnail); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } flag.setIcon(icon); name.setText(country.getName()); if(isSelected) { setOpaque(true); setBackground(HIGHLIGHT_COLOR); setForeground(Color.WHITE); setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); } else { setOpaque(false); setBackground(Color.BLACK); setForeground(Color.WHITE); } return this; }//end method getListCellRendererComponent }//end class CountryCellRendererWith a few neat tricks, anything is possible when it comes to customizing a JList to your taste. The first thing to consider is the ListCellRenderer interface. With a single method to be overridden, the desired look can be achieved. In our custom cell renderer, we extend the JPanel class and create two labels (type: JLabel) to carry the name of the country and its flag beside it. A custom implementation of the ListCellRenderer just indicates that we have provided our own implementation of what the JList should look like.package com.coolcodingtutorials.view; import com.coolcodingtutorials.model.Country; import com.coolcodingtutorials.model.CountryFactory; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JScrollPane; /** * * @author jaletechs */ public class MainWindow { public static void main(String[] args) { MainWindow window = new MainWindow(); window.go(); } private void go(){ //create a frame JFrame frame = new JFrame("Custom JList"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //create a JList JList<Country> jList = new JList(CountryFactory.getCountries().toArray()); jList.setCellRenderer(new CountryCellRenderer()); //add JList to a Scroll pane JScrollPane scroller = new JScrollPane(jList); frame.getContentPane().add(scroller); frame.setSize(300,300); frame.setVisible(true); } }Now, with just a single line in our view class, we can change the way the JList renders our data: jList.setCellRenderer(new CountryCellRenderer());Output:

Comments
Post a Comment