第18章 组合框

简介: 第18章 组合框  由JComboBox类实现的组合框是由一个可编辑区(缺省时是一个文本区)和一个可选取项的下拉列表组成的。因此,我们采取把它与JList比较的方式来介绍JComboBox.18.1 JComboBox与JList的比较  JList和ComboBox很相似,因为这两个组件都显示一个项列表。

18章 组合框

  由JComboBox类实现的组合框是由一个可编辑区(缺省时是一个文本区)和一个可选取项的下拉列表组成的。因此,我们采取把它与JList比较的方式来介绍JComboBox.

18.1 JComboBoxJList的比较

  JListComboBox很相似,因为这两个组件都显示一个项列表。因此,它们都有扩展ListModel接口的模型。而且,这两个组件都有绘制器,这些绘制器通过实现ListCellBenderer接口来绘制列表单元。
  但是,列表和组合框在施工方面还是有差别的。列表单是不可编辑的,但是组合框可以配备一个编辑器。JComboBox组件把编辑工作交给实现ComboBoxEdit接口的一个对象来处理。
  列表支持三个选取模式,并把选取工作实现ListSelectionModel接口的一个对象来处理。组合框在一个时刻只有一个可选取的项,而且选取工作由组合框模型来处理。另一方面,组合框支持键选取,即在某项上按下一下键就可以选取这个项,但列表不能这样做。

18.2 JComboBox组件

 

18-1 可编辑组合框和不可编辑组合框

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

