下面的例子中第一个进度条是一个“确定模式”的滚动条,进度中显示了当前的工作完成百分比,第二个进度条可以通过按钮切换“不确定模式”与“确定模式”:
package com.cownew.Char19;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
public class ProgressBarTest1 extends JFrame
{
private JPanel jContentPane = null;
private JProgressBar jProgressBar = null;
private JProgressBar jProgressBar1 = null;
private JButton jButton = null;
private JButton jButton1 = null;
private JProgressBar getJProgressBar()
{
if (jProgressBar == null)
{
jProgressBar = new JProgressBar();
jProgressBar.setMinimum(0);
jProgressBar.setMaximum(100);
jProgressBar.setBounds(new Rectangle(46, 25, 180, 30));
// 显示进度百分比
jProgressBar.setStringPainted(true);
}
return jProgressBar;
}
private JProgressBar getJProgressBar1()
{
if (jProgressBar1 == null)
{
jProgressBar1 = new JProgressBar();
jProgressBar1.setBounds(new Rectangle(46, 77, 182, 31));
}
return jProgressBar1;
}
private JButton getJButton()
{
if (jButton == null)
{
jButton = new JButton();
jButton.setBounds(new Rectangle(234, 28, 75, 25));
jButton.setText("进度1");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e)
{
btnOnePerformed();
}
});
}
return jButton;
}
private JButton getJButton1()
{
if (jButton1 == null)
{
jButton1 = new JButton();
jButton1.setBounds(new Rectangle(243, 81, 68, 21));
jButton1.setText("进度2");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e)
{
getJProgressBar1().setIndeterminate(
!getJProgressBar1().isIndeterminate());
}
});
}
return jButton1;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
ProgressBarTest1 thisClass = new ProgressBarTest1();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
public ProgressBarTest1()
{
super();
initialize();
}
private void initialize()
{
this.setSize(326, 200);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane()
{
if (jContentPane == null)
{
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getJProgressBar(), null);
jContentPane.add(getJProgressBar1(), null);
jContentPane.add(getJButton(), null);
jContentPane.add(getJButton1(), null);
}
return jContentPane;
}
private void btnOnePerformed()
{
final Thread thread = new Thread(new Runnable() {
public void run()
{
for (int i = 0; i <= 100; i++)
{
getJProgressBar().setValue(i);
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
});
thread.start();
}
}
选项对话框
Swing提供了—套现成的简单对话框,可以完成信息提示、从用户那里收集信息的需要。这些对话框定义在
JOptionPane提供了四个静态方法,可用来显示这些简单对话框:
showMessageDialog:显示一条消息,并等候用户单击“确定”;
showConfirmDialog:显示—条消息,并从用户那里取得确认;
showOptionDialog:显示一条消息,并让用户从一系列选项中作出选择;
showInputDialog:显示一条消息,获取用户的字符输入值;
JOptionPane提供的功能是相当丰富的,可以指定消息框的类型、图标的类型、按钮的类型等,而且允许将JOptionPane做为一个组件使用,这带来了灵活性的同时也给我们的开发带来的使用上的麻烦,因为我们必须选择合适的参数。在实际开发过程中,我们使用的大部分功能以及样式都是固定的,为此在案例系统中对JOptionPane的调用进行了一个小的简化,并放到了类MsgBox中:
package com.cownew.ctk.ui.swing;
import java.awt.Component;
import javax.swing.JOptionPane;
public class MsgBox
{
public static void showInfo(Component parentComponent, Object message)
{
JOptionPane.showMessageDialog(parentComponent, message);
}
public static void showError(Component parentComponent, Object message)
{
JOptionPane.showMessageDialog(parentComponent, message, "错误",
JOptionPane.ERROR_MESSAGE);
}
public static String showInput(Component parentComponent, Object message)
{
return JOptionPane.showInputDialog(parentComponent, message);
}
public static String showInput(Component parentComponent, Object message,
Object initValue)
{
return JOptionPane.showInputDialog(parentComponent, message, initValue);
}
public static boolean showYESNO(Component parentComponent, Object message)
{
int ret = JOptionPane.showConfirmDialog(parentComponent, message, "",
JOptionPane.YES_NO_OPTION);
return ret == JOptionPane.YES_OPTION;
}
public static int showConfirm(Component parentComponent, Object message)
{
return JOptionPane.showConfirmDialog(parentComponent, message);
}
}
MsgBox提供的方法都是静态方法:showInfo用来显示一个简单的信息对话框;showError用来显示一个简单的警告对话框;showInput则用来收集用户的输入值,showInput有一个重载方法允许指定输入值的初始值;showYESNO用来供用户选择“是”或者“否”;showConfirm供用户选择“是”、“否”或者“取消”。下面是使用示例:
package com.cownew.Char19;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.cownew.ctk.common.StringUtils;
import com.cownew.ctk.ui.swing.MsgBox;
public class MsgBoxTest extends JFrame
{
private JPanel jContentPane = null;
private JButton jButton = null;
private JButton getJButton()
{
if (jButton == null)
{
jButton = new JButton();
jButton.setText("Click Me");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e)
{
btnActionPerformed();
}
});
}
return jButton;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
MsgBoxTest thisClass = new MsgBoxTest();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
public MsgBoxTest()
{
super();
initialize();
}
private void initialize()
{
this.setSize(188, 106);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane()
{
if (jContentPane == null)
{
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getJButton(), BorderLayout.CENTER);
}
return jContentPane;
}
private void btnActionPerformed()
{
String name = MsgBox.showInput(MsgBoxTest.this, "请输入姓名");
if (StringUtils.isEmpty(name))
{
MsgBox.showError(MsgBoxTest.this, "姓名不能为空!");
return;
}
boolean male = MsgBox.showYESNO(MsgBoxTest.this, "您是男性吗?");
StringBuffer msg = new StringBuffer();
msg.append("姓名:").append(name).append("\n");
msg.append("是否男性:").append(male ? "是" : "否");
MsgBox.showInfo(MsgBoxTest.this, msg.toString());
}
}
文件对话框
Swing中提供了打开文件对话框和保存文件对话框,这两个对话框并不是以两个不同的类出现的,而是定义在同一个类JFileChooser中,JFileChooser也不是从JDialog继承的对话框,它对这两个对话框的支持是通过两个静态方法完成的:showSaveDialog用于显示保存文件对话框,showOpenDialog用于显示打开文件对话框。
下面是使用JFileChooser的基本步骤:
(1)生成一个JFileChooser对象。此处并不提供父组件。
JFileChooser chooser = JFileChooser();
(2)调用setCurrentDirectory方法,设置当前日录:
chooser.setCurrentDirectory(new File(“c:/”));
(3)如果有—个希望用户选择的默认文件名、可用setSelectedFile方法来设置它,此方法可以设置多个文件对象:
chooser.setSelectedFile(new File(“c:/pic.jpg”));
(4)如果允许用户在对话柜中同时选择多个文件,可调用setMultiSelectionEnabled方法:
chooser.setMultiSelectionEnabled(true);
(5)调用showSaveDialog或者showOpenDialog方法,才会显示出对话框,在调用这个方法的时候才需要提供父组件:
int result = chooser.showSaveDialog(this);
int result = chooser.showOpenDialog(this);
返回值类型为int,当用户单击取消的时候返回JFileChooser.CANCEL_OPTION,否则返回JFileChooser.APPROVE_OPTION。
(6)要想取得选中的文件(可能是单个或者多个文件),可使用getSelectedFile或者getSelectedFiles方法,方法返回类型分别为File对象和File对象数组。
从上边的步骤可以发现JFileChooser的使用并不是很困难,JFileChooser使用的一个难点在于在对话框中对文件进行过滤。比如在RM文件制作软件的保存对话框中只能选择文件名为*.rm的文件,更为复杂的是在播放器中的文件对话框中只显示出了*.wav、*.rm、*.mpg等多类型的文件。
JFileChooser在文件名过滤这方面做的非常灵活,它采用过滤器的方式进行文件名的过滤,用户可以传递给对话框一个过滤器,在JFileChooser向对话框中添加文件的之前会通过回调过滤器询问是否接受这个文件,只有过滤器接受以后才会将其添加到文件列表中,这样就可以实现任意复杂规则的文件过滤了。
所有的过滤器必须从javax.swing.filechooser.FileFilter派生(这个类定义为接口会更好一些),FileFilter的定义是非常间接的:
public abstract class FileFilter
{
public abstract boolean accept(File f);
public abstract String getDescription();
}
在JFileChooser向对话框中添加文件的之前会调用accept方法询问是否接受这个文件,如果接受就返回true,否则返回false;getDescription用于返回这个过滤器的描述,可在文件选择对话框中显示出来。
我们来做一个能过滤指定文件后缀的过滤器,这个过滤器以一个文件后缀名做为构造函数参数,当文件以这个名字结尾的时候就可以被显示在文件列表中。
package com.cownew.ctk.ui.swing;
import java.io.File;
import javax.swing.filechooser.FileFilter;
public class SuffixFileFilter extends FileFilter
{
private String suffix;
public SuffixFileFilter(String suffix)
{
super();
this.suffix = suffix;
}
public boolean accept(File pathname)
{
if(pathname.isDirectory())
{
return true;
}
return (pathname.getName().toLowerCase()
.endsWith(suffix.toLowerCase()));
}
public String getDescription()
{
return "*."+suffix;
}
}
通过JFileChooser的setFileFilter方法就可以将这个过滤器设置到文件选择对话框了。
有的时候一个文件选择对话框允许有多个选择器,比如在Windows MediaPlayer中就能够选择多组不同的文件类型。
为了支持这样的效果,JFileChooser不仅提供了setFileFilter方法,还提供了addChoosableFileFilter方法来增加多组过滤器。如果设定setAcceptAllFileFilterUsed为true,那么文件类型中将会显示出“所有文件”。
对于文件选择对话框显示的每一个文件我们都可以提供定制其显示的图标及文件说明,并定制对话框的一些行为。为了达到这个目的需要提供一个继承了FileView类的子类对象,并通过setFileView方法设置给对话框。FileView类定义了下面五个方法:
public String getName(File f)
public String getDescription(File f)
public String getTypeDescription(File f)
public Icon getIcon(File f)
public Boolean isTraversable(File f)
下面是文件对话框一个综合应用的例子:
package com.cownew.Char19;
import java.awt.Rectangle;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import com.cownew.ctk.ui.swing.SuffixFileFilter;
public class FileChooserTestFrame extends JFrame
{
private JPanel jContentPane = null;
private JScrollPane jScrollPane = null;
private JList jList = null;
private JButton jButton = null;
private JScrollPane getJScrollPane()
{
if (jScrollPane == null)
{
jScrollPane = new JScrollPane();
jScrollPane.setBounds(new Rectangle(6, 4, 153, 164));
jScrollPane.setViewportView(getJList());
}
return jScrollPane;
}
private JList getJList()
{
if (jList == null)
{
jList = new JList();
}
return jList;
}
private JButton getJButton()
{
if (jButton == null)
{
jButton = new JButton();
jButton.setBounds(new Rectangle(171, 132, 103, 28));
jButton.setText("选择文件");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e)
{
jButton_actionPerformed();
}
});
}
return jButton;
}
protected void jButton_actionPerformed()
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("c:/"));
//允许"全部文件"
fileChooser.setAcceptAllFileFilterUsed(true);
fileChooser.setMultiSelectionEnabled(true);
fileChooser.addChoosableFileFilter(new SuffixFileFilter("txt"));
fileChooser.addChoosableFileFilter(new SuffixFileFilter("wav"));
fileChooser.addChoosableFileFilter(new SuffixFileFilter("mp3"));
fileChooser.showOpenDialog(FileChooserTestFrame.this);
File[] files = fileChooser.getSelectedFiles();
DefaultListModel listModel = new DefaultListModel();
for(int i=0,n=files.length;i<n;i++)
{
listModel.addElement(files[i].getName());
}
getJList().setModel(listModel);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
FileChooserTestFrame thisClass = new FileChooserTestFrame();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
public FileChooserTestFrame()
{
super();
initialize();
}
private void initialize()
{
this.setSize(310, 200);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane()
{
if (jContentPane == null)
{
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getJScrollPane(), null);
jContentPane.add(getJButton(), null);
}
return jContentPane;
}
}