1. 列表

1.1 JList构件

JList可以将多个选项放置在单个框中。为了构建列表框,首先需要创建一个字符串数组,然后将这个数组传递给JList构造器。

String[] words= { "quick", "brown", "hungry", "wild", . . . };

JList wordList = new JList<>(words);

列表框不能自动滚动,要想为列表框加上滚动条,必须将它插入到一个滚动面板中:

JScrollPane scrollPane = new JScrollPane(wordList);

然后应该应该把滚动面板而不是列表框,插入到外围面板上。

默认情况下,列表框构件可以显示8个选项;可以使用setVisibleRowCount方法改变这个值:

wordList.setVisibleRowCount(4); //display 4 items

还可以使用以下三个值中的任意一个来设置列表框摆放的方向:

• JList.VERTICAL ( 默认值) :垂直摆放所有选项。

• JList.VERTICAL_WRAP: 如果选项数超过了可视行数,就开始新的一列。

•  JList.HORIZONTAL_WRAP:  如果选项数超过了可视行数,就开始新的一行,并且按照水平方向进行填充。

在默认的情况下,用户可以选择多个选项。为了选择多个选项,只需要按住CTRL键,然后在要选择的选项上单击。要选择处于连续范围内的选项,首先选择第一个选项,然后按住SHIFT键,并在最后一个选项上点击即可。

使用setSelectionMode方法,还可以对用户的选择模式加以限制:

wordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//select one item at a time

wordList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);//select one item or one range of items

列表框使用一种不同的事件通知机制,它不需要监听动作事件,而是监听列表选择事件。可以向列表构件添加一个列表选择监听器,然后在监听器中实现下面这个方法:

public void valueChanged(ListSelectionEvent evt)

在用户选择了若干个选项的同时,将产生一系列列表选择事件。假如用户在一个新选项上单击,当鼠标按下的时候,就会有一个事件来报告选项的改变。这是一种过渡型事件,在调用event.getValueIsAdjusting()时,如果该选择仍未最终结束则返回true。然后,当松开鼠标时,就产生另一事件,此时event.getValueIsAdjusting()返回false。如果你对这种过渡型事件不感兴趣,那么可以等待event.getValueIsAdjusting()调用返回false的事件。不过,如果希望只是要点击鼠标就给用户一个即时反馈,那么就需要处理所有的事件。

一旦被告知某个事件已经发生,那么就需要弄清楚当前选择了哪些选项。如果是单选模式,调用getSelectedValue可以获取所有选中列表的元素的值;否则调用getSelectedValues返回一个包含所有选中选项的对象数组。之后,可以以常规方式处理它。

for(String value : wordList.getSelectedValuesList())//do something with value

注意:列表构件不响应鼠标的双击事件。正如Swing设计者所构想的那样,使用列表选择一个选项,然后点击某个按钮执行某个动作。但是,某些用户界面允许用户在一个列表选项上双击鼠标,作为选择一个选项并调用一个默认动作的快捷方式。如果想实现这中行为,那么必须对这个列表框添加一个鼠标监听器,然后按照下面这样捕获鼠标事件:

public voidmouseClicked(MouseEvent evt)

{if (evt.getClickCount() == 2)

{

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

Object[] selection=source.getSelectedValues();

doAction(selection);

}

}

下面的程序展示了一个填入字符串的列表框。请注意valueChanged方法是怎样根据被选项来创建消息字符的。

