[的Java Swing] JList的自定义 – JList的自定义渲染

在所有 JList的 我们已经知道了如何创建一个简单的JList有一些动作和事件. 在这篇文章中,我们继续学习如何自定义只创建一个列表的JList元素为我们. 如接触 (图像, 联系人姓名, 电话号码) 最喜欢的书籍或列表 (包括封面, 称号, 作者姓名) 如下所示:
定制的JList
首先,让我们创建一个类图书存储信息的书籍. 在Book类有三个属性是冠军, 作者和书的封面与构造称号, 吸气, 设定器如下:

package nguyenvanquan7826.JList;

public class Book {
	private String name;
	private String author;
	private String iconName;

	public Book(String name, String author, String iconName) {
		super();
		this.name = name;
		this.author = author;
		this.iconName = iconName;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getIconName() {
		return iconName;
	}

	public void setIconName(String iconName) {
		this.iconName = iconName;
	}
}

接下来,我们创建 的JFrame 显示我们的图书清单. 在JFrame中含有 的JPanel Là主面板, 此JPanel包含 1 JList的是listBook, listBook放置在 1 JScrollPane中要能上下翻滚的一长串情况, JList的不完全展现.

package nguyenvanquan7826.JList;

import java.awt.BorderLayout;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

public class JListCustomRenderer extends JFrame {
	private int width = 350;
	private int height = 200;
	private JList<Book> listBook;

	public JListCustomRenderer() {
		// add main panel
		add(createMainPanel());
		// set display
		setTitle("JLIstCustomRenderer");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(width, height);
		setLocationRelativeTo(null);
		setVisible(true);
	}

	private JPanel createMainPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(new EmptyBorder(10, 10, 10, 10));
		// create list book and set to scrollpane and add to panel
		panel.add(new JScrollPane(listBook = createListBooks()),
				BorderLayout.CENTER);
		return panel;
	}

	private JList<Book> createListBooks() {
		// create List model
		DefaultListModel<Book> model = new DefaultListModel<>();
		// add item to model
		model.addElement(new Book("C/C++ Programming", "A", "cpp"));
		model.addElement(new Book("Java Programming", "B", "java"));
		model.addElement(new Book("C# Programming", "C", "cs"));
		model.addElement(new Book("IOS Programming", "D", "ios"));
		model.addElement(new Book("Windows Phone Programming", "E", "wp"));
		model.addElement(new Book("Android Programming", "F", "android"));
		// create JList with model
		JList<Book> list = new JList<Book>(model);
		return list;
	}

	public static void main(String[] args) {
		new JListCustomRenderer();
	}
}

做得好, 所以,我们已经有了一个书单,并, 运行程序,看看它出来? 这是这件事情=)) 很意外, 不是会不惜一切@@

定制的JList

为什么这么, 我们增加了书的名单包括书名和作者名, 那么,为什么这样的方案再次展示? 事实上,JList的是通过处理 模型 并进一步JList的节目被称为对象执行对象 渲染 与每个JList中有一个默认渲染器. 所以这个默认的活动如何渲染器? 负责渲染显示在JList中的元素. 它是通过调用方法完成 的toString() 在JList的主题,并把链变得现身. 因此在我们的书类没有写线程的toString() 渲染了链条,这样的toString() 默认类图书. 而且,我们相处得很好,在节目的字符串是系统提供的字符串中的JList的图书的每个对象.
现在,我们试图重写的toString() 在下面的类书:

@Override
public String toString() {
	return name + " - " + author;
}

我们覆盖的toString() 返回书的名称和作者. 所以,当你运行该程序,我们得到一个清单如下:

定制的JList

它看起来我们已经找到好? 不,他们必须! 我们需要显示的封面作为开场的形象,他们必须这样做? 大家都知道该节目的时JList的渲染引起那么要改变它是很容易被重写的JList渲染我们所期望的.
现在让我们来确定是否是什么JList中的每一个元素? 在这里,我们希望它是包含三个一个JPanel 的JLabel, JLabel的是封面写真书, 一个JLabel JLabel的名称,最后一本书是作者的名字有蓝色.
要自定义渲染器,我们将编写另一个类再次被任命为 BookRenderer从一个JPanel继承. 另外这个类实现了一个名为接口需求 ListCellRenderer. 该接口有一个方法 getListCellRendererComponent() 回到我们的主要JPanel并对其进行处理,以显示JList中.

