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