天天看點

第16章 選取器

第16章 選取器

  本章介紹兩個Swing選取器元件,它們是:JFileChooser和JColorChooser,它們分别用于選取檔案和顔色。

16.1 JFileChooser

  檔案選取器(與選項窗格一樣,參見14.3節“JOptionPane”)是放置在對話框中的輕量元件。一旦建立了一個JFileChooser執行個體,就可以把這個執行個體添加到一個對話框中。而且,JFileChooser類還提供了一些方法,這些方法把已存在的檔案添加到一個模态對話框中。并且顯示這個對話框。這些方法傳回一個integer值,指出是激活了選取器的準許按鈕還是清除了這個對話框。

  檔案選取器支援三種顯示模式:隻顯示檔案、隻顯示目錄和顯示檔案及目錄。另外,檔案選取器還支援單檔案選取和多檔案選取(Swing1.1FCS不完全支援多檔案選取。)

  可以用許多不同的方法來定制檔案選取器,如圖16-1所示。圖16-1中的上圖顯示調用JFileChooser.showSaveDialog()後顯示的标準對話框。圖16-1

例子 16-1 一個簡單的檔案選取器例子

import java.awt.*;

import java.awt.event.*;

import java.io.File;

import javax.swing.*;

import javax.swing.filechooser.*;

import java.beans.*;

public class Test extends JFrame {

JFileChooser chooser = new JFileChooser();

JButton button = new JButton("show file chooser ...");

public Test() {

super("Simple File Chooser Application");

Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());

contentPane.add(button);

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int state = chooser.showOpenDialog(null);

File file = chooser.getSelectedFile();

if(file != null &&

state == JFileChooser.APPROVE_OPTION) {

JOptionPane.showMessageDialog(

null, file.getPath());

}

else if(state == JFileChooser.CANCEL_OPTION) {

null, "Canceled");

else if(state == JFileChooser.ERROR_OPTION) {

null, "Error!");

});

