前几天讲了Swing基本的控件,今天开始讲特殊控件。一天讲2个吧,首先讲用JProgressBar,ProgressMonitor和BoundedRangeModel来实现进度条。然后讲用JSlider和BoundedRangeModel来实现滑动条。

进度条,eg

1. public class TestJProgressBar  
2. {  
3.     JFrame frame = new JFrame("测试进度条");  
4.     //创建一条垂直进度条  
5.     JProgressBar bar = new JProgressBar(JProgressBar.VERTICAL );  
6.     JCheckBox indeterminate = new JCheckBox("不确定进度");  
7.     JCheckBox noBorder = new JCheckBox("不绘制边框");  
8.     public void init()  
9.     {  
10.         Box box = new Box(BoxLayout.Y_AXIS);  
11.         box.add(indeterminate);  
12.         box.add(noBorder);  
13.         frame.setLayout(new FlowLayout());  
14.         frame.add(box);  
15.         //把进度条添加到JFrame窗口中  
16.         frame.add(bar);  
17.  
18.         //设置在进度条中绘制完成百分比  
19.         bar.setStringPainted(true);  
20.         noBorder.addActionListener(new ActionListener()  
21.         {    
22.             public void actionPerformed(ActionEvent event)  
23.             {  
24.                 //根据该选择框决定是否绘制进度条的边框  
25.                 bar.setBorderPainted(!noBorder.isSelected());  
26.             }  
27.         });  
28.         final SimulatedTarget target = new SimulatedTarget(1000);  
29.         //以启动一条线程的方式来执行一个耗时的任务  
30.         new Thread(target).start();  
31.         //设置进度条的最大值和最小值,  
32.         bar.setMinimum(0);   
33.         //以总任务量作为进度条的最大值  
34.         bar.setMaximum(target.getAmount());  
35.         Timer timer = new Timer(300 , new ActionListener()  
36.         {  
37.             public void actionPerformed(ActionEvent e)  
38.             {  
39.                 //以任务的当前完成量设置进度条的value  
40.                 bar.setValue(target.getCurrent());  
41.             }  
42.         });  
43.         timer.start();  
44.         indeterminate.addActionListener(new ActionListener()  
45.         {    
46.             public void actionPerformed(ActionEvent event)  
47.             {  
48.                 //设置该进度条的进度是否确定  
49.                 bar.setIndeterminate(indeterminate.isSelected());  
50.                 bar.setStringPainted(!indeterminate.isSelected());  
51.             }  
52.         });  
53.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
54.         frame.pack();  
55.         frame.setVisible(true);  
56.     }  
57.     public static void main(String[] args)   
58.     {  
59.         new TestJProgressBar().init();  
60.     }  
61. }  
62. //模拟一个耗时的任务  
63. class SimulatedTarget implements Runnable  
64. {   
65.     //任务的当前完成量  
66.     private volatile int current;  
67.     //总任务量  
68.     private int amount;  
69.     public SimulatedTarget(int amount)  
70.     {    
71.         current = 0;  
72.         this.amount = amount;  
73.     }  
74.  
75.     public int getAmount()  
76.     {    
77.       return amount;  
78.     }  
79.  
80.     public int getCurrent()  
81.     {    
82.         return current;  
83.     }  
84.     //run方法代表不断完成任务的过程  
85.     public void run()  
86.     {    
87.  
88.         while (current < amount)  
89.         {   
90.             try 
91.             {  
92.                 Thread.sleep(50);  
93.             }  
94.             catch(InterruptedException e)  
95.             {  
96.  
97.             }  
98.             current++;  
99.         }  
100.     }  
101. }


SimulatedTarget模拟了一个耗时程序,JProgressBar存在BoundedRangeModel用于保存数据对象。