packagelist;importjava.awt.BorderLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;import javax.swing.*;importjavax.swing.event.ListSelectionEvent;importjavax.swing.event.ListSelectionListener;public class ListFrame extendsJFrame {private static final int DEFAULT_WIDTH=400;private static final int DEFAULT_HEIGHT=300;privateJPanel listPanel;private JListwordlist;privateJLabel label;privateJPanel buttonPanel;privateButtonGroup group;private String prefix="The ";private String suffix="fox jump over the lazy dog.";publicListFrame(){this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

String[] words= {"quick","brown","hungry","wild","silent","huge","private","abstract","static","final"};

wordlist= new JList<>(words);

wordlist.setVisibleRowCount(4);

JScrollPane scrollPane= newJScrollPane(wordlist);

listPanel= newJPanel();

listPanel.add(scrollPane);

wordlist.addListSelectionListener(newListSelectionListener(){

@Overridepublic voidvalueChanged(ListSelectionEvent e) {

StringBuilder text= newStringBuilder(prefix);for(String value : wordlist.getSelectedValuesList()){

text.append(value);

text.append(" ");

}

text.append(suffix);

label.setText(text.toString());

}

});

buttonPanel= newJPanel();

group= newButtonGroup();

makeButton("Vertical", JList.VERTICAL);

makeButton("Vertical Wrap",JList.VERTICAL_WRAP);

makeButton("Horizontal Wrap",JList.HORIZONTAL_WRAP);this.add(listPanel, BorderLayout.NORTH);

label= new JLabel(prefix+suffix);this.add(label, BorderLayout.CENTER);this.add(buttonPanel, BorderLayout.SOUTH);this.setTitle("ListTest");this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}/*** 设置按钮

*@paramstring 按钮名字

*@paramvertical 按钮类型*/

private void makeButton(String string, final intvertical) {

JRadioButton button= newJRadioButton(string);

buttonPanel.add(button);if(group.getButtonCount()==0) button.setSelected(true);

group.add(button);

button.addActionListener(newActionListener(){

@Overridepublic voidactionPerformed(ActionEvent e) {

wordlist.setLayoutOrientation(vertical);

listPanel.revalidate();//重新布局并绘制

}

});

}public static voidmain(String[] args) {newListFrame();

}

}

1.2 列表模式

通过前一节,我们已经对列表构件的一些常用方法有了一定的了解:

1)指定一组在列表中显示的固定字符串

2)将列表放置到一个滚动面板中

3)捕获列表选择事件

列表构件使用了模型-视图-控制器这种设计模式,将可视化外观(以某种方式呈现的一列选项)和底层数据(一个对象集合)进行了分离。JList类负责数据的可视化外观。实际上,它对这些数据是怎样存储的知之甚少,它只知道可以通过某个实现了ListModel接口的对象来获取这些数据:

public interface ListModel{intgetSize();

E getElementAt(inti);voidaddListDataListener(ListDataListener l);voidremoveListDataListener(ListDataListener l);

}

通过这个接口,JList就可以获得元素的个数,并且能够获取每一个元素。另外,JList对象可以将其自身添加为一个ListDataListener。在这种方式下,一旦元素集合发生了变化,就会通知JList,从而使它能够重新绘制列表。

为什么这种通用性非常有用呢?为什么JList对象不直接存储一个对象数组呢?

请注意,这个接口并未指定这些对象是怎样存储的。尤其是,它根本就没有强制要求这些对象一定要被存储!无论何时调用getElementAt方法,它都会对每个值进行重新计算。如果想显示一个极大的集合,而且又不想存储这些值,那么这个方法可能会有所帮助。

下面我们举一个例子:允许用户在列表框中所有三个字母的单词当中进行选择。

三个字母的组合一共有26x26x26=17576个。我们不希望将所有这些组合都存储起来,而是想用户滚动这些单词的时候,依照请求对它们重新计算。

事实证明,这实现起来很容易。其中比较麻烦的部分,即添加和删除监听器,在我们所继承的AbstractListModel类中已经为我们实现了。我们只需要提供getSize和getElementAt方法即可:

class WordListModel extends AbstractListModel{public WordListModel(int n) { length =n; }public int getSize() { return (int) Math.pow(26, length); }public String getElementAt(intn)

{//compute nth string

. . .

}

. . .

}

既然我们已经有了一个模型,那么就可以构建一个列表,让用户可以通过滚动来选择该模型所提供的任意元素:

JList wordList = new JList<>(new WordListModel(3));

wordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

JScrollPane scrollPane= new JScrollPane(wordList);

这里的关键是这些字符串从来都没有被存储过,而只有那些用户实际要求查看的字符串才会被生成。

