Preface:
有關 Java Swing Slider 的使用可以參考 "How to Use Sliders". 預設 Java Swing Slider 只提供一個方向的滑動. 一個 Swing Tutorial 的範例如下:
通常 Slider 上會有 Min/Max 的設定, 而上面的範例只能選擇由 Min~Max 間的某個值. 但如果我希望使用 Slider 來選擇的是一個 Range, 則可以參考這邊的範例代碼.
Description:
In order to create the range slider, we needed a new Swing component because the existing JSlider component only displays a single thumb to adjust the slider value. Interestingly, even though JSlider only allows you to update a single value, its data model actually provides support for two values; these define an internal range within the minimum and maximum bounds.
The internal range is defined by the slider value and an “extent,” which is the length of the inner range that begins at the slider value. In DefaultBoundedRangeModel, the default “extent” is zero and not normally used for anything. We can add it to the slider value to define an upper value of a selected range.
- /**
- * Sets the upper value in the range.
- */
- public void setUpperValue(int value) {
- // Compute new extent.
- int lowerValue = getValue();
- int newExtent = Math.min(Math.max(0, value - lowerValue), getMaximum() - lowerValue);
- // Set extent to set upper value.
- setExtent(newExtent);
- }
RangeSlider extends JSlider to install a UI delegate and provide value change methods. The methods set the lower and upper values in the selected range. We define the existing slider value as the lower value, and the upper value as the lower value plus the extent. To access these values, we override some methods, and add a couple of our own. This class do below three things:
- package proj.ui.cmp;
- import javax.swing.JSlider;
- public class RangeSlider extends JSlider{
- /**
- * Constructs a RangeSlider with default minimum and maximum values of 0
- * and 100.
- */
- public RangeSlider() {
- initSlider();
- }
- /**
- * Initializes the slider by setting default properties.
- */
- private void initSlider() {
- setOrientation(HORIZONTAL);
- }
- /**
- * Overrides the superclass method to install the UI delegate to draw two
- * thumbs.
- */
- @Override
- public void updateUI() {
- setUI(new RangeSliderUI(this));
- // Update UI for slider labels. This must be called after updating the
- // UI of the slider. Refer to JSlider.updateUI().
- updateLabelUIs();
- }
- /**
- * Returns the lower value in the range.
- */
- @Override
- public int getValue() {
- return super.getValue();
- }
- /**
- * Sets the lower value in the range.
- */
- @Override
- public void setValue(int value) {
- int oldValue = getValue();
- if (oldValue == value) {
- return;
- }
- // Compute new value and extent to maintain upper value.
- int oldExtent = getExtent();
- int newValue = Math.min(Math.max(getMinimum(), value), oldValue + oldExtent);
- int newExtent = oldExtent + oldValue - newValue;
- // Set new value and extent, and fire a single change event.
- getModel().setRangeProperties(newValue, newExtent, getMinimum(),
- getMaximum(), getValueIsAdjusting());
- }
- /**
- * Returns the upper value in the range.
- */
- public int getUpperValue() {
- return getValue() + getExtent();
- }
- /**
- * Sets the upper value in the range.
- */
- public void setUpperValue(int value) {
- // Compute new extent.
- int lowerValue = getValue();
- int newExtent = Math.min(Math.max(0, value - lowerValue), getMaximum() - lowerValue);
- // Set extent to set upper value.
- setExtent(newExtent);
- }
- }
Example Code:
- package proj.ui.cmp;
- import javax.swing.JLabel;
- public class DemoRange extends javax.swing.JFrame {
- private JLabel jLabelS;
- private RangeSlider jSliderBtm;
- private JLabel jLabelE;
- /**
- * Auto-generated main method to display this JFrame
- */
- public static void main(String[] args) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- DemoRange inst = new DemoRange();
- inst.setLocationRelativeTo(null);
- inst.setVisible(true);
- }
- });
- }
- public DemoRange() {
- super();
- initGUI();
- initSUI();
- }
- void initSUI()
- {
- /*Setup Maximum/Minimum and initialize start/end*/
- jSliderBtm.setMaximum(10);
- jSliderBtm.setMinimum(0);
- jSliderBtm.setValue(0);
- jSliderBtm.setUpperValue(10);
- }
- private void initGUI() {
- try {
- setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- getContentPane().setLayout(null);
- {
- jLabelS = new JLabel();
- getContentPane().add(jLabelS);
- jLabelS.setText("Start: 0");
- jLabelS.setBounds(7, 6, 365, 17);
- }
- {
- jLabelE = new JLabel();
- getContentPane().add(jLabelE);
- jLabelE.setText("End: 10");
- jLabelE.setBounds(7, 29, 365, 17);
- }
- {
- jSliderBtm = new RangeSlider();
- getContentPane().add(jSliderBtm);
- jSliderBtm.setBounds(7, 58, 365, 16);
- jSliderBtm.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent evt) {
- jSliderBtmStateChanged(evt);
- }
- });
- }
- pack();
- this.setSize(400, 150);
- } catch (Exception e) {
- //add your error handling code here
- e.printStackTrace();
- }
- }
- private void jSliderBtmStateChanged(ChangeEvent evt) {
- int lowerBnd = jSliderBtm.getValue();
- int highrBnd = jSliderBtm.getUpperValue();
- System.out.printf("%d~%d\n", lowerBnd, highrBnd);
- jLabelS.setText(String.format("Start: %d", lowerBnd));
- jLabelE.setText(String.format("End: %d", highrBnd));
- }
- }
沒有留言:
張貼留言