package org.esa.snap.rcp.colormanip; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.basic.BasicSliderUI; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; /** * The <code>SliderPanel</code> class contains the slider and input text field components. * * @author Jean Coravu */ class SliderPanel extends JPanel { private final ChangeListener localChangeListener; private final JSlider slider; private final JTextField input; private final ChangeListener sliderChangeListener; private final JLabel titleLabel; private int previousValue; /** * Constructs a new item. * * @param title the panel title * @param sliderChangeListener the slider listener */ SliderPanel(String title, ChangeListener sliderChangeListener) { super(new BorderLayout()); int maximumNumber = 100; this.sliderChangeListener = sliderChangeListener; this.previousValue = 0; this.titleLabel = new JLabel(title, JLabel.LEFT); this.titleLabel.setBorder(new EmptyBorder(0, 0, 0, 0)); this.slider = new JSlider(JSlider.HORIZONTAL, -maximumNumber, maximumNumber, this.previousValue); this.slider.setFocusable(false); this.slider.setMajorTickSpacing(maximumNumber); this.slider.setMinorTickSpacing(0); this.slider.setPaintTicks(true); this.slider.setPaintLabels(true); MouseListener[] listeners = this.slider.getMouseListeners(); for (int i=0; i<listeners.length; i++) { this.slider.removeMouseListener(listeners[i]); } final BasicSliderUI ui = (BasicSliderUI) this.slider.getUI(); BasicSliderUI.TrackListener trackListener = ui.new TrackListener() { @Override public void mouseClicked(MouseEvent event) { if (slider.isEnabled()) { Point mousePoint = event.getPoint(); int value = ui.valueForXPosition(mousePoint.x); slider.setValue(value); } } @Override public boolean shouldScroll(int direction) { return false; } }; this.slider.addMouseListener(trackListener); this.localChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent event) { sliderValueChanged(event); } }; this.slider.addChangeListener(this.localChangeListener); this.input = new JTextField(5); this.input.setDocument(new NumberPlainDocument(this.slider.getMinimum(), this.slider.getMaximum())); this.input.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent event) { if (event.getKeyCode() == KeyEvent.VK_ENTER) { int number = Integer.parseInt(input.getText()); slider.setValue(number); } } }); refreshInputValue(); JPanel panelInput = new JPanel(new FlowLayout()); panelInput.add(this.input); add(this.titleLabel, BorderLayout.WEST); add(this.slider, BorderLayout.CENTER); add(panelInput, BorderLayout.EAST); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); this.titleLabel.setEnabled(enabled); this.slider.setEnabled(enabled); this.input.setEnabled(enabled); } /** * Returns the preferred width of the title label. * * @return the preferred width of the title label */ public int getTitlePreferredWidth() { return this.titleLabel.getPreferredSize().width; } /** * Sets the preferred width of the title label. * * @param preferredWidth the width to set */ public void setTitlePreferredWidth(int preferredWidth) { Dimension size = this.titleLabel.getPreferredSize(); size.width = preferredWidth; this.titleLabel.setPreferredSize(size); } /** * Returns the slider maximum value. * * @return the slider maximum value */ public int getSliderMaximumValue() { return this.slider.getMaximum(); } /** * Returns the slider value. * * @return the slider value */ public int getSliderValue() { return this.slider.getValue(); } /** * Sets the slider value. * @param sliderValue the slider value */ public void setSliderValue(int sliderValue) { this.slider.removeChangeListener(this.localChangeListener); this.previousValue = sliderValue; this.slider.setValue(this.previousValue); refreshInputValue(); this.slider.addChangeListener(this.localChangeListener); } /** * Sets the slider value in the input text field. */ private void refreshInputValue() { String value = Integer.toString(this.slider.getValue()); this.input.setText(value); } /** * Fire the slider change event if the current slider value has changed. * @param event the slider change event */ private void sliderValueChanged(ChangeEvent event) { int currentSliderValue = slider.getValue(); if (!slider.getValueIsAdjusting() && currentSliderValue != previousValue) { previousValue = currentSliderValue; refreshInputValue(); sliderChangeListener.stateChanged(event); } } }