我们还必须进行另外一项设置。那就是,我们必须告诉列表构件,所有的选项都有一个固定的宽度和高度。最简单的方法就是通过设置单元格的尺寸大小(cell dimension)来设定原型单元格的值(prototype cell value):

wordList.setPrototypeCellValue("www");

原型单元格的值通常用来确定所有单元格的尺寸(我们使用字符串“www"是因为"w"在大多数字体中都是最宽的小写字母)。另外,可以像下面这样设置一个固定不变的单元格尺寸。

wordList.setFixedCellWidth(50);

wordList.setFixedCellHeight(15);

如果你既没有设置原型值也没有设置固定的单元格尺寸,那么列表构建就必须计算每个选项的宽度和高度。这可能需要花费更长的时间。

完整的程序代码如下:

WordListModel.java

packagelongList;importjavax.swing.AbstractListModel;//计算生成列表元素

public class WordListModel extends AbstractListModel{private static final long serialVersionUID = 1L;private intlength;public static final char FIRST = 'a';public static final char LAST = 'z';public WordListModel(intn){

length=n;

}

@Overridepublic intgetSize() {//TODO Auto-generated method stub

return (int) Math.pow(LAST-FIRST+1, length);

}

@Overridepublic String getElementAt(intn) {//TODO Auto-generated method stub

StringBuilder r = newStringBuilder();for(int i=0;i

r.insert(0,c);

n=n/(LAST-FIRST+1);

}returnr.toString();

}

}

LongListFrame.java

packagelongList;importjava.awt.BorderLayout;importjava.awt.Container;import javax.swing.*;importjavax.swing.event.ListSelectionEvent;importjavax.swing.event.ListSelectionListener;//允许用户在列表框中所有三个字母的单词当中进行选择

public class LongListFrame extendsJFrame{private static final long serialVersionUID = 1L;private JListwordList;privateJLabel label;private String prefix = "The quick brown ";private String suffix = " jumps over the lazy dog.";publicLongListFrame(){

wordList= new JList(new WordListModel(3));

wordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

wordList.setPrototypeCellValue("www");

JScrollPane scrollPane= newJScrollPane(wordList);

JPanel p= newJPanel();

p.add(scrollPane);

wordList.addListSelectionListener(newListSelectionListener(){

@Overridepublic voidvalueChanged(ListSelectionEvent e) {//TODO Auto-generated method stub

setSubject(wordList.getSelectedValue());

}

});

Container contentPane=getContentPane();

contentPane.add(p, BorderLayout.NORTH);

label= new JLabel(prefix+suffix);

contentPane.add(label, BorderLayout.CENTER);

setSubject("fox");this.setTitle("LongListTest");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);this.pack(); //按组件的首选大小布局

}//在label中添加选中的信息

public voidsetSubject(String word) {

StringBuilder text= newStringBuilder(prefix);

text.append(word);

text.append(suffix);

label.setText(text.toString());

}public static voidmain(String[] args) {newLongListFrame();

}

}

1.3 插入和移除值

不能直接编辑列表值的集合。相反地,必须先访问模型,然后再添加或移除元素。

我们需要先构建一个 DefaultListModel对象,填入初始值,然后将他与一个列表关联起来。 DefaultListModel类实现了ListModel接口,并管理着一个对象集合。

DefaultListModel model = new DefaultListModel<>();

model.addElement("quick");

model.addElement("brown");

. . .

JList list = new JList<>(model);

现在,就可以从model对象中添加或移除元素值了。然后,model对象会告知列表发生了哪些变化,接着,列表会对自身进行重新绘制。

model.removeElement("quick");

model.addElement("slow");

由于历史遗留问题,DefaultListModel类使用的方法名和集合类的方法名并不相同。默认的列表模型在内部是使用一个向量来存储元素值的。

1.4 值的绘制

具有绘画单元格的类表框如下程序如下:

FontCellRenderer.java

packagelistRendering;import java.awt.*;import javax.swing.*;/*** A cell renderer for Font objects that renders the font name in its own font.*/

