swing的ListCellRenderer列表外观
使用ListCellRenderer改变列表外观 前面程序中的JList和JComboBox采用的都是简单的字符串列表项,实际上,JList和JComboBox还可以支持图标列表项,如果在创建JList或JComboBox时传入图标数组,则创建的JList和JComboBox的列表项就是图标
如果希望列表项是更复杂的组件,例如,希望像QQ程序那样每个列表项既有图标,此时需要使用ListCellRenderer接口的实现类对象,自定义 每个条目组件的渲染过程:
x
public interface ListCellRenderer<E>{ Component getListCellRendererComponent( JList<? extends E> list,//列表组件 E value,//当前列表项的内容 int index,//当前列表项的索引 boolean isSelected,//当前列表项是否被选中 boolean cellHasFocus);//当前列表项是否获取了焦点 }}通过JList的setCellRenderer(ListCellRenderer<? super E> cellRenderer)方法,把自定义的ListCellRenderer对象传递给JList,就可以按照自定义的规则绘制列表项组件了
swing的ListCellRenderer列表外观_练习
package ch30;
import javax.swing.*;import java.awt.*;
public class a_23_0swing_列表框_ListCellRenderer列表外观 {
//窗口 private JFrame mainWin = new JFrame("好友列表");
//字符串数组存储人名 private String[] friends = {"张三", "小明", "小红", "小华", "李四"};
//定义一个JList列表对象 JList friendsList = new JList(friends);
public void init() { //给JList设置ListCellRenderer对象,指定列表项绘制的组件。setCellRenderer的参数需要是ListCellRenderer接口的实现类对象 friendsList.setCellRenderer(new MyRenderer());
mainWin.add(new JScrollPane(friendsList));
//设置窗口的最佳大小,设置窗口可见,设置点击叉号就退出程序 mainWin.pack(); mainWin.setVisible(true); mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
public static void main(String[] args) { new a_23_0swing_列表框_ListCellRenderer列表外观().init(); }
//创建一个类,并实现ListCellRenderer接口 private class MyRenderer extends JPanel implements ListCellRenderer {
//下面是4个成员变量 //名字 private String name; //头像。下面那行的ImageIcon是Icon的子类 private ImageIcon icon; //每个列表项的背景色,即选中某个列表项时,头像外部和该列表项内部之间的区域的颜色 private Color backGround; //每个列表项的前景色,即字符串名字的颜色 private Color forceGround;
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
//重置4个成员变量的值 this.name = value.toString(); icon = new ImageIcon("src\\img\\" + name + ".png"); backGround = isSelected ? list.getSelectionBackground() : list.getBackground(); forceGround = isSelected ? list.getSelectionForeground() : list.getForeground(); //返回当前JPanel对象,作为列表项绘制器 return this; }
//重写下面的这个方法,绘制列表项 protected void paintComponent(Graphics g) { //定义头像图片宽高 int imageWidth = icon.getImage().getWidth(null); int imageHeight = icon.getImage().getHeight(null); //背景色,即填充一个跟列表项对应宽高的矩形即可 g.setColor(backGround); g.fillRect(0, 0, getWidth(), getHeight()); //前景色:即字体颜色 g.setColor(forceGround); //绘制头像。this.getWidth()是当前列表项的宽度。imageWidth是头像图片的宽度 g.drawImage(icon.getImage(), this.getWidth() / 2 - imageWidth / 2, 10, null); //绘制昵称,即绘制字符串,为了方便绘制字符串,我们先自定义一下字符串的字体类型、字体粗细、大小 g.setFont(new Font("StSong", Font.BOLD, 18)); //再绘制昵称 //原理:一个标准字符的宽度18px,加上前后细微的间隔,我们就默认为单个字的宽度是20px,然后this.name.length()*20/2 g.drawString(name, this.getWidth() / 2 - this.name.length() * 20 / 2, 10 + imageHeight+20); }
//每个列表项的宽高 public Dimension getPreferredSize() { return new Dimension(60, 80); }
}}