public static void main(String args[]) {

JFrame f = new Test();

f.setBounds(300,300,350,100);

f.setVisible(true);

f.setDefaultCloseOperation(

WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {

public void windowClosed(WindowEvent e) {

System.exit(0);

16.1.1 檔案選取器類型

例子 16-2 預設的檔案選取器類型

JComboBox comboBox = new JComboBox();

super("Standard File Chooser Types");

contentPane.add(comboBox);

comboBox.addItem("OPEN_DIALOG");

comboBox.addItem("SAVE_DIALOG");

comboBox.addItem("custom dialog");

String message = "CANCELED";

int state = showChooser(

(String)comboBox.getSelectedItem());

message = chooser.getApproveButtonText() +

" " + file.getPath();

JOptionPane.showMessageDialog(null, message);

private int showChooser(String s) {

int state;

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

state = chooser.showOpenDialog(null);

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

state = chooser.showSaveDialog(null);

else { // custom dialog

String string = JOptionPane.showInputDialog(

null,

"Button/Title String:");

chooser.setApproveButtonMnemonic(string.charAt(1));

state = chooser.showDialog(Test.this, string);

return state;

16.1.2 可通路元件

例子 16-3 一個圖像預覽器可通路元件

import java.io.*;

ImagePreviewer previewer = new ImagePreviewer();

super("Accessory Components");

JButton button = new JButton("Select A File");

setAccessoryComponent();

chooser.showOpenDialog(null);

private void setAccessoryComponent() {

JPanel previewPanel = new JPanel();

previewPanel.setLayout(new BorderLayout());

previewPanel.add(new JLabel("Image Previewer",

SwingConstants.CENTER),

BorderLayout.NORTH);

previewPanel.add(previewer, BorderLayout.CENTER);

previewer.setPreferredSize(new Dimension(200,0));

previewer.setBorder(BorderFactory.createEtchedBorder());

chooser.setAccessory(previewPanel);

new ImagePreviewerAccessoryAdapter(chooser, previewer);

public static void main(String a[]) {

f.setBounds(300, 300, 300, 75);

class ImagePreviewerAccessoryAdapter extends Object {

public ImagePreviewerAccessoryAdapter(

JFileChooser chooser,

final ImagePreviewer previewer) {

chooser.addPropertyChangeListener(

new PropertyChangeListener() {

public void propertyChange(PropertyChangeEvent e) {

if(e.getPropertyName().equals(

JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {

previewer.update((File)e.getNewValue());

class ImagePreviewer extends JComponent {

private ImageIcon icon;

public void update(File file) {

Dimension size = getSize();

Insets insets = getInsets();

icon = new ImageIcon(file.getPath());

icon.setImage(icon.getImage().getScaledInstance(

size.width - insets.left - insets.right,

size.height - insets.top - insets.bottom,

Image.SCALE_SMOOTH));

if(isShowing()) {

repaint();

public void paintComponent(Graphics g) {

super.paintComponent(g);

if(icon != null)

icon.paintIcon(this, g, insets.left, insets.top);

16.1.3 過濾檔案類型

例子 16-4 一個文本檔案過濾器和預覽器

import java.util.*;

import java.net.*;

TextPreviewer previewer = new TextPreviewer();

JPanel previewPanel = new PreviewPanel();

class PreviewPanel extends JPanel {

public PreviewPanel() {

JLabel label = new JLabel("Text Previewer",

SwingConstants.CENTER);

setPreferredSize(new Dimension(250,0));

setBorder(BorderFactory.createEtchedBorder());

setLayout(new BorderLayout());

label.setBorder(BorderFactory.createEtchedBorder());

add(label, BorderLayout.NORTH);

add(previewer, BorderLayout.CENTER);

JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))

class TextPreviewer extends JComponent {

private JTextArea textArea = new JTextArea();

public TextPreviewer() {

add(new JScrollPane(textArea), BorderLayout.CENTER);

textArea.setText(contentsOfFile(file));

textArea.revalidate();

static String contentsOfFile(File file) {

String s = new String();

char[] buff = new char[50000];

InputStream is;

InputStreamReader reader;

URL url;

try {

reader = new FileReader(file);

int nch;

while ((

nch = reader.read(buff, 0, buff.length)) != -1) {

s = s + new String(buff, 0, nch);

catch (java.io.IOException ex) {

s = "Could not load file";

return s;

例子 16-5 多種檔案過濾器

import java.net.URL;

PreviewPanel previewPanel = new PreviewPanel();

setPreferredSize(new Dimension(350,0));

super("Filtering Files");

String s = "CANCELED";

if(state == JFileChooser.APPROVE_OPTION) {

s = "File Selected: " +

chooser.getSelectedFile().getPath();

JOptionPane.showMessageDialog(null, s);

chooser.addChoosableFileFilter(new TextFilter());

chooser.addChoosableFileFilter(new JavaCodeFilter());

previewer.configure((File)e.getNewValue());

abstract class SuffixAwareFilter

extends javax.swing.filechooser.FileFilter {

public String getSuffix(File f) {

String s = f.getPath(), suffix = null;

int i = s.lastIndexOf('.');

if(i > 0 && i < s.length() - 1)

suffix = s.substring(i+1).toLowerCase();

return suffix;

public boolean accept(File f) {

return f.isDirectory();

class ImageFilter extends SuffixAwareFilter {

boolean accept = super.accept(f);

if( ! accept) {

String suffix = getSuffix(f);

if(suffix != null)

accept = super.accept(f) || suffix.equals("jpg")

|| suffix.equals("gif");

return accept;

public String getDescription() {

return "Java Source Code Files(*.java)";

class JavaCodeFilter extends SuffixAwareFilter {

accept = super.accept(f) || suffix.equals("java");

class TextFilter extends SuffixAwareFilter {

return super.accept(f) || suffix.equals("txt");

return false;

return "Text Files(*.txt)";

private JScrollPane scrollPane = new JScrollPane(textArea);

textArea.setEditable(false);

add(scrollPane, BorderLayout.CENTER);

public void configure(File file) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

JViewport vp = scrollPane.getViewport();

vp.setViewPosition(new Point(0,0));

16.1.4 檔案視圖

例子 16-6 一個定制的檔案視圖

import javax.swing.filechooser.FileView;

super("Custom File View Example");

chooser.setFileView(new CustomFileView());

int state = chooser.showSaveDialog(null);

if(state == JFileChooser.APPROVE_OPTION)

s = "File: " + file.getPath();

class CustomFileView extends FileView {

private Icon fileIcon = new ImageIcon("file.gif"),

directoryIcon = new ImageIcon("folder.gif"),

imageIcon = new ImageIcon("photo.jpg");

public String getName(File f) { return null; }

public String getDescription(File f) { return null; }

public String getTypeDescription(File f) { return null; }

public Icon getIcon(File f) {

Icon icon = null;

if(isImage(f)) icon = imageIcon;

else if(f.isDirectory()) icon = directoryIcon;

else icon = fileIcon;

return icon;

public Boolean isTraversable(File f) {

Boolean b = null;

if(f.getPath().equals("D://file.txt")) {

b = new Boolean(false);

else if(f.getPath().equals("D://books")) {

return b == null ? new Boolean(true) : b;

private boolean isImage(File f) {

boolean isImage = false;

if(suffix != null) {

isImage = suffix.equals("gif") ||

suffix.equals("bmp") ||

suffix.equals("jpg");

return isImage;

private String getSuffix(File file) {

String filestr = file.getPath(), suffix = null;

int i = filestr.lastIndexOf('.');

if(i > 0 && i < filestr.length()) {

suffix = filestr.substring(i+1).toLowerCase();

16.1.5 多檔案選取

例子 16-7 檔案選取器的多檔案選取

chooser.setMultiSelectionEnabled(true);

File[] files = chooser.getSelectedFiles();

String[] filenames = getFilenames(files);

if(filenames != null &&

JOptionPane.showMessageDialog(null,filenames);

private String[] getFilenames(File[] files) {

String[] filenames = null;

int numFiles = files.length;

System.out.println(numFiles);

if(files.length > 0) {

filenames = new String[numFiles];

for(int i=0; i < numFiles; ++i) {

filenames[i] = files[i].getPath();

System.out.println(filenames[i]);

return filenames;

16.1.6 JFileChooser屬性

16.1.7 JFileChooser事件

例子 16-8 JFileChooser動作事件

JDialog dialog;

String title = chooser.getDialogTitle();

if(title == null)

chooser.getUI().getDialogTitle(chooser);

dialog = new JDialog((Frame)null, title, false);

Container dialogContentPane =

dialog.getContentPane();

dialogContentPane.setLayout(new BorderLayout());

dialogContentPane.add(chooser,

BorderLayout.CENTER);

dialog.setTitle("Non-Modal File Chooser");

dialog.pack();

dialog.setLocationRelativeTo(Test.this);

dialog.setVisible(true);

chooser.addActionListener(new ActionListener() {

String state = (String)e.getActionCommand();

if(state.equals(JFileChooser.APPROVE_SELECTION)) {

else if(

state.equals(JFileChooser.CANCEL_SELECTION)) {

// JFileChooser action listeners are notified

// when one either the approve button or

// cancel button is activated

dialog.setVisible(false);

16.1.8 JFileChooser類總結

16.1.9 AWT相容

16.2 JColorChooser

例16-9 在一個小應用程式中顯示的顔色選取器

import javax.swing.colorchooser.*;

import javax.swing.event.*;

public class Test extends JApplet {

JColorChooser chooser = new JColorChooser();

ColorSelectionModel model = chooser.getSelectionModel();

public void init() {

getContentPane().add(chooser, BorderLayout.CENTER);

model.addChangeListener(new ChangeListener() {

public void stateChanged(ChangeEvent e) {

showStatus("Color: " + chooser.getColor());

16.2.1 在對話框中顯示顔色選取器

例16-10 在對話框中顯示的顔色選取器

getContentPane().add(new Palette(), BorderLayout.CENTER);

class Palette extends JPanel {

private Color[] defaultColors = new Color[] {

Color.blue, Color.red, Color.yellow, Color.green,

Color.magenta, Color.darkGray, Color.white, Color.orange,

Color.pink, Color.cyan, Color.lightGray, Color.gray,

};

public Palette() {

int columns = 3;

setBorder(

BorderFactory.createTitledBorder("Color Palette"));

setLayout(new GridLayout(columns,0,1,1));

for(int i=0; i < defaultColors.length; ++i)

add(new ColorPatch(defaultColors[i]));

class ColorPatch extends JPanel {

JApplet applet;

Color selectedColor;

public ColorPatch(Color color) {

setBackground(color);

addMouseListener(new MouseAdapter() {

public void mousePressed(MouseEvent e) {

selectedColor = JColorChooser.showDialog(

ColorPatch.this, // parent comp

"Pick A Color", // dialog title

getBackground()); // initial color

if(selectedColor == null) {

JOptionPane.showMessageDialog(ColorPatch.this,

"ColorChooser Canceled");

else {

setBackground(selectedColor);

"Color Selected: " + selectedColor);

16.2.2 定制顔色選取器

例16-11 顔色選取器中的一個定制預覽

private JColorChooser chooser = new JColorChooser();

private JButton button = new JButton("Show Color Chooser");

private JDialog dialog;

contentPane.add(button, BorderLayout.CENTER);

chooser.setPreviewPanel(new PreviewPanel());

if(dialog == null)

dialog = JColorChooser.createDialog(

Test.this, // parent comp

false, // modality

chooser,

null, null);

setPreferredSize(new Dimension(0,100));

setBorder(BorderFactory.createRaisedBevelBorder());

g.setColor(getForeground());

g.fillRect(0,0,size.width,size.height);

例16-12 實作一個定制顔色選取器面闆

private AbstractColorChooserPanel colorPanels[] =

new AbstractColorChooserPanel[] {

new ListPanel(),

chooser.setChooserPanels(colorPanels);

class ListPanel extends AbstractColorChooserPanel

implements ListSelectionListener {

private JPanel labelPanel = new JPanel(),

listPanel = new JPanel();

private JList redList = new JList(), blueList = new JList(),

greenList = new JList();

private DefaultListModel redModel = new DefaultListModel(),

blueModel = new DefaultListModel(),

greenModel = new DefaultListModel();

private boolean isAdjusting = false;

public void updateChooser() {

if( ! isAdjusting) {

isAdjusting = true;

Color color = getColorFromModel();

int r = color.getRed(), g = color.getGreen(),

b = color.getBlue();

redList.setSelectedIndex(r);

redList.ensureIndexIsVisible(r);

blueList.setSelectedIndex(b);

blueList.ensureIndexIsVisible(b);

greenList.setSelectedIndex(g);

greenList.ensureIndexIsVisible(g);

isAdjusting = false;

protected void buildChooser() {

redList.setFixedCellWidth(50);

greenList.setFixedCellWidth(50);

blueList.setFixedCellWidth(50);

for(int i=0; i < 256; ++i) {

redModel.addElement(Integer.toString(i));

greenModel.addElement(Integer.toString(i));

blueModel.addElement(Integer.toString(i));

redList.setModel(redModel);

greenList.setModel(greenModel);

blueList.setModel(blueModel);

listPanel.setLayout(new GridLayout(0,3,10,0));

listPanel.add(new JScrollPane(redList));

listPanel.add(new JScrollPane(blueList));

listPanel.add(new JScrollPane(greenList));

labelPanel.setLayout(new GridLayout(0,3,10,0));

labelPanel.add(new JLabel("Red"));

labelPanel.add(new JLabel("Blue"));

labelPanel.add(new JLabel("Green"));

add(labelPanel, BorderLayout.NORTH);

add(listPanel, BorderLayout.CENTER);

redList.addListSelectionListener(this);

greenList.addListSelectionListener(this);

blueList.addListSelectionListener(this);

public void valueChanged(ListSelectionEvent e) {

int r = redList.getSelectedIndex(),

b = blueList.getSelectedIndex(),

g = greenList.getSelectedIndex();

if(r != -1 && g != -1 && b != -1)

getColorSelectionModel().setSelectedColor(

new Color(r,g,b));

public String getDisplayName() {

return "display name";

public Icon getSmallDisplayIcon() {

return null;

public Icon getLargeDisplayIcon() {

16.2.3 JColorChooser屬性

16.2.4 JColorChooser事件

16.2.5 JColorChooser類總結

16.2.6 AWT相容

16.3 本章回顧

  略

上一篇: 第19章 表格
下一篇: 第17章 清單