public class FontCellRenderer extends JComponent implements ListCellRenderer{privateFont font;privateColor background;privateColor foreground;public Component getListCellRendererComponent(JList extends Font>list,

Font value,int index, boolean isSelected, booleancellHasFocus)

{

font=value;

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

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

}public voidpaintComponent(Graphics g)

{

String text=font.getFamily();

FontMetrics fm=g.getFontMetrics(font);

g.setColor(background);

g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(foreground);

g.setFont(font);

g.drawString(text,0, fm.getAscent());

}publicDimension getPreferredSize()

{

String text=font.getFamily();

Graphics g=getGraphics();

FontMetrics fm=g.getFontMetrics(font);return newDimension(fm.stringWidth(text), fm.getHeight());

}

}

ListRenderingFrame.java

packagelistRendering;import java.awt.*;import java.util.*;import javax.swing.*;import javax.swing.event.*;/*** This frame contains a list with a set of fonts and a text area that is set to the selected font.*/

public class ListRenderingFrame extendsJFrame

{private static final int TEXT_ROWS = 8;private static final int TEXT_COLUMNS = 20;privateJTextArea text;private JListfontList;publicListRenderingFrame()

{

java.util.List fonts = new ArrayList<>();final int SIZE = 24;

fonts.add(new Font("Serif", Font.PLAIN, SIZE));

fonts.add(new Font("SansSerif", Font.PLAIN, SIZE));

fonts.add(new Font("Monospaced", Font.PLAIN, SIZE));

fonts.add(new Font("Dialog", Font.PLAIN, SIZE));

fonts.add(new Font("DialogInput", Font.PLAIN, SIZE));

fontList= new JList(fonts.toArray(newFont[]{}));

fontList.setVisibleRowCount(4);

fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

fontList.setCellRenderer(newFontCellRenderer());

JScrollPane scrollPane= newJScrollPane(fontList);

JPanel p= newJPanel();

p.add(scrollPane);

fontList.addListSelectionListener(newListSelectionListener()

{public voidvalueChanged(ListSelectionEvent evt)

{

Font font=fontList.getSelectedValue();

text.setFont(font);

}

});

Container contentPane=getContentPane();

contentPane.add(p, BorderLayout.SOUTH);

text= newJTextArea(TEXT_ROWS, TEXT_COLUMNS);

text.setText("The quick brown fox jumps over the lazy dog");

text.setFont(fonts.get(0));

text.setLineWrap(true);

text.setWrapStyleWord(true);

contentPane.add(text, BorderLayout.CENTER);

pack();

}

}

ListRenderingTest.java

packagelistRendering;import java.awt.*;import javax.swing.*;/*** This program demonstrates the use of cell renderers in a list box.

*@version1.24 2012-01-26

*@authorCay Horstmann*/

public classListRenderingTest

