filebot/source/net/sourceforge/tuned/ui/SelectButton.java

271 lines
5.3 KiB
Java
Raw Normal View History

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.List;
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 = new ArrayList<T>(0);
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
private IconProvider<T> iconProvider = new NullIconProvider<T>();
private boolean hover = false;
public SelectButton() {
setContentAreaFilled(false);
setFocusable(false);
super.setIcon(selectIcon);
setHorizontalAlignment(SwingConstants.CENTER);
setVerticalAlignment(SwingConstants.CENTER);
setPreferredSize(new Dimension(32, 22));
addActionListener(new OpenPopupOnClick());
}
public void setModel(List<T> model) {
this.model = model;
setSelectedIndex(0);
}
public IconProvider<T> getIconProvider() {
return iconProvider;
}
public void setIconProvider(IconProvider<T> iconProvider) {
this.iconProvider = iconProvider;
// update icon
this.setIcon(iconProvider.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(iconProvider.getIcon(value));
firePropertyChange(SELECTED_VALUE, null, value);
}
}
public int getSelectedIndex() {
return selectionModel.getSelectedIndex();
}
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(value, iconProvider.getIcon(value));
if (value == getSelectedValue())
item.setSelected(true);
popup.add(item);
}
popup.show(SelectButton.this, -4, getHeight() - 5);
}
}
private class SelectPopupMenuItem extends JMenuItem implements ActionListener {
private final T value;
public SelectPopupMenuItem(T value, Icon icon) {
super(value.toString(), 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;
}
}
}