6593bfdbda
* refactoring / cleanup
281 lines
5.6 KiB
Java
281 lines
5.6 KiB
Java
|
|
package net.sourceforge.tuned.ui;
|
|
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Component;
|
|
import java.awt.Dimension;
|
|
import java.awt.Font;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Insets;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.geom.GeneralPath;
|
|
import java.awt.geom.Path2D;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.DefaultSingleSelectionModel;
|
|
import javax.swing.Icon;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JMenuItem;
|
|
import javax.swing.JPopupMenu;
|
|
import javax.swing.SingleSelectionModel;
|
|
import javax.swing.SwingConstants;
|
|
|
|
|
|
public class SelectButton<T> extends JButton {
|
|
|
|
public static final String SELECTED_VALUE = "selected value";
|
|
|
|
private final Color beginColor = new Color(0xF0EEE4);
|
|
private final Color endColor = new Color(0xE0DED4);
|
|
|
|
private final Color beginColorHover = beginColor;
|
|
private final Color endColorHover = new Color(0xD8D7CD);
|
|
|
|
private final SelectIcon selectIcon = new SelectIcon();
|
|
|
|
private List<T> model = Collections.emptyList();
|
|
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
|
|
|
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
|
|
|
private boolean hover = false;
|
|
|
|
|
|
public SelectButton() {
|
|
setContentAreaFilled(false);
|
|
setFocusable(false);
|
|
|
|
super.setIcon(selectIcon);
|
|
|
|
setHorizontalAlignment(SwingConstants.CENTER);
|
|
setVerticalAlignment(SwingConstants.CENTER);
|
|
|
|
setBorder(BorderFactory.createLineBorder(new Color(0xA4A4A4), 1));
|
|
setPreferredSize(new Dimension(32, 22));
|
|
|
|
addActionListener(new OpenPopupOnClick());
|
|
}
|
|
|
|
|
|
public void setModel(Collection<T> model) {
|
|
this.model = new ArrayList<T>(model);
|
|
|
|
setSelectedIndex(0);
|
|
}
|
|
|
|
|
|
public LabelProvider<T> getLabelProvider() {
|
|
return labelProvider;
|
|
}
|
|
|
|
|
|
public void setLabelProvider(LabelProvider<T> labelProvider) {
|
|
this.labelProvider = labelProvider;
|
|
|
|
// update icon
|
|
this.setIcon(labelProvider.getIcon(getSelectedValue()));
|
|
}
|
|
|
|
|
|
@Override
|
|
public void setIcon(Icon icon) {
|
|
selectIcon.setInnerIcon(icon);
|
|
repaint();
|
|
}
|
|
|
|
|
|
public void setSelectedValue(T value) {
|
|
setSelectedIndex(model.indexOf(value));
|
|
}
|
|
|
|
|
|
public T getSelectedValue() {
|
|
if (!selectionModel.isSelected())
|
|
return null;
|
|
|
|
return model.get(selectionModel.getSelectedIndex());
|
|
}
|
|
|
|
|
|
public void setSelectedIndex(int i) {
|
|
if (i < 0 || i >= model.size()) {
|
|
selectionModel.clearSelection();
|
|
setIcon(null);
|
|
return;
|
|
}
|
|
|
|
if (i != selectionModel.getSelectedIndex()) {
|
|
selectionModel.setSelectedIndex(i);
|
|
|
|
T value = model.get(i);
|
|
|
|
setIcon(labelProvider.getIcon(value));
|
|
|
|
firePropertyChange(SELECTED_VALUE, null, value);
|
|
}
|
|
}
|
|
|
|
|
|
public int getSelectedIndex() {
|
|
return selectionModel.getSelectedIndex();
|
|
}
|
|
|
|
|
|
public SingleSelectionModel getSelectionModel() {
|
|
return selectionModel;
|
|
}
|
|
|
|
|
|
public void spinValue(int spin) {
|
|
int size = model.size();
|
|
|
|
spin = spin % size;
|
|
|
|
int next = getSelectedIndex() + spin;
|
|
|
|
if (next < 0)
|
|
next += size;
|
|
else if (next >= size)
|
|
next -= size;
|
|
|
|
setSelectedIndex(next);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void paintComponent(Graphics g) {
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
if (hover)
|
|
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(getBounds(), beginColorHover, endColorHover));
|
|
else
|
|
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(getBounds(), beginColor, endColor));
|
|
|
|
g2d.fill(getBounds());
|
|
|
|
super.paintComponent(g);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void processMouseEvent(MouseEvent e) {
|
|
switch (e.getID()) {
|
|
case MouseEvent.MOUSE_ENTERED:
|
|
hover = true;
|
|
repaint();
|
|
break;
|
|
case MouseEvent.MOUSE_EXITED:
|
|
hover = false;
|
|
repaint();
|
|
break;
|
|
}
|
|
|
|
super.processMouseEvent(e);
|
|
}
|
|
|
|
|
|
private class OpenPopupOnClick implements ActionListener {
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
JPopupMenu popup = new JPopupMenu();
|
|
|
|
for (T value : model) {
|
|
SelectPopupMenuItem item = new SelectPopupMenuItem(labelProvider.getText(value), labelProvider.getIcon(value), value);
|
|
|
|
if (value == getSelectedValue())
|
|
item.setSelected(true);
|
|
|
|
popup.add(item);
|
|
}
|
|
|
|
popup.show(SelectButton.this, 0, getHeight() - 1);
|
|
}
|
|
}
|
|
|
|
|
|
private class SelectPopupMenuItem extends JMenuItem implements ActionListener {
|
|
|
|
private final T value;
|
|
|
|
|
|
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
|
super(text, icon);
|
|
|
|
this.value = value;
|
|
|
|
setMargin(new Insets(3, 0, 3, 0));
|
|
addActionListener(this);
|
|
}
|
|
|
|
|
|
@Override
|
|
public void setSelected(boolean selected) {
|
|
setFont(getFont().deriveFont(selected ? Font.BOLD : Font.PLAIN));
|
|
}
|
|
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
setSelectedValue(value);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private static class SelectIcon implements Icon {
|
|
|
|
private final GeneralPath arrow;
|
|
|
|
private Icon icon;
|
|
|
|
|
|
public SelectIcon() {
|
|
arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
|
|
int x = 25;
|
|
int y = 10;
|
|
|
|
arrow.moveTo(x - 2, y);
|
|
arrow.lineTo(x, y + 3);
|
|
arrow.lineTo(x + 3, y);
|
|
arrow.lineTo(x - 2, y);
|
|
}
|
|
|
|
|
|
public void setInnerIcon(Icon icon) {
|
|
this.icon = icon;
|
|
}
|
|
|
|
|
|
public void paintIcon(Component c, Graphics g, int x, int y) {
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
if (icon != null) {
|
|
icon.paintIcon(c, g2d, 4, 3);
|
|
}
|
|
|
|
g2d.setPaint(Color.BLACK);
|
|
g2d.fill(arrow);
|
|
}
|
|
|
|
|
|
public int getIconWidth() {
|
|
return 30;
|
|
}
|
|
|
|
|
|
public int getIconHeight() {
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
}
|