JList用法小结
今天从《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个元素,显示结果如下:
![](https://img-blog.csdnimg.cn/img_convert/8f649efb73cdcc9a4fbf593e9b22a086.png)
public void mouseClicked(MouseEvent evt)
{
if (evt.getClickCount() == 2)
{
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()
{
return (int) Math.pow(LAST - FIRST + 1, length);
}
public Object getElementAt(int n)
{
StringBuilder r = new StringBuilder();;
for (int i = 0; i < length; i++)
{
char c = (char)(FIRST + n % (LAST - FIRST + 1));
r.insert(0, c);
n = n / (LAST - FIRST + 1);
}
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的内容刷。
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(0, 0, getWidth(), getHeight()); //设置背景色
g.setColor(foreground);
g.drawString(text, 5, 15); //在制定位置绘制文本
}
public Dimension getPreferredSize()
{
return new Dimension(30, 20); //Cell的尺寸
}
private String text;
private Color background;
private Color foreground;
}