[的Java Swing] 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中的元素. 它是通过调用方法完成 的toString() 在JList的主题,并把链变得现身. 因此在我们的书类没有写线程的toString() 渲染了链条,这样的toString() 默认类图书. 而且,我们相处得很好,在节目的字符串是系统提供的字符串中的JList的图书的每个对象.
现在,我们试图重写的toString() 在下面的类书:
@Override
public String toString() {
return name + " - " + author;
}
我们覆盖的toString() 返回书的名称和作者. 所以,当你运行该程序,我们得到一个清单如下:

它看起来我们已经找到好? 不,他们必须! 我们需要显示的封面作为开场的形象,他们必须这样做? 大家都知道该节目的时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的.

然而,在未完成的. 你有没有注意到,当我们点击一个项目,他们没有看到任何现象的@@. 这是因为我们已经重写应该渲染器创建没有更多的渲染效果默认 (当选择背景颜色 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;
}
就是这样, 现在,我们可以执行,然后选择项目.

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

参考文章在: codejava.net



让我问, 服用标签, ImageIcon的, 一个JRadioButton阵列以书面形式如何JList的爵士. 因为我不能选择单选按钮
仅凭这一点还不清楚.
我哥哥问我 :
有方法list.setCellRenderer(新BookRenderer());
它重Renderer对象VS类BookRenderer()
但不调用该方法getListCellRendererComponent()
如何才能显示正确的DC ?
广告请问怎么才能选择JList的多个项目, JList中只选择的是 1 项目
你试试谷歌搜索 “选择multil项目JList的NHE”
在此行中的明星这显示java.lang.NullPointerException错误:
lbIcon.setIcon(新的ImageIcon(的getClass().的getResource(
“/nguyenvanquan7826 / JList的/” + book.getIconName() + “.JPG”)));
在此功能线:
公共组件getListCellRendererComponent();
你看,像到正确的文件夹路径而轻质. 如果还是失败,可以看到如何在这里解决: https://cachhoc.net/san-pham/