天天看點

第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 一個帶有預設清單模型的清單

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]" };

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() {

final DefaultListModel model =

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 javax.swing.border.*;

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"

ListModel model =

new NameAndPictureListModel(names, pics);

ListCellRenderer renderer =

new NameAndPictureListCellRenderer();

JList list = new JList(model);

list.setCellRenderer(renderer);

list.setVisibleRowCount(5);

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) {

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 檢測清單選取的調整值

list.addListSelectionListener(

new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

String s;

if(e.getValueIsAdjusting()) {

s = "adjusting selection ...";

s = "selection from " + e.getFirstIndex() +

" to " + e.getLastIndex();

showStatus(s);

例17-5 處理清單選取事件

private ControlPanel controlPanel;

JPanel listPanel = new JPanel();

list.setPrototypeCellValue("MMMMMMM");

controlPanel = new ControlPanel(list);

controlPanel.update();

listPanel.setBorder(BorderFactory.createEtchedBorder());

listPanel.add(new JScrollPane(list));

contentPane.add(listPanel, BorderLayout.CENTER);

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() {

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) + " / ");

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);

case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:

mode.setSelectedItem(multipleInterval);

private void setSelectionMode(String s) {

if(s.equals("SINGLE_SELECTION")) {

list.setSelectionMode(

ListSelectionModel.SINGLE_SELECTION);

else if(s.equals("SINGLE_INTERVAL_SELECTION")) {

ListSelectionModel.SINGLE_INTERVAL_SELECTION);

else if(s.equals("MULTIPLE_INTERVAL_SELECTION")) {

ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

例17-6 處理清單資料事件

private String[] items = {

"item one", "item two", "item three",

"item nine", "item ten"

JPanel controlPanel = new ControlPanel(this, list);

final DefaultListModel model = new DefaultListModel();

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");

JButton repopulate = new JButton("repopulate");

public ControlPanel(final Test applet, final JList list) {

add(repopulate);

repopulate.addActionListener(new ActionListener() {

applet.populateList();

例17-7 處理滑鼠輕按兩下和三擊

String[] items = { "item one", "item two", "item three",

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);

case 2:

showStatus("Double Click" + s);

case 3:

showStatus("Triple Click" + s);

17.3.3 JList類總結

17.3.4 AWT相容

17.4 本章回顧

繼續閱讀