/* * Copyright 2017 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.gui.utils; import pixelitor.utils.IconUtils; import javax.swing.*; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * A textfield with a drop down button that shows a slider in a popup window */ public class DropDownSlider extends JComponent { private static final Icon downIconEnabled = IconUtils.loadIcon("dropdown_enabled.gif"); private static final Icon downIconDisabled = IconUtils.loadIcon("dropdown_disabled.gif"); private final IntTextField textField; private JButton dropDownButton; private final JPopupMenu popupMenu; private boolean dropDownEnabled = true; private final JSlider slider; public DropDownSlider(int value, int minValue, int maxValue, boolean limitRange) { setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); textField = new IntTextField(String.valueOf(value), minValue, maxValue, limitRange, 4); add(textField); initDropDownButton(); textField.add(dropDownButton); slider = new JSlider(JSlider.HORIZONTAL, minValue, maxValue, value); popupMenu = new JPopupMenu(); popupMenu.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 1)); popupMenu.add(slider); connectSlideAndTextField(); } private void initDropDownButton() { dropDownButton = new JButton(downIconEnabled); dropDownButton.setDisabledIcon(downIconDisabled); dropDownButton.putClientProperty("JComponent.sizeVariant", "mini"); dropDownButton.setRequestFocusEnabled(false); dropDownButton.setInheritsPopupMenu(true); dropDownButton.setBorderPainted(false); dropDownButton.setFocusPainted(false); dropDownButton.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { dropDown(); } @Override public void mouseEntered(MouseEvent e) { dropDownButton.setBorderPainted(true); } @Override public void mouseExited(MouseEvent e) { dropDownButton.setBorderPainted(false); } }); dropDownButton.setIconTextGap(0); dropDownButton.setBorder(null); dropDownButton.setMargin(new Insets(0, 0, 0, 0)); setDropDownButtonSize(); } private void setDropDownButtonSize() { Dimension ps = textField.getPreferredSize(); int width = 17; int height = 22; int boundsX = ps.width - width; int boundsY = (ps.height - height) / 2; dropDownButton.setBounds(boundsX, boundsY, width, height); // Works only for the Nimbus L&F } private void connectSlideAndTextField() { slider.addChangeListener(e -> { int value1 = slider.getValue(); textField.setText(String.valueOf(value1)); if (!slider.getValueIsAdjusting()) { textField.fireActionPerformed(); } }); textField.addActionListener(e -> { int value1 = textField.getIntValue(); int sliderValue = slider.getValue(); if (value1 != sliderValue) { slider.setValue(value1); } }); } public int getValue() { return textField.getIntValue(); } public void setValue(int newValue) { textField.setText(String.valueOf(newValue)); slider.setValue(newValue); } public void addActionListener(ActionListener listener) { textField.addActionListener(listener); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); textField.setEnabled(enabled); dropDownButton.setEnabled(enabled); dropDownEnabled = enabled; } private void dropDown() { if (dropDownEnabled) { if (popupMenu.isShowing()) { popupMenu.setVisible(false); } else { Dimension size = getSize(); Dimension preferredSize = popupMenu.getPreferredSize(); popupMenu.show(this, size.width - preferredSize.width, size.height); } } } public void setTFName(String name) { textField.setName(name); } }