第17章 列表

17章 列表

  由JList类代表的Swing列表显示一个可选取对象列表,它支持三种选取模式:单选取、单间隔选取和多间隔选取。
  JList类把维护和绘制列表的工作委托给一个对象来完成。一个列表的模型维护一个对象列表,列表单元绘制器将这些对象绘制在列表单元中。
  缺省情况下,列表单元绘制器是DefaultListCellRenderrer的实例,它绘制表17-1中列出的对象。图标和字符串按原样显示,而所有其他类型对象的绘制方式是:通过显示从这些对象的toString返回的字符串来绘制这些对象。

17-1 一个简单的列表样例

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();
Object[] items = { "item one", "item two", "item three",
"item four", "item five", "item six",
"item seven", "item eight",
"item nine", "item ten" };

JList list = new JList(items);
JScrollPane sp = new JScrollPane(list);

list.setVisibleRowCount(7);

contentPane.setLayout(new FlowLayout());
contentPane.add(sp);
}
}

17.1 列表模型

 

17-2 一个带有缺省列表模型的列表

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
private JList list = new JList();

String[] items = { "item[0]", "item[1]", "item[2]",
"item[3]", "item[4]", "item[5]",
"item[6]", "item[7]",
"item[8]", "item[9]" };

public void init() {
Container contentPane = getContentPane();
JPanel controlPanel = new ControlPanel(list);

contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(new JScrollPane(list),
BorderLayout.CENTER);
populateList();
}
public void populateList() {
DefaultListModel model = new DefaultListModel();

for(int i=0; i < items.length; ++i)
model.addElement(items[i]);

list.setModel(model);
}
}
class ControlPanel extends JPanel {
JButton remove = new JButton("remove selected items");
JButton add = new JButton("add item");

public ControlPanel(final JList list) {
add(remove);
add(add);

remove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int[] selected = list.getSelectedIndices();
DefaultListModel model =
(DefaultListModel)list.getModel();

for(int i=0; i < selected.length; ++i) {
model.removeElementAt(selected[i] - i);
}
}
});
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final DefaultListModel model =
(DefaultListModel)list.getModel();

String s = JOptionPane.showInputDialog(
list,
"Enter item text:");

model.addElement(s);

SwingUtilities.invokeLater(new Runnable() {
public void run() {
list.ensureIndexIsVisible(
model.getSize()-1);
}
});
}
});
}
}

17.1.1 AbstractListModel

 

17.1.2 DefaultListModel

 

17.2 列表选取

 

17.3 列表单绘制器

 

17-3 实现一个定制列表单元绘制器

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
private String[] names = new String[] {
"baseball player", "basketball player",
"beach player", "chef",
"hockey player", "software developer",
"construction worker", "martial artist",
"soccer", "movie star"
};
private String[] pics = new String[] {
"baseball.gif", "basketball.gif",
"beach_umbrella.gif", "dining.gif",
"hockey.gif", "mad_hacker.gif",
"men_at_work.gif", "punch.gif",
"soccer.gif", "filmstrip.gif"
};

public void init() {
Container contentPane = getContentPane();
ListModel model =
new NameAndPictureListModel(names, pics);

ListCellRenderer renderer =
new NameAndPictureListCellRenderer();

JList list = new JList(model);

list.setCellRenderer(renderer);
list.setVisibleRowCount(5);

contentPane.setLayout(new FlowLayout());
contentPane.add(new JScrollPane(list));
}
}
class NameAndPictureListModel extends DefaultListModel {
public NameAndPictureListModel(String[] names,String[] pics) {
for(int i=0; i < names.length; ++i) {
addElement(new Object[] {
names[i], new ImageIcon(pics[i]) } );
}
}
public String getName(Object object) {
Object[] array = (Object[])object;
return (String)array[0];
}
public Icon getIcon(Object object) {
Object[] array = (Object[])object;
return (Icon)array[1];
}
}
class NameAndPictureListCellRenderer extends JLabel
implements ListCellRenderer {
private Border
lineBorder = BorderFactory.createLineBorder(Color.red, 2),
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);

public NameAndPictureListCellRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
NameAndPictureListModel model =
(NameAndPictureListModel)list.getModel();

setText(model.getName(value));
setIcon(model.getIcon(value));

if(isSelected) {
setForeground(list.getSelectionForeground());
setBackground(list.getSelectionBackground());
}
else {
setForeground(list.getForeground());
setBackground(list.getBackground());
}

if(cellHasFocus) setBorder(lineBorder);
else setBorder(emptyBorder);

return this;
}
}

17.3.1 JList属性

 

17.3.2 JList事件

 

17-4 检测列表选取的调整值

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();

String[] items = { "item[0]", "item[1]", "item[2]",
"item[3]", "item[4]", "item[5]",
"item[6]", "item[7]",
"item[8]", "item[9]" };

JList list = new JList(items);

contentPane.add(new JScrollPane(list),
BorderLayout.CENTER);

list.addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
String s;

if(e.getValueIsAdjusting()) {
s = "adjusting selection ...";
}
else {
s = "selection from " + e.getFirstIndex() +
" to " + e.getLastIndex();
}
showStatus(s);
}
});
}
}

17-5 处理列表选取事件

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
private ControlPanel controlPanel;