public class Test extends JApplet {
private JCheckBox checkBox = new JCheckBox("Editable");
private JComboBox comboBox = new JComboBox();

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

comboBox.addItem("Top");
comboBox.addItem("Center");
comboBox.addItem("Bottom");

checkBox.setSelected(comboBox.isEditable());

contentPane.setLayout(new FlowLayout());
contentPane.add(checkBox);
contentPane.add(comboBox);

checkBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
comboBox.setEditable(checkBox.isSelected());
}
});
comboBox.getEditor().addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("here" +
comboBox.getSelectedItem());
}
});
}
public static void main(String args[]) {
final JFrame f = new JFrame();
JApplet applet = new Test();

applet.init();

f.setContentPane(applet.getContentPane());
f.setBounds(100,100,308,199);
f.setTitle("An Application");
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

18.3 组合框模型

 

18.3.1 JComboBoxModel

 

18.3.2 MutableComboBoxModel

 

18.3.3 DefaultComboBoxModel

 

18.4 组合框单绘制器

 

18-2 一个定制的列表单元绘制器

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

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();
JComboBox combo = new JComboBox(new Object[] {
new Object[] { Color.gray, "gray" },
new Object[] { Color.orange, "orange" },
new Object[] { Color.red, "red" },
new Object[] { Color.blue, "blue" },
new Object[] { Color.yellow, "yellow" },
new Object[] { Color.magenta, "magenta" },
new Object[] { Color.black, "black" },
new Object[] { Color.green, "green" },
new Object[] { Color.lightGray, "lightGray"} });

combo.setRenderer(new ColorRenderer());

contentPane.setLayout(new FlowLayout());
contentPane.add(combo);
}
}
class ColorRenderer extends JLabel implements ListCellRenderer {
private static ColorIcon icon = new ColorIcon();

private Border
redBorder = BorderFactory.createLineBorder(Color.red,2),
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Object[] array = (Object[])value;

icon.setColor((Color)array[0]);
setIcon(icon);
setText((String)array[1]);

if(isSelected) setBorder(redBorder);
else setBorder(emptyBorder);

return this;
}
}
class ColorIcon implements Icon {
private Color color;
private int w, h;

public ColorIcon() {
this(Color.gray, 50, 15);
}
public ColorIcon(Color color, int w, int h) {
this.color = color;
this.w = w;
this.h = h;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawRect(x, y, w-1, h-1);
g.setColor(color);
g.fillRect(x+1, y+1, w-2, h-2);
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getIconWidth() {
return w;
}
public int getIconHeight() {
return h;
}
}

18.5 组合框键选取管理器

 

18.5.1 使用缺省键选取管理

 

18-3 使用缺省的键选取管理器

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

public class Test extends JApplet {
private JComboBox colorCombo = new JComboBox(new Object[] {
new Item(new Object[] { Color.gray, "gray" }),
new Item(new Object[] { Color.orange, "orange" }),
new Item(new Object[] { Color.red, "red" }),
new Item(new Object[] { Color.blue, "blue" }),
new Item(new Object[] { Color.yellow, "yellow" }),
new Item(new Object[] { Color.magenta, "magenta" }),
new Item(new Object[] { Color.black, "black" }),
new Item(new Object[] { Color.green, "green" }),
new Item(new Object[] { Color.lightGray, "lightGray"})
});

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

colorCombo.setRenderer(new ColorRenderer());

contentPane.setLayout(new FlowLayout());
contentPane.add(colorCombo);

colorCombo.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Item item = (Item)colorCombo.getSelectedItem();
String first = item.toString().substring(0,1);

showStatus("'" + first + "'" + " is for " + item);
}
});
}
}
class Item {
private Color color;
private String string;

public Item(Object[] array) {
color = (Color)array[0];
string = (String)array[1];
}
public Color getColor() { return color; }
public String toString() { return string; }
}
class ColorRenderer extends JLabel implements ListCellRenderer {
private static ColorIcon icon = new ColorIcon();

private Border
redBorder = BorderFactory.createLineBorder(Color.red,2),
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Item item = (Item)value;

icon.setColor(item.getColor());

setIcon(icon);
setText(item.toString());

if(isSelected) setBorder(redBorder);
else setBorder(emptyBorder);

return this;
}
}
class ColorIcon implements Icon {
private Color color;
private int w, h;

public ColorIcon() {
this(Color.gray, 50, 15);
}
public ColorIcon(Color color, int w, int h) {
this.color = color;
this.w = w;
this.h = h;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawRect(x, y, w-1, h-1);
g.setColor(color);
g.fillRect(x+1, y+1, w-2, h-2);
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getIconWidth() {
return w;
}
public int getIconHeight() {
return h;
}
}

18.5.2 定制键选取管理器

 

18-4 实现一个定制的键选取管理器

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

public class Test extends JApplet {
private ColorKeySelectionManager ksm =
new ColorKeySelectionManager();

private JComboBox colorCombo = new JComboBox(new Object[] {
new Item(new Object[] { Color.gray, "gray" }),
new Item(new Object[] { Color.orange, "orange" }),
new Item(new Object[] { Color.red, "red" }),
new Item(new Object[] { Color.blue, "blue" }),
new Item(new Object[] { Color.yellow, "yellow" }),
new Item(new Object[] { Color.magenta, "magenta" }),
new Item(new Object[] { Color.black, "black" }),
new Item(new Object[] { Color.green, "green" }),
new Item(new Object[] { Color.lightGray, "lightGray"})
});
public void init() {
final Container contentPane = getContentPane();

colorCombo.setRenderer(new ColorRenderer());
colorCombo.setKeySelectionManager(ksm);

contentPane.setLayout(new FlowLayout());
contentPane.add(colorCombo);

colorCombo.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Item item = (Item)colorCombo.getSelectedItem();
String itemString = item.toString();

showStatus("'" + ksm.getSearchString() +
"'" + " is for " + itemString);
}
});
}
}
class Item {
private Color color;
private String string;

public Item(Object[] array) {
color = (Color)array[0];
string = (String)array[1];
}
public Color getColor() { return color; }
public String toString() { return string; }
}
class ColorRenderer extends JLabel implements ListCellRenderer {
private static ColorIcon icon = new ColorIcon();

private Border
redBorder = BorderFactory.createLineBorder(Color.red,2),
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Item item = (Item)value;

icon.setColor(item.getColor());
setIcon(icon);
setText(item.toString());

if(isSelected) setBorder(redBorder);
else setBorder(emptyBorder);

return this;
}
}
class ColorIcon implements Icon {
private Color color;
private int w, h;

public ColorIcon() {
this(Color.gray, 50, 15);
}
public ColorIcon(Color color, int w, int h) {
this.color = color;
this.w = w;
this.h = h;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawRect(x, y, w-1, h-1);
g.setColor(color);
g.fillRect(x+1, y+1, w-2, h-2);
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getIconWidth() {
return w;
}
public int getIconHeight() {
return h;
}
}
class ColorKeySelectionManager
implements JComboBox.KeySelectionManager {
private String searchString = new String();
private long lastTime;

public int selectionForKey(char key,ComboBoxModel model) {
updateSearchString(model, key);

int start = getIndexAfter(model,getSelectedString(model));
int selection = search(model, start);

if(selection == -1 && start != 0)
selection = search(model, 0);

return selection;
}
public String getSearchString() {
return searchString;
}
private int search(ComboBoxModel model, int start) {
for(int i=start; i < model.getSize(); ++i) {
String s = getString(model, i);
int searchLength = searchString.length();

if(s.regionMatches(0,searchString,0,searchLength))
return i;
}
return -1;
}
private int getIndexAfter(ComboBoxModel model, String find) {
int size = model.getSize();

if(find != null) {
for(int i=0; i < size; ++i) {
String s = getString(model, i);

if(s.compareToIgnoreCase(find) == 0) {
return (i == size-1) ? 0 : i + 1;
}
}
}
return 0;
}
private String getString(ComboBoxModel model, int index) {
Item item = (Item)model.getElementAt(index);
return item.toString();
}
private String getSelectedString(ComboBoxModel model) {
Item item = (Item)model.getSelectedItem();
return item.toString();
}
private void updateSearchString(
ComboBoxModel model, char key) {
long time = System.currentTimeMillis();

if(time - lastTime < 500) searchString += key;
else searchString = "" + key;

lastTime = time;
}
}

18.5.3 程序式的键选取

 

18-5 使用SwingUtilities.invokeLater()

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

public class Test extends JApplet {
private JComboBox charsCombo = new JComboBox(new Object[] {
new Character('g'), new Character('o'),
new Character('r'), new Character('b'),
new Character('y'), new Character('m'),
new Character('g'), new Character('l'),
});
private JComboBox colorCombo = new JComboBox(new Object[] {
new Item(new Object[] { Color.gray, "gray" }),
new Item(new Object[] { Color.orange, "orange" }),
new Item(new Object[] { Color.red, "red" }),
new Item(new Object[] { Color.blue, "blue" }),
new Item(new Object[] { Color.yellow, "yellow" }),
new Item(new Object[] { Color.magenta, "magenta" }),
new Item(new Object[] { Color.black, "black" }),
new Item(new Object[] { Color.green, "green" }),
new Item(new Object[] { Color.lightGray, "lightGray"})
});

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

colorCombo.setRenderer(new ColorRenderer());

colorCombo.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Item item = (Item)colorCombo.getSelectedItem();
Character first = new Character(
item.toString().charAt(0));

showStatus("'" + first.toString() + "'" +
" is for " + item);
}
});
charsCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final Character c = (Character)
charsCombo.getSelectedItem();