{public static voidmain(String[] args)

{

EventQueue.invokeLater(newRunnable()

{public voidrun()

{

JFrame frame= newListRenderingFrame();

frame.setTitle("ListRenderingTest");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

});

}

}

javax.swing.JList < E > 1.2

• Color getBackground()

返回未选定单元格的背景颜色。

• Color getSelectionBackground()

返回选定单元格的背景颜色。

• Color getForeground()

返回未选定单元格的前景颜色。

• Color getSelectionForeground()

返回选定单元格的前景颜色。

• void setCellRenderer(ListCellRenderer super E> cellRenderer)

设置用于绘制列表中单元格的绘制器。

javax.swing.ListCellRenderer 1.2

• Component getListCellRendererComponent(JList extends E> list, E item, int index, boolean isSelected, boolean hasFocus)

返回一个其paint方法用于绘制单元格内容的构件,如果列表的单元格尺寸没有固定,那么该构件还必须实现getPreferredSize。

参数: list     单元格正在被绘制的列表

item     要绘制的选项

index   存储在模型中的选项索引

inSelected  true表示指定的单元格被选定

hasFocus   true表示焦点在指定的单元格上

java swing列表_高级Swing——列表相关推荐

  1. 新手必看的ACL基本访问控制列表及高级访问控制列表

    [温馨提示]需要资料或者需要进群交流划到最底部 ACL原理 ACL是什么 为了过滤数据包,需要配置一些规则,规定什么样的数据包可以通过,什么样的数据包不能通过.这些规则就是通过访问控制列表(Acces ...

  2. java jtable刷新_使用Swing timer实现Jtable数据定时更新

    程序分三部分,主程序类SuperTable.java,框架类SuperTableFrame.java,数据模板类SuperTableModel.java. 主程序类SuperTable.java,如下 ...

  3. java 布局层次_[求助]swing问题---层次布局

    [求助]swing问题---层次布局 代码功能为:用两个按钮来控制组件的层次,一个是"往上一层",另一个是"往下一层",蓝色的代码为错误的! package m ...

  4. axure form列表_常见的列表页如何用Axure画出来

    列表页是PM画原型的时候最容易碰到的页面类型,那么如何快速画出并且展现交互呢? 我们从具体的例子开始讲解其中的技巧,和各种不同的演变场景.希望初级PM可以通过这篇文章改进下自己的画法. 列表页基本是由 ...

  5. java swing 空白_用swing创建窗体运行后怎么一片空白,什么都没有

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 我一边敲一边现学,不知道哪里错了,也是一样的空白 package homework; import javax.swing.*; import java. ...

  6. java 实际参数列表_实际参数列表和形式参数列表长度不同

    class ButtonDemo2 extends JFrame//输出结果窗口 { public static final int WIDTH=1000; public static final i ...

  7. java jtable 颜色_更改Swing JTable单元格颜色

    我试图使自己熟悉JTables,TableModels,JTableHeaders,渲染器等.我试图制作一个简单的虚拟表(出于实践目的),如下所示: -    1    2   3 A    A1  ...

  8. java微信获取素材列表_获取素材列表

    本接口可以获取当前管理组指定类型的素材列表. 请求说明 Https请求方式: POST 请求包结构体为 { "type": "image", "off ...

  9. java swing 图层_用Swing制作精美的图层叠加图

    在TWaver的各个使用手册,文档和Demo中我们可以看到,TWaver提供了Layer的概念,就是图层,这与一些制图软件也有几分相似.在实际应用中也是比较的多.比如TWaver的Demo中有TWav ...

最新文章

  1. 102. Binary Tree Level Order Traversal
  2. [恢]hdu 1412
  3. java中如何声明外键约束_java – 如何使用Hibernate注释标记外键约束...
  4. 生成两个表的笛卡尔积
  5. spark学习-72-源代码:Endpoint模型介绍(4)-Spark为何使用Netty通信框架替代Akka
  6. xampp 403 禁止访问 问题解决
  7. Android网络库的比较:OkHTTP,Retrofit和Volley [关闭]
  8. js中字符串正则表达式、正则法则pattern、RegExp、flags、exec
  9. PostgreSQL(2)常用命令(附教程)
  10. You Probably Dont Need Derived State
  11. Siebel Open UI
  12. over partition by ... order by ...用法汇总
  13. 【后端】--process information unavailable解决办法[详细版]
  14. mac 4k分辨率 字太小 27寸 hidpi_2019年两千价位你可以买到一台怎样的4K显示器?AOC U2790PQU...
  15. thread ‘<unnamed>‘ panicked at ‘assertion failed: `(left == right)`
  16. spring boot跳过maven test
  17. 论文笔记 Weakly Supervised Deep Detection Networks - CVPR 2016
  18. 区分SLA,SLI,SLO Google 云原生的三个S
  19. 使用线性神经网络实现逻辑与和逻辑异或(一)
  20. Sendmail配置以及验证成功

热门文章

  1. 0day漏洞(aspcms)漏洞实战
  2. 中重科技冲刺上交所:年营收18亿 谷峰兰母女控制75%股权
  3. C语言专升本编程题复习
  4. SequoiaDB巨杉数据库数据节点
  5. Three.js - 雾(十四)
  6. TaffyDB: Javascript数据库教程
  7. 光栅图形学-画直线经典算法
  8. 图标选择器之批量复制阿里云图标名称和图标代码
  9. Unity Audio -- (3)创建3D音效
  10. SAP STMS:如何优雅的传输请求