下面的例子中第一個進度條是一個“確定模式”的滾動條,進度中顯示了當前的工作完成百分比,第二個進度條可以通過按鈕切換“不確定模式”與“確定模式”:
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;
}
}