mirror of
https://gitlab.com/biskuteri-cafe/JKomasto2.git
synced 2024-11-20 05:14:50 +01:00
dacf58ac20
The UI needs to be easier on the eyes, I'm working on it
415 lines
9.5 KiB
Java
415 lines
9.5 KiB
Java
|
|
import javax.swing.AbstractButton;
|
|
import javax.swing.DefaultButtonModel;
|
|
import javax.swing.Icon;
|
|
import javax.swing.ImageIcon;
|
|
import java.awt.Image;
|
|
import java.awt.Graphics;
|
|
import java.awt.Dimension;
|
|
import java.awt.Shape;
|
|
import java.awt.geom.Ellipse2D;
|
|
import java.awt.event.MouseListener;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.KeyListener;
|
|
import java.awt.event.KeyEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.FocusListener;
|
|
import java.awt.event.FocusEvent;
|
|
import java.net.URL;
|
|
|
|
import javax.swing.JFrame;
|
|
|
|
class
|
|
TwoToggleButton extends AbstractButton
|
|
implements KeyListener, MouseListener, FocusListener {
|
|
|
|
private String
|
|
primaryName,
|
|
secondaryName;
|
|
|
|
// - -%- -
|
|
|
|
private boolean
|
|
primaryToggled = false,
|
|
secondaryToggled = false;
|
|
|
|
private Image
|
|
primaryToggledIcon,
|
|
secondaryToggledIcon,
|
|
primaryUntoggledIcon,
|
|
secondaryUntoggledIcon;
|
|
|
|
private int
|
|
nextEventID = ActionEvent.ACTION_FIRST;
|
|
|
|
// - -%- -
|
|
|
|
private static Image
|
|
button,
|
|
selectedOverlay,
|
|
disabledOverlay;
|
|
|
|
// ---%-@-%---
|
|
|
|
public void
|
|
togglePrimary()
|
|
{
|
|
setPrimaryToggled(!primaryToggled);
|
|
}
|
|
|
|
public void
|
|
toggleSecondary()
|
|
{
|
|
setSecondaryToggled(!secondaryToggled);
|
|
}
|
|
|
|
public void
|
|
setPrimaryToggled(boolean toggled)
|
|
{
|
|
primaryToggled = toggled;
|
|
repaint();
|
|
announce(primaryName, toggled);
|
|
}
|
|
|
|
public void
|
|
setSecondaryToggled(boolean toggled)
|
|
{
|
|
secondaryToggled = toggled;
|
|
repaint();
|
|
announce(secondaryName, toggled);
|
|
}
|
|
|
|
public boolean
|
|
getPrimaryToggled()
|
|
{
|
|
return primaryToggled;
|
|
}
|
|
|
|
public boolean
|
|
getSecondaryToggled()
|
|
{
|
|
return secondaryToggled;
|
|
}
|
|
|
|
// - -%- -
|
|
|
|
private void
|
|
announce(String name, boolean toggled)
|
|
{
|
|
ActionEvent eA = new ActionEvent(
|
|
this, nextEventID++,
|
|
name + (toggled ? "On" : "Off")
|
|
);
|
|
for (ActionListener listener: getActionListeners())
|
|
listener.actionPerformed(eA);
|
|
}
|
|
|
|
|
|
protected void
|
|
paintComponent(Graphics g)
|
|
{
|
|
g.drawImage(button, 0, 0, this);
|
|
if (!isEnabled())
|
|
g.drawImage(disabledOverlay, 0, 0, this);
|
|
if (isFocusOwner())
|
|
g.drawImage(selectedOverlay, 0, 0, this);
|
|
|
|
if (secondaryToggled)
|
|
g.drawImage(secondaryToggledIcon, 0, 0, this);
|
|
else
|
|
g.drawImage(secondaryUntoggledIcon, 0, 0, this);
|
|
if (primaryToggled)
|
|
g.drawImage(primaryToggledIcon, 0, 0, this);
|
|
else
|
|
g.drawImage(primaryUntoggledIcon, 0, 0, this);
|
|
}
|
|
|
|
|
|
public void
|
|
mouseClicked(MouseEvent eM)
|
|
{
|
|
switch (eM.getButton()) {
|
|
case MouseEvent.BUTTON1: togglePrimary(); break;
|
|
case MouseEvent.BUTTON3: toggleSecondary(); break;
|
|
}
|
|
requestFocusInWindow();
|
|
}
|
|
|
|
public void
|
|
keyPressed(KeyEvent eK)
|
|
{
|
|
switch (eK.getKeyCode()) {
|
|
case KeyEvent.VK_SPACE: togglePrimary(); break;
|
|
case KeyEvent.VK_ENTER: toggleSecondary(); break;
|
|
}
|
|
requestFocusInWindow();
|
|
}
|
|
|
|
public void
|
|
focusGained(FocusEvent eF) { repaint(); }
|
|
|
|
public void
|
|
focusLost(FocusEvent eF) { repaint(); }
|
|
|
|
|
|
public void
|
|
mousePressed(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseReleased(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseEntered(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseExited(MouseEvent eM) { }
|
|
|
|
public void
|
|
keyReleased(KeyEvent eK) { }
|
|
|
|
public void
|
|
keyTyped(KeyEvent eK) { }
|
|
|
|
// (悪) If we don't have the 'armed' behaviour of JButton,
|
|
// we really need to rectify that, it's important for this
|
|
// use case.
|
|
|
|
// ---%-@-%---
|
|
|
|
TwoToggleButton(String primaryName, String secondaryName)
|
|
{
|
|
if (button == null) loadCommonImages();
|
|
this.primaryName = primaryName;
|
|
this.secondaryName = secondaryName;
|
|
|
|
setModel(new DefaultButtonModel());
|
|
setFocusable(true);
|
|
setOpaque(false);
|
|
|
|
int w = button.getWidth(null);
|
|
int h = button.getHeight(null);
|
|
setPreferredSize(new Dimension(w, h));
|
|
loadSpecificImages();
|
|
|
|
this.addKeyListener(this);
|
|
this.addMouseListener(this);
|
|
this.addFocusListener(this);
|
|
}
|
|
|
|
private void
|
|
loadSpecificImages()
|
|
{
|
|
String p1 = "graphics/" + primaryName + "Toggled.png";
|
|
String p2 = "graphics/" + secondaryName + "Toggled.png";
|
|
String p3 = "graphics/" + primaryName + "Untoggled.png";
|
|
String p4 = "graphics/" + secondaryName + "Untoggled.png";
|
|
URL u1 = getClass().getResource(p1);
|
|
URL u2 = getClass().getResource(p2);
|
|
URL u3 = getClass().getResource(p3);
|
|
URL u4 = getClass().getResource(p4);
|
|
if (u1 == null) primaryToggledIcon = null;
|
|
else primaryToggledIcon = new ImageIcon(u1).getImage();
|
|
if (u2 == null) secondaryToggledIcon = null;
|
|
else secondaryToggledIcon = new ImageIcon(u2).getImage();
|
|
if (u3 == null) primaryUntoggledIcon = null;
|
|
else primaryUntoggledIcon = new ImageIcon(u3).getImage();
|
|
if (u4 == null) secondaryUntoggledIcon = null;
|
|
else secondaryUntoggledIcon = new ImageIcon(u4).getImage();
|
|
}
|
|
|
|
// - -%- -
|
|
|
|
private static void
|
|
loadCommonImages()
|
|
{
|
|
Class c = TwoToggleButton.class;
|
|
URL u1 = c.getResource("graphics/button.png");
|
|
URL u2 = c.getResource("graphics/disabledOverlay.png");
|
|
URL u3 = c.getResource("graphics/selectedOverlay.png");
|
|
assert u1 != null && u2 != null && u3 != null;
|
|
button = new ImageIcon(u1).getImage();
|
|
disabledOverlay = new ImageIcon(u2).getImage();
|
|
selectedOverlay = new ImageIcon(u3).getImage();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
class
|
|
RoundButton extends AbstractButton
|
|
implements KeyListener, MouseListener, FocusListener {
|
|
|
|
private Image
|
|
image;
|
|
|
|
// - -%- -
|
|
|
|
private int
|
|
nextEventID = ActionEvent.ACTION_FIRST;
|
|
|
|
// - -%- -
|
|
|
|
private static Image
|
|
button,
|
|
selectedOverlay,
|
|
disabledOverlay;
|
|
|
|
// ---%-@-%---
|
|
|
|
public void
|
|
setImage(Image n) { image = n; }
|
|
|
|
// - -%- -
|
|
|
|
protected void
|
|
paintComponent(Graphics g)
|
|
{
|
|
g.drawImage(button, 0, 0, this);
|
|
if (!isEnabled())
|
|
g.drawImage(disabledOverlay, 0, 0, this);
|
|
if (isFocusOwner())
|
|
g.drawImage(selectedOverlay, 0, 0, this);
|
|
|
|
if (image == null) return;
|
|
|
|
int w1 = button.getWidth(this);
|
|
int h1 = button.getHeight(this);
|
|
int w2 = image.getWidth(this);
|
|
int h2 = image.getHeight(this);
|
|
if (w2 == -1) w2 = w1;
|
|
if (h2 == -1) h2 = h1;
|
|
if (h2 > w2) {
|
|
h2 = h2 * w1 / w2;
|
|
w2 = w1;
|
|
}
|
|
else {
|
|
w2 = w2 * h1 / h2;
|
|
h2 = h1;
|
|
}
|
|
Shape defaultClip, roundClip;
|
|
defaultClip = g.getClip();
|
|
roundClip = new Ellipse2D.Float(6, 6, w1 - 12, h1 - 12);
|
|
|
|
g.setClip(roundClip);
|
|
g.drawImage(image, 0, 0, w2, h2, getParent());
|
|
// I don't know why, but when we repaint ourselves, our
|
|
// parent doesn't repaint, so nothing seems to happen.
|
|
g.setClip(defaultClip);
|
|
}
|
|
|
|
private void
|
|
announce()
|
|
{
|
|
ActionEvent eA = new ActionEvent(this, nextEventID++, null);
|
|
for (ActionListener listener: getActionListeners())
|
|
listener.actionPerformed(eA);
|
|
}
|
|
|
|
|
|
public void
|
|
keyPressed(KeyEvent eK)
|
|
{
|
|
if (eK.getKeyCode() != KeyEvent.VK_SPACE) return;
|
|
doClick();
|
|
}
|
|
|
|
public void
|
|
mouseClicked(MouseEvent eM) { announce(); }
|
|
|
|
public void
|
|
focusGained(FocusEvent eF) { repaint(); }
|
|
|
|
public void
|
|
focusLost(FocusEvent eF) { repaint(); }
|
|
|
|
|
|
public void
|
|
mousePressed(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseReleased(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseEntered(MouseEvent eM) { }
|
|
|
|
public void
|
|
mouseExited(MouseEvent eM) { }
|
|
|
|
public void
|
|
keyReleased(KeyEvent eK) { }
|
|
|
|
public void
|
|
keyTyped(KeyEvent eK) { }
|
|
|
|
// (悪) Again, armed?
|
|
|
|
// ---%-@-%---
|
|
|
|
RoundButton()
|
|
{
|
|
if (button == null) loadCommonImages();
|
|
|
|
setModel(new DefaultButtonModel());
|
|
setFocusable(true);
|
|
setOpaque(false);
|
|
|
|
int w = button.getWidth(this);
|
|
int h = button.getHeight(this);
|
|
setPreferredSize(new Dimension(w, h));
|
|
|
|
this.addKeyListener(this);
|
|
this.addMouseListener(this);
|
|
this.addFocusListener(this);
|
|
}
|
|
|
|
// - -%- -
|
|
|
|
private static void
|
|
loadCommonImages()
|
|
{
|
|
Class c = TwoToggleButton.class;
|
|
URL u1 = c.getResource("graphics/button.png");
|
|
URL u2 = c.getResource("graphics/disabledOverlay.png");
|
|
URL u3 = c.getResource("graphics/selectedOverlay.png");
|
|
assert u1 != null && u2 != null && u3 != null;
|
|
button = new ImageIcon(u1).getImage();
|
|
disabledOverlay = new ImageIcon(u2).getImage();
|
|
selectedOverlay = new ImageIcon(u3).getImage();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
class
|
|
TwoToggleButtonTest {
|
|
|
|
public static void
|
|
main(String... args)
|
|
{
|
|
if (args.length != 2)
|
|
{
|
|
String err = "Please give two toggle names.";
|
|
System.err.println(err);
|
|
System.exit(1);
|
|
}
|
|
|
|
String p = args[0], s = args[1];
|
|
TwoToggleButton t1 = new TwoToggleButton(p, s);
|
|
TwoToggleButton t2 = new TwoToggleButton(p, s);
|
|
TwoToggleButton t3 = new TwoToggleButton(p, s);
|
|
|
|
JFrame mainframe = new JFrame("Two-toggle button test");
|
|
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
mainframe.setLocationByPlatform(true);
|
|
mainframe.add(t1, java.awt.BorderLayout.WEST);
|
|
mainframe.add(t2);
|
|
mainframe.add(t3, java.awt.BorderLayout.EAST);
|
|
mainframe.pack();
|
|
t2.setEnabled(false);
|
|
t3.requestFocusInWindow();
|
|
mainframe.setVisible(true);
|
|
}
|
|
|
|
}
|