分类: JAVA技术2007-08-11
01:02 18485人阅读 评论(11) 收藏 举报
        今天从《java核心编程》中学习了JList 的用法,写下自己的感受,以免时间久了又忘记了。
        JList从含义上看是一个列表,有点和JComboBox相似。其实不然,JComboBox的内容只能用一列显示出来,而JList的内容可以多列显示,我想这就是JList存在的意义。
        首先是JList的构造,没什么特别的,给他一个对象数组就可以了,代码说明一切:
String[] words= { "quick", "brown", "hungry", "wild"};

JList wordList = new JList(words);
        然后就是JList的多列显示,使用setLayoutOrientation(参数)方法来实现,共有3个参数,默认值是JList.VERTICAL,只用一列来显示,但不会自动滚动,需要添加滚动面板才能出现滚动条。setVisibleRowCount(n);方法可以设置最多显示多少行(若没有添加滚动面板,此设置无效,所有内容均会显示)。另外两个参数是JList.VERTICAL_WRAP和JList.HORIZONTAL_WRAP,其含义分别是“在保证行数不超过setVisibleRowCount(n)的情况下,纵向或横向排列元素”。此时滚动面板无效,因为行数永远不可能超标,因此滚动面板也永远不会出现 。比如最大显示行数为4,总共有5个元素,显示结果如下:
        接下来就是事件的处理,与其他控件不同,他处理的不是Action事件,而是ListSelectionEvent事件,监听器为ListSelectionListener。在这个事件处理过程中,又将鼠标的操作分为2种状态:1.按下鼠标不松手,在各个元素间拖动;2.松开鼠标。也就是说,当你按下鼠标后,会触发一个事件,拖动到另一个控件,又触发一个事件,继续拖动则继续触发事件,最后松手,触发一个事件。那么,你如何区分这2种情况呢?ListSelectionEvent提供了一个方法getValueIsAdjusting(),如果该方法返回true,则代表情况1;反之代表情况2。同时请注意,JList控件不提供鼠标双击元素的处理事件,若要处理鼠标双击的情况,则应该添加鼠标监听器,代码如下:
public void mouseClicked(MouseEvent evt)

{

   )

   {

      JList source = (JList) evt.getSource();

      Object[] selection = source.getSelectedValues();

      doAction(selection);

   }

}
        JList还有一个很有趣的特性,就是你根本没必要把元素存入一个数组,只要能临时把元素计算出来就行。具体实现方法就是继承AbstractListModel类,实现其中的2个方法即可,代码如下:
class WordListModel extends AbstractListModel

{

   /**

      Constructs the model.

      @param n the word length

   */

   public WordListModel(int n) { length = n; }



   public int getSize()

   {

      , length);

   }



   public Object getElementAt(int n)

   {

      StringBuilder r = new StringBuilder();;

      ; i < length; i++)

      {

         ));

         r.insert(, c);

         n );

      }

      return r;

   }



   private int length;

   public static final char FIRST = 'a';

   public static final char LAST = 'z';

}
        接下来就是元素的插入和删除了,这个看似简单的功能,实现起来可不是一件容易的事情。最天真的想法:我用一个数组构造JList,那么我只要将数组中的元素增加或减少,那么JList的内容自然会增加或减少。这绝对是个错误的认识,对数组内容的修改不会影响到JList。正确的做法是,用一个特别的类来构造JList,也就是DefaultListModel类,然后对这个类的内容添加或者减少,那么JList会很快的做出响应。为什么这个类会这么神奇呢?查看他的源代码得知,他继承自AbstractListModel类,内部用一个Vector来存储数据。在它的添加元素方法中,他调用了父类的fireIntervalAdded方法,同理,在他的删除元素方法中,他调用了父类的fireIntervalRemoved方法,因此可以将JList的内容刷。
    最后就是内部元素的绘制了。在JList中,内部显示的每一个元素叫做一个Cell。如果我想让内部元素的显示方式更完美一些,比如居中显示,比如每一个Cell字体颜色不一样,那么我们就要借助JList的setCellRenderer方法来实现。该方法接受一个实现了ListCellRenderer接口的参数,而该接口只有一个方法getListCellRendererComponent,但是,该方法的实现是比较简单的,他只需要构造一个Component对象并返回这个对象,这个对象就是一个Cell。因此,真正的难点在于,如何修改这个Component的内部显示方式,从而使得他可以满足一个Cell的显示方式。一般来讲,我们都是用一个JPanel作为绘制Cell的对象,因为在JPanel上显示文字和图像都是很方便的。最后说一个小技巧,我们实现一个类,从JPanel继承而来,同时又实现了ListCellRenderer接口,那么我们只用实现这一个类就可以了,到时候把自己返回,呵呵,真的好方便哦。下面我们来看一下具体的代码:
 class FontCellRenderer extends JPanel implements ListCellRenderer

 {

    public Component getListCellRendererComponent(JList list, Object value, int index,

       boolean isSelected, boolean cellHasFocus)

    {

       text = (String)value;

       background = isSelected ? list.getSelectionBackground() : list.getBackground();

       foreground = isSelected ? list.getSelectionForeground() : list.getForeground();

       return this;

    }



    public void paintComponent(Graphics g)

    {

       g.setColor(background);

       g.fillRect(, getWidth(), getHeight());  //设置背景色

       g.setColor(foreground);

       g.drawString(text, );   //在制定位置绘制文本

    }



    public Dimension getPreferredSize()

    {

       );   //Cell的尺寸

    }



    private String text;

    private Color background;

    private Color foreground;

 }

    我们来简单分析一下上面的代码。我们定义了一个类,继承自JPanel并实现了指定接口。在这个类里面有3个私有变量,分别存放Cell的内容,Cell的前景色和背景色。因为Cell的绘制完全由程序员来实现,因此这些内容都是必须的。之后就是接口中规定的getListCellRendererComponent方法,这个方法其实很简单,就是对三个变量进行赋值并返回自己。其中前景色和背景色又分为2中情况,就是选中时和未选中时,这点需要注意。接下来我们有实现了2个方法,其中PaintComponent负责Cell的绘制,GetPreferedSize负责设置Cell的尺寸。对于尺寸有一点需要注意,上述代码给的是一个固定尺寸。如果尺寸不固定有变化,那么最终会选择最大的那个尺寸作为所有Cell的尺寸。如果你想在绘制Cell的时候加入什么花样,那么尽管在PaintComponent中施展你的才华吧,上述代码只提供了在指定位置绘制文本,算是抛砖引玉了。这里也有一点需要注意,那就是JPanel本身提供的“居中”,“设置背景色”,“设置前景色”,等方法一律失效,所有的功能一律要使用JAVA
