Slider+ArrowButton(和Slider+Spinner)同步更新
Slider+ArrowButton(和Slider+Spinner)同步更新
1、Slider + ArrowButton 同步更新
实现一个竖直的slider,
extends BasicSliderUI,
slider = new JSlider(JSlider.VERTICAL, 0, 200, 0);
上下各加一个箭头,点击箭头可实现slider的更新,同时在slider上点击,也可实现更新
可加一个JTextArea sliderText,显示slider和箭头按钮的同步更新。
class CustomSliderUI extends BasicSliderUI
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package SliderandArrowButton;import java.awt.BorderLayout;import java.awt.Component;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.DefaultListCellRenderer;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JSlider;import javax.swing.JTextArea;import javax.swing.SwingConstants;import javax.swing.UIManager;import javax.swing.border.Border;import javax.swing.border.CompoundBorder;import javax.swing.plaf.basic.BasicArrowButton;import javax.swing.plaf.basic.BasicSliderUI;import static javax.swing.plaf.basic.BasicSliderUI.NEGATIVE_SCROLL;import static javax.swing.plaf.basic.BasicSliderUI.POSITIVE_SCROLL;/** * * @author Administrator */public class CustomSliderUI extends BasicSliderUI { static JTextArea sliderText = new JTextArea(); static int step = 1; public CustomSliderUI(JSlider b) { super(b); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setLayout(new FlowLayout()); final JSlider slider = new JSlider(JSlider.VERTICAL, 0, 200, 0); // 1/10// slider.setPaintTicks(true);// slider.setPaintLabels(true); // slider.setMinorTickSpacing(5); //set the step// slider.setMajorTickSpacing(25); slider.setUI(new CustomSliderUI(slider)); slider.setPreferredSize(new Dimension(20, 200)); sliderText.setText(String.valueOf(slider.getValue())); slider.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { sliderText.setText(String.valueOf(slider.getValue())); } }); JPanel sliderPanel = new JPanel(new BorderLayout()); JButton northButton = (JButton) createTheArrowButton(SwingConstants.NORTH, "north"); JButton southButton = (JButton) createTheArrowButton(SwingConstants.SOUTH, "south"); sliderPanel.add(northButton, BorderLayout.NORTH); sliderPanel.add(southButton, BorderLayout.SOUTH); sliderPanel.add(slider, BorderLayout.CENTER); northButton.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int lastValue = slider.getValue(); slider.getModel().setValue(lastValue + step); sliderText.setText(String.valueOf(slider.getValue())); } }); southButton.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int lastValue = slider.getValue(); slider.getModel().setValue(lastValue - step); sliderText.setText(String.valueOf(slider.getValue())); } }); frame.add(sliderPanel); frame.add(sliderText); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } /* * 创建三角形的箭头,由direction设置箭头方向 */ private static Component createTheArrowButton(int direction, String name) { JButton b = new BasicArrowButton(direction); b.setName(name); Border buttonBorder = UIManager.getBorder("Spinner.arrowButtonBorder"); if (buttonBorder instanceof DefaultListCellRenderer.UIResource) { b.setBorder(new CompoundBorder(buttonBorder, null)); } else { b.setBorder(buttonBorder); } b.setInheritsPopupMenu(true); b.setPreferredSize(new Dimension(20, 20)); return b; } /* * 设置在slider上点击,一次跳动多少,如 * blockIncrement =(slider.getMaximum() - slider.getMinimum()) / 20; * 也可 int blockIncrement = 1; */ @Override public void scrollByBlock(int direction) { synchronized (slider) { int blockIncrement = (slider.getMaximum() - slider.getMinimum()) / 20;// int blockIncrement = 1; if (blockIncrement == 0) { blockIncrement = 1; } if (slider.getSnapToTicks()) { int tickSpacing = getTickSpacing(); if (blockIncrement < tickSpacing) { blockIncrement = tickSpacing; } } int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); slider.setValue(slider.getValue() + delta); } } int getTickSpacing() { int majorTickSpacing = slider.getMajorTickSpacing(); int minorTickSpacing = slider.getMinorTickSpacing(); int result; if (minorTickSpacing > 0) { result = minorTickSpacing; } else if (majorTickSpacing > 0) { result = majorTickSpacing; } else { result = 0; } return result; }}
2、Slider + Spinner 同步更新
实现Spinner与Slider的同步更新,
Spinner和Slider都是竖直的
2.1、Spinner:
通过 SpinnerNumberModel构造spinnerModel,然后通过spinnerModel构造JSpinner;
spinnerModel = new SpinnerNumberModel(0, 0, 10, 0.1);
pinner = new JSpinner(spinnerModel);
2.2、Slider
写一个类:private class SliderModel extends DefaultBoundedRangeModel
(A slider model which keeps in consistent with a Spinner's number model.)
通过spinnerModel 构造Slider 的model
再在Slider上添加鼠标点击事件,改变model
改变model时,spinner直接添加ChangeListener实现同步: spinner.addChangeListener(sliderPanel.this);
public class sliderPanel implements ChangeListener:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package newslidertest;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.BorderFactory;import javax.swing.DefaultBoundedRangeModel;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JSlider;import javax.swing.JSpinner;import javax.swing.SpinnerNumberModel;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;/** * * @author Administrator */public class sliderPanel implements ChangeListener { JPanel mPanel = new JPanel(); JFrame mFrame; SpinnerNumberModel spinnerModel; JSpinner spinner; JSlider slider; public static boolean isImmediateSimulation = false; public final static int SPINNER_WIDTH = 108; public final static int SPINNER_HEIGHT = 60; public sliderPanel() { JFrame mJFrame = new JFrame(); mJFrame.setLayout(new BorderLayout()); mJFrame.setBounds(200, 300, 350, 280); mJFrame.add(initComponents(), BorderLayout.CENTER); mJFrame.setTitle("slider"); mJFrame.setVisible(true); mJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private JPanel initComponents() {// spinnerModel = getSpinnerModel(); spinnerModel = new SpinnerNumberModel(0, 0, 10, 0.1); spinner = new JSpinner(spinnerModel); final SliderModel model = new SliderModel(spinnerModel); slider = new JSlider(JSlider.VERTICAL); slider.setModel(model); spinner.addChangeListener(sliderPanel.this); slider.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (isImmediateSimulation) { model.setMode(SliderModel.SLIDE_MODE_SYNC); } else { model.setMode(SliderModel.SLIDE_MODE_NON_SYNC); } } @Override public void mouseReleased(MouseEvent e) { model.setMode(SliderModel.SLIDE_MODE_SYNC); if (!isImmediateSimulation) { //set current value to spinner model model.setValue(model.getValue()); } } }); mPanel.setLayout(new FlowLayout()); mPanel.add(slider); mPanel.add(spinner); mPanel.setPreferredSize(new Dimension(SPINNER_WIDTH, SPINNER_HEIGHT)); mPanel.setBorder(BorderFactory.createEmptyBorder()); return mPanel; } private SpinnerNumberModel getSpinnerModel() { double value = 0; double min = -10; double max = 10; double step = 0.1;// value = (double) spinnerModel.getValue();// Bound bound = param.getSoftBound();// min = bound.getMin();// max = bound.getMax();// step = param.getStep(); return new SpinnerNumberModel(value, min, max, step); } @Override public void stateChanged(ChangeEvent event) { Double value = (Double) spinnerModel.getValue(); Double min = (Double) spinnerModel.getMinimum(); Double max = (Double) spinnerModel.getMaximum(); SliderModel sliderModel = (SliderModel) slider.getModel(); int sliderMin = sliderModel.getMinimum(); int sliderMax = sliderModel.getMaximum(); int sliderValue = (int) (sliderMin + ((value.doubleValue() - min.doubleValue()) / (max .doubleValue() - min.doubleValue())) * (sliderMax - sliderMin)); //no need to set back to spinner model, so set the flag first int oldMode = sliderModel.getMode(); sliderModel.setMode(SliderModel.SLIDE_MODE_NON_SYNC); try { sliderModel.setValue(sliderValue); } finally { sliderModel.setMode(oldMode); } } /** * A slider model which keeps in consistent with a Spinner's number model. */ private class SliderModel extends DefaultBoundedRangeModel { private static final long serialVersionUID = 1L; public final static int SLIDE_MODE_SYNC = 0; public final static int SLIDE_MODE_NON_SYNC = 1; int mode = SLIDE_MODE_SYNC; SpinnerNumberModel spinnerModel = null; int sliderValue = 0; public SliderModel(SpinnerNumberModel spinnerModel) { this.spinnerModel = spinnerModel; initValue(); } final void initValue() { Double value = (Double) spinnerModel.getValue(); Double min = (Double) spinnerModel.getMinimum(); Double max = (Double) spinnerModel.getMaximum(); int sliderMin = getMinimum(); int sliderMax = getMaximum(); sliderValue = (int) (sliderMin + ((value.doubleValue() - min.doubleValue()) / (max .doubleValue() - min.doubleValue())) * (sliderMax - sliderMin)); } public void setMode(int mode) { this.mode = mode; } public int getMode() { return mode; } @Override public int getValue() { return sliderValue; } @Override public void setValue(int n) { sliderValue = n; if (mode != SLIDE_MODE_NON_SYNC) { spinnerModel.removeChangeListener(sliderPanel.this); try { Double min = (Double) spinnerModel.getMinimum(); Double max = (Double) spinnerModel.getMaximum(); int myMin = getMinimum(); int myMax = getMaximum(); double value = (((double) (n - myMin) / (myMax - myMin)) * (max .doubleValue() - min.doubleValue())) + min.doubleValue(); spinnerModel.setValue(new Double(value)); } finally { spinnerModel.addChangeListener(sliderPanel.this); } } super.setValue(n); } } public static void main(String[] args) { sliderPanel msliderPanel = new sliderPanel(); }}