package nguyenvanquan7826.JList;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;

public class BookRenderer extends JPanel implements ListCellRenderer<Book> {

	private JLabel lbIcon = new JLabel();
	private JLabel lbName = new JLabel();
	private JLabel lbAuthor = new JLabel();

	public BookRenderer() {
		setLayout(new BorderLayout(5, 5));

		JPanel panelText = new JPanel(new GridLayout(0, 1));
		panelText.add(lbName);
		panelText.add(lbAuthor);
		add(lbIcon, BorderLayout.WEST);
		add(panelText, BorderLayout.CENTER);
	}

	@Override
	public Component getListCellRendererComponent(JList<? extends Book> list,
			Book book, int index, boolean isSelected, boolean cellHasFocus) {

		lbIcon.setIcon(new ImageIcon(getClass().getResource(
				"/nguyenvanquan7826/JList/" + book.getIconName() + ".jpg")));
		lbName.setText(book.getName());
		lbAuthor.setText(book.getAuthor());
		lbAuthor.setForeground(Color.blue);

		return this;
	}
}

在JList中每个元素都是一个JPanel. 这JPanel的布局是BorderLayout, 它包含在西部图标 (WEST) 和panelText. panelText的JPanel包含JLabel的两个冠军和作者姓名.
我们把文本和图标的方法选择JLabel getListCellRendererComponent(). 这种方法需要的类的对象此书Book电视. 这本书的主要目的是在其中在显示元件的JList. 所以我们把图标, 的JLabel通过采取iconName文本, 名字, 这本书的作者对象.
现在我们回到下面createListBook JListCustomRenderer类和修改方法:

private JList<Book> createListBooks() {
	// create List model
	DefaultListModel<Book> model = new DefaultListModel<>();
	// add item to model
	model.addElement(new Book("C/C++ Programming", "A", "cpp"));
	model.addElement(new Book("Java Programming", "B", "java"));
	model.addElement(new Book("C# Programming", "C", "cs"));
	model.addElement(new Book("IOS Programming", "D", "ios"));
	model.addElement(new Book("Windows Phone Programming", "E", "wp"));
	model.addElement(new Book("Android Programming", "F", "android"));
	// create JList with model
	JList<Book> list = new JList<Book>(model);
	// set cell renderer 
	list.setCellRenderer(new BookRenderer());
	return list;
}

现在,运行该程序,我们将根据需要JList的.
定制的JList

然而,在未完成的. 你有没有注意到,当我们点击一​​个项目,他们没有看到任何现象的@@. 这是因为我们已经重写应该渲染器创建没有更多的渲染效果默认 (当选择背景颜色 1 项目). 我们将设置背景色的JPanel, 对于被选中的JLabel或不选时,如下 (写方法getListCellRendererComponent() 类BookRenderer的)

@Override
public Component getListCellRendererComponent(JList<? extends Book> list,
		Book book, int index, boolean isSelected, boolean cellHasFocus) {

	lbIcon.setIcon(new ImageIcon(getClass().getResource(
			"/nguyenvanquan7826/JList/" + book.getIconName() + ".jpg")));
	lbName.setText(book.getName());
	lbAuthor.setText(book.getAuthor());
	lbAuthor.setForeground(Color.blue);

	// set Opaque to change background color of JLabel
	lbName.setOpaque(true);
	lbAuthor.setOpaque(true);
	lbIcon.setOpaque(true);

	// when select item
	if (isSelected) {
		lbName.setBackground(list.getSelectionBackground());
		lbAuthor.setBackground(list.getSelectionBackground());
		lbIcon.setBackground(list.getSelectionBackground());
		setBackground(list.getSelectionBackground());
	} else { // when don't select
		lbName.setBackground(list.getBackground());
		lbAuthor.setBackground(list.getBackground());
		lbIcon.setBackground(list.getBackground());
		setBackground(list.getBackground());
	}
	return this;
}

就是这样, 现在,我们可以执行,然后选择项目.

定制的JList

和一个非常小的一部分,这本书的封面照片似乎比较接近? 我们在第一美容用品下线分离出来的一种形式大致相同, 这意味着你可以做 (建议把lbIcon在 1 空边框的JPanel并为此设置的JPanel).
该软件包可以在这里下载 自定义的JList
定制的JList

参考文章在: codejava.net