2D来实现,算是一点小小的难度。

JList用法小结的更多相关文章

  1. 转载:Hadoop排序工具用法小结

    本文转载自Silhouette的文章,原文地址:http://www.dreamingfish123.info/?p=1102 Hadoop排序工具用法小结 发表于 2014 年 8 月 25 日 由 ...

  2. [No000010]Ruby 中一些百分号(%)的用法小结

    #Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...

  3. C++ typedef用法小结 (※不能不看※)

    C++ typedef用法小结 (※不能不看※) 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不 ...

  4. 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)

    函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...

  5. 1:CSS中一些@规则的用法小结 2: @media用法详解

    第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下     at-rule ...

  6. 英语语法最终珍藏版笔记- 21it 用法小结

    it 用法小结 it 在英语中的意思较多,用法较广,现总结如下. 一.it作句子的真正主语 1.it 指前面已经提到过的人或事物,有时指心目中的或成为问题的人或事物,作真正主语. 例如: What’s ...

  7. [转]ssh常用用法小结

    ssh常用用法小结 1.连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机, ...

  8. 结构体定义 typedef struct 用法详解和用法小结

    typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...

  9. typedef用法小结

    typedef用法小结- - 注意:本文转自网络,版权归原作者所有. typedef typedef用法小结- - 这两天在看程序的时候,发现很多地方都用到typedef,在结构体定义,还有一些数组等 ...

随机推荐

  1. ACdream 1148(莫比乌斯反演+分块)

    传送门:GCD SUM 题意:给出N,M执行如下程序:long long  ans = 0,ansx = 0,ansy = 0;for(int i = 1; i <= N; i ++)   fo ...

  2. 【Java&Android开源库代码剖析】のAndroid-Universal-Image-Loader-part1

    做Android app开发的同学应该都听说过或者用过nostra13的Android-Universal-Image-Loader开源库,它在图片异步加载.缓存和显示等方面提供了强大灵活的框架.之前 ...

  3. Cocos2dx 3.x创建Layer的步骤

    创建 1.新建类文件.注意文件夹为Classes下.否则文件不能正常找到. 2.改动预编译头.如用VS,默觉得#pragma once,为了兼容,改为#ifndef | #define | #endi ...

  4. 从头来之【图解针对虚拟机iOS开发环境搭建】 (转)

    1.下载Mac OSX10.9. 点击下载 2.下载VMware Workstation 10,点击下载,网页中包含序列号.安装VM. 3.VM10-MacOS补丁.用于创建苹果虚拟机. 安装VM就不 ...

  5. 在IIS上发布Web(使用VS2005)

    最近想在IIS上发布网站,弄了一下午.遇到很多问题,幸运的是都一一解决了,现在把解决问题的过程分享出来: 安装好IIS后,在VS2005上写了个网站(新建-->网站-->ASP.NET网站 ...

  6. WPF界面设计技巧(1)—不规则窗体图文指南

    原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...

  7. PHP移动互联网开发笔记(2)——变量及常量

    原文地址:http://www.php100.com/html/php/rumen/2014/0326/6703.html 一.PHP5.4的基本的语法格式 1.PHP的切割符 view source ...

  8. 彻底理解Javascript原型继承

    彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...

  9. C#实现仿QQ震动

    前提:新建winForm窗体应用程序,放置一个Button,设置按钮的单击事件 ; i < ; i++) { Point p = this.FindForm().Location; ,p.Y+) ...

  10. poj 2992 Divisors 整数分解

    设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数 将m分解质因数得到 p1有a1个 p2有a2个 .... 因为每一个质因数能够取0~ai个(所有取0就是1,所有取ai就是m) ...