colorCombo.selectWithKeyChar(c.charValue());

SwingUtilities.invokeLater(new Runnable() {
public void run() {
Item item = (Item)
colorCombo.getSelectedItem();

JOptionPane.showMessageDialog(contentPane,
"'" + c.toString() + "'" +
" is for " + item.toString());
}
});
}
});
contentPane.setLayout(
new FlowLayout(FlowLayout.CENTER, 10, 35));

contentPane.add(new JLabel("Select a Character:"));
contentPane.add(charsCombo);
contentPane.add(colorCombo);
}
}
class Item {
private Color color;
private String string;

public Item(Object[] array) {
color = (Color)array[0];
string = (String)array[1];
}
public Color getColor() { return color; }
public String toString() { return string; }
}

class ColorRenderer extends JLabel implements ListCellRenderer {
private static ColorIcon icon = new ColorIcon();

private Border
redBorder = BorderFactory.createLineBorder(Color.red,2),
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Item item = (Item)value;

icon.setColor(item.getColor());

setIcon(icon);
setText(item.toString());

if(isSelected) setBorder(redBorder);
else setBorder(emptyBorder);

return this;
}
}
class ColorIcon implements Icon {
private Color color;
private int w, h;

public ColorIcon() {
this(Color.gray, 50, 15);
}
public ColorIcon(Color color, int w, int h) {
this.color = color;
this.w = w;
this.h = h;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawRect(x, y, w-1, h-1);
g.setColor(color);
g.fillRect(x+1, y+1, w-2, h-2);
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getIconWidth() {
return w;
}
public int getIconHeight() {
return h;
}
}

18.6 组合框编辑器

 

18-6 实现一个定制的组合框编辑器

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

public class Test extends JApplet {
private JComboBox comboBox =
new JComboBox(new Object[] {
new Item(new Object[] {Color.gray, "gray"}),
new Item(new Object[] {Color.orange, "orange"}),
new Item(new Object[] {Color.red, "red"}),
new Item(new Object[] {Color.blue, "blue"}),
new Item(new Object[] {Color.yellow, "yellow"}),
new Item(new Object[] {Color.magenta, "magenta"}),
new Item(new Object[] {Color.black, "black"}),
new Item(new Object[] {Color.green, "green"}),
new Item(new Object[] {Color.lightGray, "lightGray"}),
new Item(new Object[] {Color.white, "white"}),
});

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

comboBox.setRenderer(new ColorRendererer());
comboBox.setEditor(new ColorComboBoxEditor());
comboBox.setEditable(true);

contentPane.setLayout(new FlowLayout());
contentPane.add(comboBox);
}
}
class Item {
private Color color;
private String string;

public Item(Object[] array) {
color = (Color)array[0];
string = (String)array[1];
}
public Color getColor() { return color; }
public String toString() { return string; }
}
class ColorComboBoxEditor extends AbstractComboBoxEditor {
ColorIcon editorIcon = new ColorIcon();
JLabel editorLabel = new JLabel(editorIcon);

Item item;

JColorChooser colorChooser = new JColorChooser();
ActionListener okListener = new OKListener();
Dialog dialog = JColorChooser.createDialog(
null, // parentComponent
"Choose A Color",// title
true, // modal
colorChooser,
okListener,
null); // cancel listener

public ColorComboBoxEditor() {
editorLabel.setBorder(BorderFactory.createEtchedBorder());

editorLabel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
dialog.setVisible(true);
}
});
}
class OKListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
item =
new Item(new Object[] {
colorChooser.getColor(), null});