ProgressMonitor是进度对话框,用起来很方便,但就缺乏了自主性,eg

    1. public class TestProgressMonitor  
    2. {  
    3.     Timer timer;  
    4.     public void init()  
    5.     {  
    6.         final SimulatedTarget target = new SimulatedTarget(1000);  
    7.         //以启动一条线程的方式来执行一个耗时的任务  
    8.         final Thread targetThread = new Thread(target);  
    9.         targetThread.start();  
    10.         //创建进度对话框  
    11.         final ProgressMonitor dialog = new ProgressMonitor(null ,  
    12.             "等待任务完成" , "已完成:" , 0 , target.getAmount());  
    13.         //创建一个计时器  
    14.         timer = new Timer(300 , new ActionListener()  
    15.         {  
    16.             public void actionPerformed(ActionEvent e)  
    17.             {  
    18.                 //以任务的当前完成量设置进度对话框的完成比例  
    19.                 dialog.setProgress(target.getCurrent());  
    20.                 //如果用户单击了进度对话框的”取消“按钮  
    21.                 if (dialog.isCanceled())  
    22.                 {  
    23.                     //停止计时器  
    24.                     timer.stop();  
    25.                     //中断任务的执行线程  
    26.                     targetThread.interrupt();  
    27.                     //系统退出  
    28.                     System.exit(0);  
    29.                 }  
    30.             }  
    31.         });  
    32.         timer.start();  
    33.     }  
    34.     public static void main(String[] args)   
    35.     {  
    36.         new TestProgressMonitor().init();  
    37.     }  
    38. }


    这个程序利用了上面的耗时程序。进度条就是那么简单。

    滑动条和进度条差不多,他们共用一个模型BoundedRangeModel。下面是个滑动条的各样式的演示例子,eg

      1. public class TestJSlider  
      2. {  
      3.     JFrame mainWin = new JFrame("滑动条示范");  
      4.     Box sliderBox = new Box(BoxLayout.Y_AXIS);  
      5.     JTextField showVal = new JTextField();  
      6.     ChangeListener listener;  
      7.     public void init()   
      8.     {  
      9.         //定义一个监听器,用于监听所有滑动条  
      10.         listener = new ChangeListener()  
      11.         {    
      12.             public void stateChanged(ChangeEvent event)  
      13.             {    
      14.                 //取出滑动条的值,并在文本中显示出来  
      15.                 JSlider source = (JSlider) event.getSource();  
      16.                 showVal.setText("当前滑动条的值为:" + source.getValue());  
      17.             }  
      18.         };  
      19.         //-----------添加一个普通滑动条-----------  
      20.         JSlider slider = new JSlider();  
      21.         addSlider(slider, "普通滑动条");  
      22.  
      23.         //-----------添加保留区为30的滑动条-----------  
      24.         slider = new JSlider();  
      25.         slider.setExtent(30);  
      26.         addSlider(slider, "保留区为30");  
      27.  
      28.         //-----------添加带主、次刻度的滑动条,并设置其最大值,最小值-----------  
      29.         slider = new JSlider(30 , 200);  
      30.         //设置绘制刻度  
      31.         slider.setPaintTicks(true);  
      32.         //设置主、次刻度的间距  
      33.         slider.setMajorTickSpacing(20);  
      34.         slider.setMinorTickSpacing(5);  
      35.         addSlider(slider, "有刻度");  
      36.  
      37.         //-----------添加滑块必须停在刻度处滑动条-----------  
      38.         slider = new JSlider();  
      39.         //设置滑块必须停在刻度处  
      40.         slider.setSnapToTicks(true);  
      41.         //设置绘制刻度  
      42.         slider.setPaintTicks(true);  
      43.         //设置主、次刻度的间距  
      44.         slider.setMajorTickSpacing(20);  
      45.         slider.setMinorTickSpacing(5);  
      46.         addSlider(slider, "滑块停在刻度处");  
      47.  
      48.         //-----------添加没有滑轨的滑动条-----------  
      49.         slider = new JSlider();  
      50.         //设置绘制刻度  
      51.         slider.setPaintTicks(true);  
      52.         //设置主、次刻度的间距  
      53.         slider.setMajorTickSpacing(20);  
      54.         slider.setMinorTickSpacing(5);  
      55.         //设置不绘制滑轨  
      56.         slider.setPaintTrack(false);  
      57.         addSlider(slider, "无滑轨");  
      58.  
      59.         //-----------添加方向反转的滑动条-----------  
      60.         slider = new JSlider();  
      61.         //设置绘制刻度  
      62.         slider.setPaintTicks(true);  
      63.         //设置主、次刻度的间距  
      64.         slider.setMajorTickSpacing(20);  
      65.         slider.setMinorTickSpacing(5);  
      66.         //设置方向反转  
      67.         slider.setInverted(true);  
      68.         addSlider(slider, "方向反转");  
      69.  
      70.         //-----------添加绘制默认刻度标签的滑动条-----------  
      71.         slider = new JSlider();  
      72.         //设置绘制刻度  
      73.         slider.setPaintTicks(true);  
      74.         //设置主、次刻度的间距  
      75.         slider.setMajorTickSpacing(20);  
      76.         slider.setMinorTickSpacing(5);  
      77.         //设置绘制刻度标签,默认绘制数值刻度标签  
      78.         slider.setPaintLabels(true);  
      79.         addSlider(slider, "数值刻度标签");  
      80.  
      81.         //-----------添加绘制Label类型的刻度标签的滑动条-----------   
      82.         slider = new JSlider();  
      83.         //设置绘制刻度  
      84.         slider.setPaintTicks(true);  
      85.         //设置主、次刻度的间距  
      86.         slider.setMajorTickSpacing(20);  
      87.         slider.setMinorTickSpacing(5);  
      88.         //设置绘制刻度标签  
      89.         slider.setPaintLabels(true);  
      90.         Dictionary<Integer, Component> labelTable = new Hashtable<Integer, Component>();  
      91.         labelTable.put(0, new JLabel("A"));  
      92.         labelTable.put(20, new JLabel("B"));  
      93.         labelTable.put(40, new JLabel("C"));  
      94.         labelTable.put(60, new JLabel("D"));  
      95.         labelTable.put(80, new JLabel("E"));  
      96.         labelTable.put(100, new JLabel("F"));  
      97.         //指定刻度标签,标签是JLabel  
      98.         slider.setLabelTable(labelTable);  
      99.         addSlider(slider, "JLable标签");  
      100.  
      101.         //-----------添加绘制Label类型的刻度标签的滑动条-----------   
      102.         slider = new JSlider();  
      103.         //设置绘制刻度  
      104.         slider.setPaintTicks(true);  
      105.         //设置主、次刻度的间距  
      106.         slider.setMajorTickSpacing(20);  
      107.         slider.setMinorTickSpacing(5);  
      108.         //设置绘制刻度标签  
      109.         slider.setPaintLabels(true);  
      110.         labelTable = new Hashtable<Integer, Component>();  
      111.         labelTable.put(0, new JLabel(new ImageIcon("ico/0.GIF")));  
      112.         labelTable.put(20, new JLabel(new ImageIcon("ico/2.GIF")));  
      113.         labelTable.put(40, new JLabel(new ImageIcon("ico/4.GIF")));  
      114.         labelTable.put(60, new JLabel(new ImageIcon("ico/6.GIF")));  
      115.         labelTable.put(80, new JLabel(new ImageIcon("ico/8.GIF")));  
      116.         //指定刻度标签,标签是ImageIcon  
      117.         slider.setLabelTable(labelTable);  
      118.         addSlider(slider, "Icon标签");  
      119.  
      120.         mainWin.add(sliderBox, BorderLayout.CENTER);  
      121.         mainWin.add(showVal, BorderLayout.SOUTH);  
      122.         mainWin.pack();  
      123.         mainWin.setVisible(true);  
      124.  
      125.     }  
      126.     //定义一个方法,用于将滑动条添加到容器中  
      127.     public void addSlider(JSlider slider, String description)  
      128.     {          
      129.         slider.addChangeListener(listener);  
      130.         Box box = new Box(BoxLayout.X_AXIS);  
      131.         box.add(new JLabel(description + ":"));  
      132.         box.add(slider);  
      133.         sliderBox.add(box);  
      134.     }  
      135.  
      136.     public static void main(String[] args)  
      137.     {  
      138.         new TestJSlider().init();  
      139.     }  
      140. }