`
djsl6071
  • 浏览: 595311 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

定制JList的显示

阅读更多

定制JList的显示

Java平台的基本类(Java Foundation Classes)或者说是Swing 组件是一套图形界面的开发
包.使用Swing组件可让你的应用程序简单易用而不失丰富的表现,以此让你的应用程序具有
友好的用户界面.本文将着重说javax.swing.JList组件以及如何定制它的显示.

问题:

在图形界面上,javax.swing.JList显示成一个列表。默认时,在JList上仅显示一个对象的
toString()方法的返回值.比方说,你的应用程序里的JList上显示一串java.util.Locale对
象,用户通常在列表上选则一个选项来改变应用程序所用的语言环境.

想一想,JList是如何来显示一个包含Locale对象实例的数据模型的呢? JList是让
javax.swing.ListCellRenderer来显示这些对象的.正如你所想,ListCellRenderer将会
把对象的toString()方法的返回值显示出来.但是,Locale对象的实例返回的是ISO代码,
然而,这样的代码肯定不满足"友好的用户界面"的要求的.JList在默认情况下将显示出
如下图中的用户不知所云的那些东西.
http://java.sun.com/developer/technicalArticles/GUI/jlist/Figure1-DefaultDisplay.jpg

又一个例子也可说明在默认情况下,JList并不向终端用户显示任何有意义的数值.譬如,
你用的绘图程序会提供一个颜色选择的列表,你也许会从中选用一样颜色来填充某区域,
或者绘制一条某种颜色的线段.尽管把java.awt.Color的实例对象放进JList,这样做也是
非常有道理的,但是你会发现结果却是不实用.正如下图中那个放置在javax.swing.JFrame
右边的Color对象的列表.
http://java.sun.com/developer/technicalArticles/GUI/jlist/Figure2-Locale.jpg

Color对象的toString()方法返回的是颜色的RGB各个分量的亮度值的报告.除非你为显示
效果做点明显的区别外,用户是看不懂的.就拿上图中第三行被选中的那条来说:
255,200,0是橙黄色的RGB分量.默认情况下,你并不能直观地观察到颜色值和颜色的显示是否
正确.

当然,你也许会把java.lang.String对象的实例放进JList去替代Color对象实例.但是这么做
却放弃了使用JList的初衷.你的初衷是:用户是要从列表里选用一种颜色并非仅是选一段文本.

用Color对象的时候,要让JList的那些监听变化的监听器来返回一个实际看到的颜色.如果是
用String对象来替代的话,JList将把String传递到监听器,然后监听器去找到与这个String
对应的颜色来填充某区域或者是画一条这种颜色的线段.

如果是让用户来选颜色,把实际的Color对象实例放到JList中是对的.可是为了显示颜色,不得不
另做一些工作.JList的默认行为方式对于像Color或者Locale对象以及其他大多数对象来说并
不适合意想的要求.

解决办法

应用程序应当以友好的用户界面来显示数据,而不是把像Locale对象的ISO代码或者是颜色的RGB值
显示出来,这样才能贴近用户.ISO代码或者RGB值对编程的人来说或许有用,但是并不适合终端用户.

幸好,Locale对象有个displayName属性适合用来为用户显示信息.我们可用这个属性来替代
toString()方法用在JList的显示上,这样一来就能使得JList更具可读性.比较以下代码片段中Locale
对象的toString()方法和getDisplayName方法的返回值:

Locale[] locales = {new Locale("en", "US"), new Locale("fr", "FR"),
                    new Locale("th", "TH"), new Locale("es", "MX"),
                    new Locale("ja", "JP")};
               
System.out.printf("%-10s\t%s\n", "toString", "getDisplayName");
System.out.printf("%-10s\t%s\n", "--------", "--------------");
for(Locale l: locales) {
    System.out.printf("%-10s\t%s\n", l.toString(), l.getDisplayName());
}

以上代码在一台美国英语环境的机器的控制台上将显示出如下的结果:
toString        getDisplayName

en_US           English (United States)
fr_FR           French (France)
th_TH           Thai (Thailand)
es_MX           Spanish (Mexico)
ja_JP           Japanese (Japan)

displayName属性对用户来说更具可读性,也更贴近用户.如果应用程序里的JList使用
displayName,那么看起来会类似下图中的样子
http://java.sun.com/developer/technicalArticles/GUI/jlist/Figure3-userfriendly.jpg

这个效果是怎么实现的呢? 就如前面的简述中提到过用ListCellRenderer来显示文本.
为了让列表达到友好的用户界面的要求,关键是创建你自己的renderer.如上的例子里就用
displayName来替代默认的toString()方法的返回值.

类似地,如果你的应用程序中的JList是放颜色的,也可以定制renderer来显示实际的颜色或
者是显示颜色的名称.下图给出了一个颜色列表的样子
http://java.sun.com/developer/technicalArticles/GUI/jlist/Figure4-colorlist.jpg

javax.swing.DefaultListCellRenderer继承于javax.swing.JLabel并且实现了
ListCellRenderer接口.从先前的例子来看,适合的解决方案包括继承DefaultListCellRenderer
和实现ListCellRenderer接口里的getListCellRendererComponent方法.虽然自定义的
ListCellRenderer可继承自任何Component,还是用DefaultListCellRender的好,因为它继承
自JLabel并且还为设置文本,颜色甚至是图片提供了便利途径.必须实现的一个重要方法是:
public Component getListCellRendererComponent(JList list, Object value,
              int index,boolean isSelected, boolean cellHasFocus)

为了改进Locale的显示效果,你需要像以下代码那样扩展DefaultListCellRenderer:
package com.sun.demo.cellrenderer;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import java.util.Locale;
import java.awt.Component;
public class LocaleRenderer extends DefaultListCellRenderer {   
  /** Creates a new instance of LocaleRenderer */
  public LocaleRenderer() {}
   
  public Component getListCellRendererComponent(JList list,
                                              Object value,
                                              int index, boolean isSelected,
                                              boolean cellHasFocus) {

    super.getListCellRendererComponent(list,
                                       value,
                                       index,
                                       isSelected,
                                       cellHasFocus);
    Locale l = (Locale)value;
    setText(l.getDisplayName());
    return this;
  }
}

如上代码片段中的装饰器先调用它的超类的getListCellRendererComponent()方法来绘制出组件,
而后仅简单的作了点贡献:用被选中的Locale对象的getDisplayName()方法的返回值来设置文本.

那么如何让JList来使用这个新的装饰器呢?很简单,调用setCellRenderer()方法并且把新创建的
ListCellRenderer作参数传递进去.现在,JList将用定制的装饰器来展现列表里每个Locale对象.

ListCellRenderer localeRenderer = new LocaleRenderer();
localeList.setCellRenderer(localeRenderer);

使用类似的方式来展现颜色对象.同样,我们还需要定制装饰器,还是简单地来扩展
DefaultListCellRenderer:

package com.sun.demo.cellrenderer;
import javax.swing.ListCellRenderer;
import javax.swing.JLabel;
import javax.swing.DefaultListCellRenderer;
import java.awt.Color;
import javax.swing.JList;
import java.awt.Component;
import java.util.HashMap;


public class ColorRenderer
extends DefaultListCellRenderer {
   
  /** Creates a new instance of ColorRenderer */
  public ColorRenderer() {
    initColorMap();
  }
   
  public Component getListCellRendererComponent(JList list,
                                                Object value,
                                                int index,
                                                boolean isSelected,
                                                boolean cellHasFocus) {

    super.getListCellRendererComponent(list,
                                       value,
                                       index,
                                       isSelected,
                                       cellHasFocus);
    if (value instanceof Color) {
      Color color = (Color)value;
      String strColor = (String)colorMap.get(color);
      if (strColor != null) {
        setText(strColor);
      }
      setBackground(color);
    }
    return this;
  }
   
  private void initColorMap() {
    colorMap = new HashMap();
    for (int x=0; x < colorAssociation.length; ++x) {
      colorMap.put(colorAssociation[x][0], colorAssociation[x][1]);
    }
    colorAssociation = null;
  }
   
  private HashMap colorMap;
  private Object[][] colorAssociation = {
    {Color.BLACK, "Black" },
    {Color.BLUE, "Blue" },
    {Color.CYAN, "Cyan" },
    {Color.DARK_GRAY, "Dark Gray" },
    {Color.GRAY, "Gray" },
    {Color.GREEN, "Green"},
    {Color.LIGHT_GRAY, "Light Gray" },
    {Color.MAGENTA, "Magenta"},
    {Color.ORANGE, "Orange" },
    {Color.PINK, "Pink" },
    {Color.RED, "Red"},
    {Color.WHITE, "White"},
    {Color.YELLOW, "Yellow"},
  }; 
}

本例与Locale的例子有点不同.不同之处在于,装饰器不仅设置了选项格子的文本,还设置了与颜色
对应的背景色.因为Color对象本身里没有内建的文本名,所以你需要把颜色名与颜色关联起来.
如上代码片段里,用HashMap类创建一个Color对象到String对象的映射.实例化这个装饰器前,应初
始化HashMap.这样才能使得HashMap在后来调用getListCellRendererComponent()方法时有实际作用.

总结

最后说一下对象如何在JList里显示.你不必靠对象提供一个实用的toString()方法,因为你可以
用ListCellRenderer来显示你想要和对象相关的任何文本.此外,在你选用来充当ListCellRenderer的
组件上可选用任何颜色或者绘制你想要的图象.这样的装饰器也能很好地用于javax.swing.JComboBox.
用定制的ListCellRenderer,使JList或JComboBox上的文本更趋于界面友好的要求.

 
分享到:
评论

相关推荐

    JFC Swing活学活用系列之定制JList显示.rar

    本资料“JFC Swing活学活用系列之定制JList显示”聚焦于如何利用Swing中的JList组件来实现自定义的显示效果。 JList是一个可滚动的组件,允许用户从一系列选项中进行选择。默认情况下,JList会按照字符串形式展示...

    java构建几种个性的JList

    你可以使用`ListCellRenderer`来定制每个列表项的显示,包括设置图片和文字的位置。 2. **复选框的JList** 如果需要用户可以选择多个选项,可以创建一个带有复选框的`JList`。这需要使用`CheckBoxModel`,例如`...

    JList事件监听器的实现例子

    在Java Swing库中,`JList`是一个非常重要的组件,用于显示一组可选择的项。在用户与`JList`进行交互时,如选择、取消选择等操作,我们可能需要捕获这些事件并做出响应。这就涉及到事件监听器的使用。本教程将详细...

    java_swing_更酷的Jlist.

    在Swing框架中,`JList` 和 `JComboBox` 都可以使用 `ListCellRenderer` 来定制其单元格的渲染方式。`ListCellRenderer` 的作用在于为列表中的每个条目提供一个自定义的视图组件。这个接口定义了一个方法 `...

    java swing带复选框的JList控件

    `DefaultListModel` 用于存储列表中的项,而 `ListCellRenderer` 则负责定制每个列表项的显示方式,包括添加复选框。 以下是一些关键步骤: 1. **创建 `DefaultListModel`**: 首先,我们需要创建一个 `...

    swing的课件以及有关的习题

    1. JList:JList是一个可滚动的组件,用于显示一组项目,用户可以选择一个或多个项目。你可以通过ListModel接口来管理列表中的数据,可以设置单选或多选模式,并且可以通过自定义CellRenderer来自定义列表项的显示...

    一个java应用程序

    2. **JList**: JList类是Swing中的一个容器,用于显示一系列的元素。这些元素可以是字符串、图标或者自定义对象。通过使用ListModel接口,JList可以动态地改变其显示的列表数据。 3. **ListModel**: 这是JList用来...

    java media

    - **JList**:`JList`是Swing组件之一,用于显示列表项。 - **JPopupMenu**:`JPopupMenu`是一个弹出式菜单,通常用于上下文敏感的操作。 - **示例**:在提供的代码中,可以看到如何将一个`JPopupMenu`与一个`JList`...

    java的一个变成小例子

    总的来说,"java的一个变成小例子",特别是"实例4 彩色列表框",是一个涉及Java Swing组件`JList`的定制,以及如何通过自定义渲染器实现彩色列表项的示例。这个例子可以帮助初学者理解如何在Java图形用户界面(GUI)...

    JavaSwing下拉框列表框补全提示的类

    在实现这样的功能时,开发者可能会使用 `JComboBox` 或 `JList` 的 `setRenderer` 方法来定制渲染器,确保在渲染过程中能够触发 `ViewTooltip` 的显示。此外,可能还需要利用 `MouseListener` 和 `...

    [ java + swing ] demo

    通过对JFrame、JPanel等容器组件的合理布局,配合JButton、JLabel、JTextField和JList等交互元素,可以实现用户登录验证、数据显示等功能。同时,利用事件监听机制可以响应用户的各种操作,增强应用的交互性。

    swing带滚动条的多选下拉选择框(name code形式)

    2. **构建JList**: 使用JList来显示所有的选项,设置其MultiSelectionEnabled属性为true,以便支持多选。 ```java JList[]&gt; list = new JList(new NameCodeComboBoxModel()); list.setSelectionMode...

    浅析使用模型参数构造Java Swing组件.zip

    2. **JList的ListModel**:JList用于显示单列数据,它的数据模型是ListModel。通过实现ListModel接口或使用AbstractListModel子类,你可以控制列表中的项和它们的顺序。例如,动态添加、删除或更新列表项。 3. **...

    学员信息管理系统

    在学员信息管理系统中,JList可能用于显示所有学员的列表,用户可以快速查找、选择特定的学员进行操作,如查看详细信息、修改记录或者执行其他管理任务。 除此之外,由于系统还涉及到了"Oracle"标签,我们可以推断...

    自定义列表框,可以屏蔽某些元素

    例如,在Java中,你可以使用JList类,并通过ListModel接口来控制显示的内容。在Python的tkinter库中,可以利用Listbox对象和相应的事件绑定来实现类似功能。 要创建这样一个自定义列表框,你需要执行以下步骤: 1....

    JAVA创建带图片的List.pdf

    总之,本文档的知识点围绕着Java Swing组件编程的核心概念,包括JList的使用、ListCellRenderer接口的实现、图像的加载和显示,以及外观和感觉的配置。通过这些知识点,我们可以创建一个功能丰富、外观定制的用户...

    swing 组件 demo

    8. **JList**: JList显示一组可选择的项目,用户可以单击或使用键盘导航进行选择。可以配合ListModel使用,自定义列表项。 9. **JTable**: JTable用于显示二维表格数据,支持排序、选择和编辑。开发者可以通过...

    java swing

    7. JList与JTable:用于显示列表数据和表格数据,JList适用于展示一列数据,JTable则更强大,能处理行列数据。 8. JTree:用于显示层次结构的数据,如文件系统目录结构。 Swing 还提供了许多高级特性,如模态...

    openSwing组件

    8. **JList**: JList显示一个可滚动的项目列表,用户可以选择一个或多个项。适合用于展示选项列表。 9. **JTable**: JTable用于显示和编辑表格数据。它可以处理多列和多行的数据,支持排序、选择和编辑。 10. **...

    swing各种组件举例

    6. **JList**: JList 可以显示一组项目的列表,用户可以选择其中的一个或多个。你可以通过ListModel来管理列表中的数据。 7. **JTextArea** 和 **JTextField**: 这两个组件都是文本输入组件。JTextField用于单行...

Global site tag (gtag.js) - Google Analytics