fireActionPerformed(e);
}
}
public Component getEditorComponent() {
return editorLabel;
}
public Object getItem() {
return item;
}
public void setItem(Object itemToSet) {
item = (Item)itemToSet;

// cannot set the selected item in an editor's
// setItem method, or an infinite loop results

editorIcon.setColor(item.getColor());
editorLabel.setText(item.toString());
}
public void selectAll() {
// from ComboBoxModel interface: nothing to select
}
}
abstract class AbstractComboBoxEditor implements ComboBoxEditor {
EventListenerList listenerList = new EventListenerList();

public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed(ActionEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();

// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
((ActionListener)
listeners[i+1]).actionPerformed(e);
}
}
}
}
class ColorRendererer extends JLabel implements ListCellRenderer {
private ColorIcon icon = new ColorIcon();

public ColorRendererer() {
setOpaque(true);
setIcon(icon);
}
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Item item = (Item)value;

icon.setColor(item.getColor());
setText(item.toString());

if(isSelected) {
setForeground(list.getSelectionForeground());
setBackground(list.getSelectionBackground());
}
else {
setForeground(list.getForeground());
setBackground(list.getBackground());
}
return this;
}
}
class ColorIcon implements Icon {
private Color color;
private int w, h;

public ColorIcon() {
this(Color.gray, 50, 15);
}
public ColorIcon(Color color, int w, int h) {
this.color = color;
this.w = w;
this.h = h;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawRect(x, y, w-1, h-1);
g.setColor(color);
g.fillRect(x+1, y+1, w-2, h-2);
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getIconWidth() {
return w;
}
public int getIconHeight() {
return h;
}
}

18.6.1 JComboBox属性

 

 

18.6.2 JComboBox事件

 

18-7 处理选取事件

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

public class Test extends JApplet {
private JComboBox comboBox = new JComboBox();

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

comboBox.addItem("Top");
comboBox.addItem("Center");
comboBox.addItem("Bottom");

contentPane.setLayout(new FlowLayout());
contentPane.add(comboBox);

comboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent event) {
int state = event.getStateChange();
String item = (String)event.getItem(), s;

if(event.getStateChange() == ItemEvent.SELECTED)
s = " selected";
else
s = " deselected";

JOptionPane.showMessageDialog(
comboBox, // parent component
item + s, // message
"JComboBox Selection", // title
JOptionPane.INFORMATION_MESSAGE); // type
}
});
}
}

18-8 处理编辑事件

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

public class Test extends JApplet {
private JComboBox comboBox = new JComboBox();
private ComboBoxEditor editor = comboBox.getEditor();

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

comboBox.setEditable(true);

comboBox.addItem("Top");
comboBox.addItem("Center");
comboBox.addItem("Bottom");

contentPane.setLayout(new FlowLayout());
contentPane.add(comboBox);

editor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = (String)editor.getItem();
showStatus("Item Edited: " + s);
}
});
}
}

 

18.6.3 JComboBox类总结

 

18-9 手工显示一个组件框的弹出式菜单

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

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();
JButton button = new JButton("show popup");
final JComboBox combo = new JComboBox();

combo.addItem("first item");
combo.addItem("second item");
combo.addItem("third item");
combo.addItem("fourth item");
combo.addItem("fifth item");

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
combo.showPopup();
}
});
contentPane.setLayout(new FlowLayout());
contentPane.add(button);
contentPane.add(combo);
}
}

18.6.4 AWT兼容

 

18.7 本章回顾

 

目录
相关文章
|
6月前
|
索引
[Qt5&控件] 下拉框ComBoBox和层叠窗口StackedWidget控件组合使用
[Qt5&控件] 下拉框ComBoBox和层叠窗口StackedWidget控件组合使用
157 0
16 MFC - 组合框(下拉框) CComboBox
16 MFC - 组合框(下拉框) CComboBox
45 0
|
XML Java API
按钮和复选框控件
按钮和复选框控件
88 0