[的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/