public void init() {
Container contentPane = getContentPane();
JPanel listPanel = new JPanel();

String[] items = { "item[0]", "item[1]", "item[2]",
"item[3]", "item[4]", "item[5]",
"item[6]", "item[7]",
"item[8]", "item[9]" };

JList list = new JList(items);

list.setPrototypeCellValue("MMMMMMM");

controlPanel = new ControlPanel(list);
controlPanel.update();

listPanel.setBorder(BorderFactory.createEtchedBorder());
listPanel.add(new JScrollPane(list));

contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(listPanel, BorderLayout.CENTER);

list.addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
controlPanel.update();
}
});
}
}
class ControlPanel extends JPanel {
private JComboBox mode = new JComboBox();
private JButton clear = new JButton("clear selection");

private String single = "SINGLE_SELECTION",
singleInterval = "SINGLE_INTERVAL_SELECTION",
multipleInterval = "MULTIPLE_INTERVAL_SELECTION";

private JLabel leadLabel = new JLabel(),
anchorLabel = new JLabel(),
minLabel = new JLabel(),
maxLabel = new JLabel(),
selIndicesLabel = new JLabel();

private JList list;

public ControlPanel(JList l) {
JPanel top = new JPanel(),
mid = new JPanel(),
bottom = new JPanel();

this.list = l;

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorder(BorderFactory.createEtchedBorder());

top.add(mode);
top.add(clear);

mid.add(new JLabel("Lead:")); mid.add(leadLabel);
mid.add(new JLabel("Anchor:")); mid.add(anchorLabel);
mid.add(new JLabel("Minimum:")); mid.add(minLabel);
mid.add(new JLabel("Maximum:")); mid.add(maxLabel);

add(top);
add(mid);
add(bottom);

mode.addItem(single);
mode.addItem(singleInterval);
mode.addItem(multipleInterval);
initializeSelectionMode();

bottom.add(new JLabel("Selected Indices:"));
bottom.add(selIndicesLabel);

mode.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED)
setSelectionMode((String)e.getItem());
}
});
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
list.clearSelection();
}
});
}
public void update() {
int lead = list.getLeadSelectionIndex(),
min = list.getMinSelectionIndex(),
max = list.getMaxSelectionIndex(),
anchor = list.getAnchorSelectionIndex();

leadLabel.setText(Integer.toString(lead) + " / ");
anchorLabel.setText(Integer.toString(anchor) + " / ");
minLabel.setText(Integer.toString(min) + " / ");
maxLabel.setText(Integer.toString(max) + " / ");

int[] selected = list.getSelectedIndices();
String s = new String();

for(int i = 0; i < selected.length; ++i) {
s += Integer.toString(selected[i]);

if(i < selected.length-1)
s += ",";
}
selIndicesLabel.setText(s);
validate();
}
private void initializeSelectionMode() {
int m = list.getSelectionMode();

switch(m) {
case ListSelectionModel.SINGLE_SELECTION:
mode.setSelectedItem(single);
break;
case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
mode.setSelectedItem(singleInterval);
break;
case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:
mode.setSelectedItem(multipleInterval);
break;
}
}
private void setSelectionMode(String s) {
if(s.equals("SINGLE_SELECTION")) {
list.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
}
else if(s.equals("SINGLE_INTERVAL_SELECTION")) {
list.setSelectionMode(
ListSelectionModel.SINGLE_INTERVAL_SELECTION);
}
else if(s.equals("MULTIPLE_INTERVAL_SELECTION")) {
list.setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
}
}

17-6 处理列表数据事件

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
private JList list = new JList();

private String[] items = {
"item one", "item two", "item three",
"item four", "item five", "item six",
"item seven", "item eight",
"item nine", "item ten"
};

public void init() {
Container contentPane = getContentPane();

JPanel controlPanel = new ControlPanel(this, list);

contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(new JScrollPane(list),
BorderLayout.CENTER);
populateList();
}
public void populateList() {
final DefaultListModel model = new DefaultListModel();

for(int i=0; i < items.length; ++i)
model.addElement(items[i]);

list.setModel(model);

if(list.isShowing())
list.revalidate();

model.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent e) {
showStatus("contents changed");
}
public void intervalRemoved(ListDataEvent e) {
Object[] message = new Object[] {
"Removed item at index " + e.getIndex0(),
" ",
"There are now " + model.getSize() + " items"
};
JOptionPane.showMessageDialog(Test.this,
message,
"Items Removed", // title
JOptionPane.INFORMATION_MESSAGE); // type
}
public void intervalAdded(ListDataEvent e) {
showStatus("interval added");
}
});
}
}
class ControlPanel extends JPanel {
JButton remove = new JButton("remove selected items");
JButton repopulate = new JButton("repopulate");

public ControlPanel(final Test applet, final JList list) {
add(remove);
add(repopulate);

remove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int[] selected = list.getSelectedIndices();
DefaultListModel model =
(DefaultListModel)list.getModel();

for(int i=0; i < selected.length; ++i) {
model.removeElementAt(selected[i] - i);
}
}
});
repopulate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
applet.populateList();
}
});
}
}

 

 

17-7 处理鼠标双击和三击

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();

String[] items = { "item one", "item two", "item three",
"item four", "item five", "item six",
"item seven", "item eight",
"item nine", "item ten" };

JList list = new JList(items);

contentPane.setLayout(new FlowLayout());
contentPane.add(new JScrollPane(list));

list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
JList theList = (JList)e.getSource();
ListModel model = theList.getModel();

int index = theList.locationToIndex(e.getPoint());
String itemString =
(String)model.getElementAt(index);

String s = new String(" for " +
model.getElementAt(index));

switch(e.getClickCount()) {
case 1:
showStatus("Single Click" + s);
break;
case 2:
showStatus("Double Click" + s);
break;
case 3:
showStatus("Triple Click" + s);
break;
}
}
});
}
}

17.3.3 JList类总结

 

17.3.4 AWT兼容

 

17.4 本章回顾

上一篇:第10章 菜单和工具条(二)


下一篇:第18章 组合框