滑动杆(Slider),时间控制(Timer),进度元件(Progress)的使用与介绍:
14-1:使用JSlider组件:
JSlider的类层次结构图:
java.lang.Object
--java.awt.COmponent
--java.awt.Container
--javax.swing.JComponent
--javax.swing.JSlider
我们曾在前面提到JScrollBar这个组件,可以让用户决定拉曳时一次滚动的区域大小,并且可以得到目前滚动杆上的值,看起来JScrollBar好象可以当作这
种微调的组件.然而JScrollBar通常置于窗口的最右边或最下面,且常JScrollBar来使用,因此在外观上或
实际应用上并不适合当微调工具使用,不过不用担心,java提供了一个特别为微调设计的组件,那就是JSlider.JSlider不仅可以置于
面版的任何地方,也可以在JSlider上标上刻度与数字,既美观又实用,我们现在就来看如何使用JSlider吧.
JSlider的构造函数:
JSlider():建立一个水平的JSlider对象,刻度从0-100,初始刻度为50.
JSlider(BoundedRangeModel brm):使用默认模式建立一个水平的JSlider对象.
JSlider(int orientation):建立一个自定义方向的JSlider对象,刻度从0-100,初始刻度为50.
JSlider(int min,int max):建立一个水平的JSlider对象,自定义刻度,从min-max,初始刻度为50.
JSlider(int min, int max,int value):建立一个水平的JSlider的对象,自定义刻度与初始值.
JSlider(int orientation,int min,int max,int value):建立一个自定义方向,刻度与刻度初始值的JSlider对象.
要使用JSlider组件就不得不提到JSlider事件的处理.当用户在JSlider上滑动杆时,就会产生ChangeEvent事件,若我们要处理
ChangeEvent事件就必须实作ChangeListener界面,此界面定义了一个方法,那就是stateChanged().通常我们在这个方法上会取得或
置滑动杆的相关信息,例如滑动杆的延伸区(extent),最大最小值或滑动杆目前所在刻度等等.我们来看下一节所举的范例:
14-1-1:建立JSlider组件:
这个范例我们建立了3个JSlider组件,并对每个JSlider组件做相关的设置,例如设置方向,初始值,最大最小值,延伸区值(extent)
等.
import javax.swing.*;//ChangeEvent事件是属于Swing事件,若要处理此事件必须将import swing的event package进来.
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
public class SliderDemo1 implements ChangeListener
{
JFrame f = null;
JSlider slider1;
JSlider slider2;
JSlider slider3;
JLabel label1;
JLabel label2;
JLabel label3;
public SliderDemo1()
{
f = new JFrame("JSlider Example");
Container contentPane = f.getContentPane();
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2,1));
slider1 = new JSlider();//建立一个默认的JSlider组件.
label1 = new JLabel("目前刻度:"+slider1.getValue());
panel1.add(label1);
panel1.add(slider1);
panel1.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 1",TitledBorder.LEFT,
TitledBorder.TOP));
JPanel panel2 = new JPanel();
panel2.setLayout(new GridLayout(2,1));
/*下面五行程序建立一个水平方向的JSlider组件,并设置其取大值,最小值,初始值与延伸区值,所谓的延伸区值我们在前面
*JScrollBar中也提到过,意思是限制JSlider刻度可变动的范围,也就是说延伸区就像是一个障碍区,是无法通行的.延伸区
*设得越大,刻度可变动的范围就越小.例如若minimum值设为0,maximan值设为100,而extent值设为0,则JSlider刻度可变动
*的区域大小为100-50-0=50刻度(从0-50).
*/
slider2 = new JSlider(JSlider.HORIZONTAL);
slider2.setMinimum(0);
slider2.setMaximum(100);
slider2.setValue(30);
slider2.setExtent(50);
label2 = new JLabel("目前刻度:"+slider2.getValue());
panel2.add(label2);
panel2.add(slider2);
panel2.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 2",TitledBorder.LEFT,
TitledBorder.TOP));
JPanel panel3 = new JPanel();
panel3.setLayout(new GridLayout(2,1));
//下面两行建立一个具有最大最小值的JSlider组件,并设置此JSlider组件为垂直方向.
slider3 = new JSlider(20,80);
slider3.setOrientation(JSlider.VERTICAL);
label3 = new JLabel("目前刻度:"+slider3.getValue());
panel3.add(label3);
panel3.add(slider3);
panel3.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 3",TitledBorder.LEFT,
TitledBorder.TOP));
slider1.addChangeListener(this);
slider2.addChangeListener(this);
slider3.addChangeListener(this);
panel1.setPreferredSize(new Dimension(300,100));
panel2.setPreferredSize(new Dimension(300,100));
panel3.setPreferredSize(new Dimension(150,200));
GridBagConstraints c;
int gridx,gridy,gridwidth,
gridheight,anchor,fill,ipadx,ipady;
double weightx,weighty;
Insets inset;
GridBagLayout gridbag = new GridBagLayout();
contentPane.setLayout(gridbag);
gridx=0; //第0行
gridy=0; //第0列
gridwidth = 2; //占两单位宽度
gridheight = 1; //占一单位高度
weightx = 0; //窗口增大时组件宽度增大比率0
weighty = 0; //窗口增大时组件高度增大比率0
anchor = GridBagConstraints.CENTER; //容器大于组件size时将组件
//置于容器中央
fill = GridBagConstraints.BOTH; //窗口拉大时会填满水平与垂
//直空间
inset = new Insets(0,0,0,0); //组件间间距
ipadx = 0; //组件内水平宽度
ipady = 0; //组件内垂直高度
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel1,c);
contentPane.add(panel1);
gridx=0;
gridy=1;
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel2,c);
contentPane.add(panel2);
gridx=2;
gridy=0;
gridwidth = 1; //占一单位宽度
gridheight = 2; //占两单位高度
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel3,c);
contentPane.add(panel3);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args)
{
new SliderDemo1();
}
//处理ChangeEvent事件,当用户移动滑动杆时,label上的值会随着用户的移动而改变.
public void stateChanged(ChangeEvent e)
{
if ((JSlider)e.getSource() == slider1)
label1.setText("目前刻度:"+slider1.getValue());
if ((JSlider)e.getSource() == slider2)
label2.setText("目前刻度:"+slider2.getValue());
if ((JSlider)e.getSource() == slider3)
label3.setText("目前刻度:"+slider3.getValue());
}
}
注:由于slider3设置延伸区值(Extent)为50,因此slider2刻度可变动的区域只到50,因此当slider2超过50刻度时就算你再向右移
动,刻度值一样维持在50上.
14-1-2:为JSlider组件加入刻度.
上面这个例子中,你是否觉得好像少了什么?没错,就是刻度!接下来,我们来设置JSlider的刻度与数字,并增加一些设置项目,完
整的JSlider组件就大功告成了.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.*;
public class SliderDemo2 implements ChangeListener
{
JFrame f = null;
JSlider slider1;
JSlider slider2;
JSlider slider3;
JLabel label1;
JLabel label2;
JLabel label3;
public SliderDemo2()
{
f = new JFrame("JSlider Example");
Container contentPane = f.getContentPane();
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2,1));
slider1 = new JSlider();
//setPaintTicks()方法是设置是否在JSlider加上刻度,若为true则下面两行才有作用。
slider1.setPaintTicks(true);
/*设置大刻度与小刻度之间的距离(setMajorTickSpacing()与setMinorTickSpacing()方法).例如若大刻度间距离为30,
*小刻度间距离为10,则表示2个大刻度间会有3个小刻度.
*/
slider1.setMajorTickSpacing(20);
slider1.setMinorTickSpacing(10);
//setPaintLabels()方法为设置是否数字标记,若设为true,则JSlider刻度上就会有数值出现。
slider1.setPaintLabels(true);
//setPaintTrack()方法表示是否出现滑动杆的横杆。默认值为true.
slider1.setPaintTrack(true);
//setSnapToTicks()方法表示一次移动一个小刻度,而不再是一次移动一个单位刻度。
slider1.setSnapToTicks(true);
label1 = new JLabel("目前刻度:"+slider1.getValue());
panel1.add(label1);
panel1.add(slider1);
panel1.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 1",TitledBorder.LEFT,
TitledBorder.TOP));
JPanel panel2 = new JPanel();
panel2.setLayout(new GridLayout(2,1));
slider2 = new JSlider(JSlider.HORIZONTAL);
slider2.setMinimum(0);
slider2.setMaximum(100);
slider2.setValue(30);
slider2.setExtent(50);
slider2.setPaintTicks(true);
slider2.setMajorTickSpacing(10);
slider2.setMinorTickSpacing(2);
slider2.setPaintLabels(true);
/*JComponent提供了一个putClientProperty()方法,可以使得JSlider中的小于滑动杆位置与大于滑动杆位置间的颜色不
*一样,这样的视觉效果会比较好,"JSlider.isFilled"值是定义在MetalSliderUI这个类的SLIDER_FILL常数中,此类是
*定义在java的JSlider默认外观,你可以在javax.swing.plaf.metal.package中找到这个类。
*/
slider2.putClientProperty("JSlider.isFilled",Boolean.TRUE);
label2 = new JLabel("目前刻度:"+slider2.getValue());
panel2.add(label2);
panel2.add(slider2);
panel2.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 2",TitledBorder.LEFT,
TitledBorder.TOP));
JPanel panel3 = new JPanel();
panel3.setLayout(new GridLayout(2,1));
slider3 = new JSlider(20,80);
slider3.setOrientation(JSlider.VERTICAL);
slider3.setPaintTicks(true);
slider3.setMajorTickSpacing(30);
slider3.setMinorTickSpacing(10);
slider3.setPaintLabels(true);
slider3.putClientProperty("JSlider.isFilled",Boolean.TRUE);
label3 = new JLabel("目前刻度:"+slider3.getValue());
panel3.add(label3);
panel3.add(slider3);
panel3.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 3",TitledBorder.LEFT,
TitledBorder.TOP));
slider1.addChangeListener(this);
slider2.addChangeListener(this);
slider3.addChangeListener(this);
panel1.setPreferredSize(new Dimension(300,130));
panel2.setPreferredSize(new Dimension(300,130));
panel3.setPreferredSize(new Dimension(150,260));
GridBagConstraints c;
int gridx,gridy,gridwidth,
gridheight,anchor,fill,ipadx,ipady;
double weightx,weighty;
Insets inset;
GridBagLayout gridbag = new GridBagLayout();
contentPane.setLayout(gridbag);
gridx=0; //第0行
gridy=0; //第0列
gridwidth = 2; //占两单位宽度
gridheight = 1; //占一单位高度
weightx = 0;
weighty = 0;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.BOTH;
inset = new Insets(0,0,0,0);
ipadx = 0;
ipady = 0;
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel1,c);
contentPane.add(panel1);
gridx=0;
gridy=1;
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel2,c);
contentPane.add(panel2);
gridx=2;
gridy=0;
gridwidth = 1; //占一单位宽度
gridheight = 2; //占两单位高度
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel3,c);
contentPane.add(panel3);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args)
{
new SliderDemo2();
}
public void stateChanged(ChangeEvent e)
{
if ((JSlider)e.getSource() == slider1)
label1.setText("目前刻度:"+slider1.getValue());
if ((JSlider)e.getSource() == slider2)
label2.setText("目前刻度:"+slider2.getValue());
if ((JSlider)e.getSource() == slider3)
label3.setText("目前刻度:"+slider3.getValue());
}
}
14-1-3:自定义JSlider标记名称:
我们在上个范例中看到的JSlider标记都是数字形态,当然我们也可以自定义自己想要的标记文字,这时候就必须使用JSlider所
提供的setLabelTable()方法。我们来看下面的例子。
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.*;
public class SliderDemo3 implements ChangeListener
{
JFrame f = null;
JSlider slider1;
JSlider slider2;
JSlider slider3;
JLabel label1;
JLabel label2;
JLabel label3;
public SliderDemo3()
{
f = new JFrame("JSlider Example");
Container contentPane = f.getContentPane();
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2,1));
slider1 = new JSlider();
slider1.setPaintTicks(true);
slider1.setMajorTickSpacing(20);
slider1.setMinorTickSpacing(10);
slider1.setPaintLabels(true);
slider1.setPaintTrack(true);
slider1.setSnapToTicks(true);
label1 = new JLabel("目前刻度:"+slider1.getValue());
panel1.add(label1);
panel1.add(slider1);
panel1.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 1",TitledBorder.LEFT,
TitledBorder.TOP));
Hashtable table = new Hashtable();
table.put(new Integer( 0 ),new JLabel("低"));
table.put(new Integer( 50 ),new JLabel("中"));
table.put(new Integer( 100 ),new JLabel("高"));
slider1.setLabelTable(table);
JPanel panel2 = new JPanel();
panel2.setLayout(new GridLayout(2,1));
slider2 = new JSlider(JSlider.HORIZONTAL);
slider2.setMinimum(0);
slider2.setMaximum(100);
slider2.setValue(30);
slider2.setExtent(50);
slider2.setPaintTicks(true);
slider2.setMajorTickSpacing(10);
slider2.setMinorTickSpacing(5);
slider2.setPaintLabels(true);
slider2.putClientProperty("JSlider.isFilled",Boolean.TRUE);
label2 = new JLabel("目前刻度:"+slider2.getValue());
panel2.add(label2);
panel2.add(slider2);
panel2.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 2",TitledBorder.LEFT,
TitledBorder.TOP));
table = new Hashtable();
table.put(new Integer( 0 ),new JLabel("弱"));
table.put(new Integer( 25 ),new JLabel("有点弱"));
table.put(new Integer( 50 ),new JLabel("中"));
table.put(new Integer( 75 ),new JLabel("有点强"));
table.put(new Integer( 100 ),new JLabel("强"));
slider2.setLabelTable(table);
JPanel panel3 = new JPanel();
panel3.setLayout(new GridLayout(2,1));
slider3 = new JSlider(20,80);
slider3.setOrientation(JSlider.VERTICAL);
slider3.setPaintTicks(true);
slider3.setMajorTickSpacing(30);
slider3.setMinorTickSpacing(10);
slider3.setPaintLabels(true);
slider3.putClientProperty("JSlider.isFilled",Boolean.TRUE);
label3 = new JLabel("目前刻度:"+slider3.getValue());
panel3.add(label3);
panel3.add(slider3);
panel3.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),"Slider 3",TitledBorder.LEFT,
TitledBorder.TOP));
slider1.addChangeListener(this);
slider2.addChangeListener(this);
slider3.addChangeListener(this);
panel1.setPreferredSize(new Dimension(300,130));
panel2.setPreferredSize(new Dimension(300,130));
panel3.setPreferredSize(new Dimension(150,260));
GridBagConstraints c;
int gridx,gridy,gridwidth,
gridheight,anchor,fill,ipadx,ipady;
double weightx,weighty;
Insets inset;
GridBagLayout gridbag = new GridBagLayout();
contentPane.setLayout(gridbag);
gridx=0; //第0行
gridy=0; //第0列
gridwidth = 2; //占两单位宽度
gridheight = 1; //占一单位高度
weightx = 0;
weighty = 0;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.BOTH;
inset = new Insets(0,0,0,0);
ipadx = 0;
ipady = 0;
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel1,c);
contentPane.add(panel1);
gridx=0;
gridy=1;
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel2,c);
contentPane.add(panel2);
gridx=2;
gridy=0;
gridwidth = 1; //占一单位宽度
gridheight = 2; //占两单位高度
c = new GridBagConstraints(gridx,gridy,gridwidth,gridheight,
weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(panel3,c);
contentPane.add(panel3);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args)
{
new SliderDemo3();
}
public void stateChanged(ChangeEvent e)
{
if ((JSlider)e.getSource() == slider1)
label1.setText("目前刻度:"+slider1.getValue());
if ((JSlider)e.getSource() == slider2)
label2.setText("目前刻度:"+slider2.getValue());
if ((JSlider)e.getSource() == slider3)
label3.setText("目前刻度:"+slider3.getValue());
}
}
说明:要改变标记值必须使用setLabelTable(Dictionary table)方法,参数Dictionary本身是一个抽象类,我们并不能直接就new
出一个Dictionary对象,而必须使用它的子类Hashtable来产生Dictionary类型的对象。Hashtable存储信息的方式是以
key-value pair类型来存储,换名话说,当你要找某个对象时,你就必须知道此对象的key值。而在此例中,我们要换原有
JSlider上的文字,必须指明那个数字要理发成什么文字。例如table.put(new Integer(0)),new JLabel("弱"))就表示数字
0要变更成文字"弱",在Hashtable中,Integer(0)就是对象JLabel("弱")的key值。
14-2:使用Timer组件:
java.lang.Object
--javax.swing.Timer
使用Timer组件可以让你在一段时间内依次做出你指定的操作,这在动画的展示上非常有用。如果你有用过如ACDsee这类的看图
软件,你可以发现这类软件都会提供一种功能,那就是自动换图的功能,而且也可以让你设置换图时间间隔的长短。在java中,
swing的Timer组件就可以让你做到这样的功能,而且非常容易使用,下面我们先来看Timer的构造函数。
Timer构造函数:
Timer(int delay,ActionListener listener):建立一个Timer组件,并在每一次delay的时间点上触发ActionEvent.
使用Timer组件它会在根据你所给予的delay时间,周期性的触发ActionEvent事件,如果你要处理这个事件,你必须实作
ActionListener界面所定义的actionPerformed()方法。要开始激活Timer组件,你可以用start()方法,要停止Timer组件可以使用
stop()方法,要从新激活Timer组件可以使用restart()方法,若只想Timer组件只触发一次ActionEvent事件,可利用
setRepeats(false)方法,将参数设为false,若要设置delay时间则可用setDelay()方法。
事实上使用Timer组件表示在程序背后是利用Threads在运行Timer的工作,因此你当然也可以利用Thread的功能来自行制造出这
样的效果,不过这不在本书的讨论范围内,下面的范例我们实作一个显示图程序,可让用户调整显示图时间的快慢。
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.*;
public class TimerDemo1 implements ActionListener,ChangeListener
{
JFrame f = null;
ImageIcon[] icons;
JSlider slider1;
JLabel label;
JToggleButton toggleb1,toggleb2;
JButton b;
javax.swing.Timer timer;
int index = 0;
public TimerDemo1()
{
f = new JFrame("Timer Example");
Container contentPane = f.getContentPane();
icons = new ImageIcon[5];
for (int i=0 ; i<5 ; i++)
icons[i] = new ImageIcon(".\\icons\\"+(i+1)+".jpg");
label = new JLabel(icons[0]);
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2,1));
slider1 = new JSlider();
slider1.setPaintTicks(true);
slider1.setMajorTickSpacing(20);
slider1.setMinorTickSpacing(10);
slider1.setPaintLabels(true);
slider1.addChangeListener(this);
panel1.add(slider1);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1,3));
toggleb1 = new JToggleButton("Start");
toggleb1.addActionListener(this);
buttonPanel.add(toggleb1);
b = new JButton("Restart");
b.addActionListener(this);
buttonPanel.add(b);
toggleb2 = new JToggleButton("Don't Repeat");
toggleb2.addActionListener(this);
buttonPanel.add(toggleb2);
panel1.add(buttonPanel);
Hashtable table = new Hashtable();
table.put(new Integer( 0 ),new JLabel("е"));
table.put(new Integer( 50 ),new JLabel("い"));
table.put(new Integer( 100 ),new JLabel("篊"));
slider1.setLabelTable(table);
/*由于java的Timer组件有两种,一种是javax.swing.Timer,一种是java.util.Timer,若我们在程序中import了这两种
*package,则系统将不晓得到底要产生哪种Timer组件,就如同本范例一般,因此我们必须在new Timer组件的同时,指
*定要new出哪一种类型的Timer组件。因此我们必须在new Timer组件的同时,指定要new出哪一种类型的Timer组件,在
*此我们当然是要产生Swing的Timer组件,在此我们当然是要产生Swing的Timer组件。
*/
timer = new javax.swing.Timer(slider1.getValue()*10,this);
contentPane.add(label,BorderLayout.CENTER);
contentPane.add(panel1,BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args)
{
new TimerDemo1();
}
//处理按钮事件与Timer事件。
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == toggleb1)
{//当用户按下"start"按钮时,Timer开始运行,且"Start"按钮会变成"Stop",若用户再次按下"stop"按钮,则Timer暂停
//运行,且"stop"按钮变成"start".
if (e.getActionCommand().equals("Start"))
{
timer.start();
toggleb1.setText("Stop");
}
if (e.getActionCommand().equals("Stop"))
{
timer.stop();
toggleb1.setText("Start");
}
}
//当用户按下"Don't Repeat"按钮时,则Timer事件只触发一次,若再按一次"Don't Repeat"按钮,则Timer继续运行。
if (e.getSource() == toggleb2)
{
if(timer.isRepeats())
{
timer.setRepeats(false);
}
else
{
timer.setRepeats(true);
timer.start();
}
}
//当用户按下"Restart"按钮时,则Timer组件的delay值恢复成初如值,并重新运行Timer.
if (e.getSource() == b)
{
slider1.setValue(50);
timer.restart();
}
//处理Timer产生的ActionEvent事件,每次时间一到delay所设置的时间,label上的图片就会更换一次。
if (e.getSource() == timer)
{
if (index == 5)
index = 0;
label.setIcon(icons[index]);
label.repaint();
//f.pack(); //若要窗口随图形大小变化,可加入此行.
index++;
}
}
//处理slider所产生的ChangeEvent事件,当用户移动slider1的滑动杆时,等于从新设置Timer的delay时间。
public void stateChanged(ChangeEvent e1)
{
timer.setDelay(slider1.getValue()*10);
}
}
14-3:使用Progress Bar组件:
JProgressBar的类层次结构图:
java.lang.Object
--java.awt.Component
--java.awt.Container
--javax.swing.JComponent
--javax.swing.JProgressBar
当你在安装一个新软件时,系统会告知你目前软件安装的进度如何?才不会让你觉得程序好像死了,同样的,若你设计的程序所
需要的运行超过2秒以上,你应该显示程序正在运行中的图标,或直接显示程序运行的进度,这样就能让用户清楚知道程序到底是死
了还是继续运行,在swing中,JProgressBar组件提供了类似这样的功能,它可以簋简单地输出进度的变化情况,让你想要提供进度
信息时,不再需要自行绘制绘图组件,只需要使用JProgressBar再加上几行程序设置就可以了。以下是JProgressBar的范例,在此
范例中,我们使用Timer组件当作控制进度杆移动的速度,当用户按下"start"按钮,则进度杆线就会开始向右移动,并显示出目前
的进度信息。每当JProgressBar的值改变一次(利用setValue()方法),就会触发一次ChangeEvent事件,如果你要处理这个事件,
你必须实作ChangeListener界面所定义的stateChanged()方法,在此我们是将JPogressBar的移动信息放在label上。
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
public class ProgressBarDemo implements ActionListener,ChangeListener
{
JFrame f = null;
JProgressBar progressbar;
JLabel label;
Timer timer;
JButton b;
public ProgressBarDemo()
{
f = new JFrame("progressbar Example");
Container contentPane = f.getContentPane();
label = new JLabel(" ",JLabel.CENTER);
progressbar = new JProgressBar();
progressbar.setOrientation(JProgressBar.HORIZONTAL);
progressbar.setMinimum(0);
progressbar.setMaximum(100);
progressbar.setValue(0);
progressbar.setStringPainted(true);
progressbar.addChangeListener(this);
progressbar.setPreferredSize(new Dimension(200,30));
progressbar.setBorderPainted(false);
JPanel panel = new JPanel();
b = new JButton("Start");
b.addActionListener(this);
panel.add(b);
timer = new Timer(50,this);
contentPane.add(panel,BorderLayout.NORTH);
contentPane.add(progressbar,BorderLayout.CENTER);
contentPane.add(label,BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args)
{
new ProgressBarDemo();
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == b)
{
timer.start();
}
if(e.getSource() == timer)
{
int value = progressbar.getValue();
if( value < 100)
{
value++;
progressbar.setValue(value);
}
else
{
timer.stop();
progressbar.setValue(0);
}
}
}
public void stateChanged(ChangeEvent e1)
{
int value = progressbar.getValue();
if(e1.getSource() == progressbar)
{
label.setText("目前已完成进度:"+Integer.toString(value)+" %");
}
}
}