Java Swing编程:进度条和滑动条

时间:2022-03-28 11:08:13

前几天讲了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.     }  

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.     }  

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

滑动条和进度条差不多,他们共用一个模型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(0new JLabel("A"));  
  92.         labelTable.put(20new JLabel("B"));  
  93.         labelTable.put(40new JLabel("C"));  
  94.         labelTable.put(60new JLabel("D"));  
  95.         labelTable.put(80new JLabel("E"));  
  96.         labelTable.put(100new 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(0new JLabel(new ImageIcon("ico/0.GIF")));  
  112.         labelTable.put(20new JLabel(new ImageIcon("ico/2.GIF")));  
  113.         labelTable.put(40new JLabel(new ImageIcon("ico/4.GIF")));  
  114.         labelTable.put(60new JLabel(new ImageIcon("ico/6.GIF")));  
  115.         labelTable.put(80new 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.     }