CaRMtl/rene/gui/IconBar.java

1796 lines
39 KiB
Java
Raw Normal View History

/*
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
This file is part of C.a.R. software.
C.a.R. is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
C.a.R. 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package rene.gui;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JDialog;
import eric.JEricPanel;
class SaveColor extends Color {
/**
*
*/
private static final long serialVersionUID = 1L;
public SaveColor(final int red, final int green, final int blue) {
super(red > 0 ? red : 0, green > 0 ? green : 0, blue > 0 ? blue : 0);
}
}
/**
* These are the common things to Separators and Incons.
*/
interface IconBarElement {
public int width();
public void setPosition(int x, int y);
public Point getPosition();
public void setEnabled(boolean flag);
public String getName();
}
/**
* A simple separator between icons.
*/
class Separator extends JEricPanel implements IconBarElement {
/**
*
*/
private static final long serialVersionUID = 1L;
final int Size = 6;
public Separator(final IconBar bar) {
if (bar.Vertical)
setSize(BasicIcon.Size, Size);
else
setSize(Size, BasicIcon.Size);
}
public int width() {
return Size;
}
public void setPosition(final int x, final int y) {
setLocation(x, y);
}
public Point getPosition() {
return new Point(0, 0);
}
@Override
public void setEnabled(final boolean flag) {
}
@Override
public String getName() {
return "";
}
@Override
public void paint(final Graphics g) {
g.setColor(getBackground());
if (Global.getParameter("iconbar.showseparators", false))
g
.fill3DRect(1, 1, getSize().width - 1,
getSize().height - 1, false);
else
g.fillRect(1, 1, getSize().width - 1, getSize().height - 1);
}
}
/**
* @author Rene This is the most basic icon, handling mouse presses and display
* in activated, pressed, unset or disabled state.
*/
class BasicIcon extends JEricPanel implements MouseListener, IconBarElement,
Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
IconBar Bar;
String Name;
boolean Enabled; // Icon cannot be changed by user action.
boolean On; // On or off are the basic stated of icons.
boolean Focus = false;
public static int Size = 22; // the size of icons
boolean MouseOver, MouseDown; // for display states during mouse action
boolean Unset; // Unknown State!
public BasicIcon(final IconBar bar, final String name) {
Bar = bar;
Name = name;
Enabled = true;
On = false;
addMouseListener(this);
enableEvents(AWTEvent.KEY_EVENT_MASK);
setSize(Size, Size);
}
@Override
public void processKeyEvent(final KeyEvent e) {
Bar.getKey(e);
}
/**
* Paint a button with an image
*/
@Override
public void paintComponent(final Graphics g) {
if (MouseDown) {
g.setColor(getBackground());
g.fill3DRect(0, 0, Size, Size, false);
} else {
if (MouseOver) {
if (On) {
final Color c = getBackground();
g.setColor(new SaveColor(c.getRed() - 30,
c.getGreen() - 30, c.getBlue()));
} else
g.setColor(getBackground());
g.fill3DRect(0, 0, Size, Size, true);
} else {
if (On) {
final Color c = getBackground();
g.setColor(c);
g.fillRect(0, 0, Size, Size);
g.setColor(new SaveColor(c.getRed() - 100,
c.getGreen() - 100, c.getBlue()));
g.fillRect(3, 3, Size - 2, Size - 2);
g.setColor(new SaveColor(c.getRed() - 50,
c.getGreen() - 50, c.getBlue()));
g.fillRect(1, 1, Size - 2, Size - 2);
} else {
g.setColor(getBackground());
g.fillRect(0, 0, Size, Size);
}
}
}
dopaint(g);
if (Unset) {
final Color c = getBackground();
g.setColor(new SaveColor(c.getRed() - 100, c.getGreen(), c
.getBlue()));
g.drawLine(0, 0, Size, Size);
}
if (Focus)
showFocus(g);
}
public void showFocus(final Graphics g) {
g.setColor(Color.white);
g.drawRect(4, 4, 1, 1);
g.drawRect(Size - 5, 4, 1, 1);
g.drawRect(4, Size - 5, 1, 1);
g.drawRect(Size - 5, Size - 5, 1, 1);
}
public void dopaint(final Graphics g) {
}
//
@Override
public void update(final Graphics g) {
paintComponent(g);
}
/**
* User pressed the mouse key over this button.
*/
public void mousePressed(final MouseEvent e) {
if (!Enabled)
return;
MouseDown = true;
repaint();
}
/**
* User released the mouse key again.
*/
public void mouseReleased(final MouseEvent e) {
if (!Enabled)
return;
MouseDown = false;
final Dimension d = getSize();
if (e.getX() < 0 || e.getX() > d.width || e.getY() < 0
|| e.getY() > d.height) {
repaint();
return;
}
Unset = false;
pressed(e); // call method for children to change states etc.
repaint();
T = null; // stop icon help thread
// Notify Iconbar about activation:
long time = System.currentTimeMillis();
Bar.iconPressed(Name, e.isShiftDown(), e.isControlDown());
// Necessary, since Java 1.4 does not report
// MouseExited, if a modal dialog is active:
time = System.currentTimeMillis() - time;
if (MouseOver && time > 1000) {
MouseOver = false;
repaint();
}
}
/**
* Overwrite for children!
*
* @param e
* Mouse event for determining right button etc.
*/
public void pressed(final MouseEvent e) {
}
public void mouseClicked(final MouseEvent e) {
}
Thread T;
boolean Control;
/**
* Start a thread, that waits for one second, then tells the icon bar to
* display the proper help text.
*/
public synchronized void mouseEntered(final MouseEvent e) {
if (T != null)
return;
if (Enabled)
MouseOver = true;
repaint();
if (!Global.getParameter("iconbar.showtips", true))
return;
Control = e.isControlDown();
T = new Thread(this);
T.start();
}
/**
* A thread to display an icon help.
*/
public void run() {
try {
Thread.sleep(1000);
} catch (final Exception e) {
}
if (T != null) {
synchronized (this) {
try {
getLocationOnScreen();
String help = Global.name("iconhelp." + Name, "");
if (help.equals("") && Name.length() > 1) {
help = Global.name("iconhelp."
+ Name.substring(0, Name.length() - 1) + "?",
"");
}
if (help.equals(""))
help = Bar.getHelp(Name);
if (help.equals(""))
help = Global.name("iconhelp.nohelp",
"No help available");
if (Control) {
final String hc = Global.name("iconhelp.control."
+ Name, "");
if (!hc.equals(""))
help = hc;
}
Bar.displayHelp(this, help);
} catch (final Exception e) {
}
}
try {
Thread.sleep(5000);
} catch (final Exception e) {
}
if (T != null)
Bar.removeHelp();
T = null;
}
}
/**
* Tell the run method, that display is no longer necessary, and remove the
* help text.
*/
public synchronized void mouseExited(final MouseEvent e) {
T = null;
MouseOver = false;
repaint();
Bar.removeHelp();
}
// for the IconBarElement interface
public int width() {
return Size;
}
public void setPosition(final int x, final int y) {
setLocation(x, y);
}
public Point getPosition() {
return getLocationOnScreen();
}
@Override
public void setEnabled(final boolean flag) {
if (Enabled == flag)
return;
Enabled = flag;
repaint();
}
@Override
public String getName() {
return Name;
}
@Override
public boolean hasFocus() {
return Focus;
}
public void setFocus(final boolean flag) {
Focus = flag;
repaint();
}
// needs to be removed:
public boolean isSet() {
return !Unset;
}
public void unset(final boolean flag) {
Unset = flag;
}
public void unset() {
unset(true);
}
}
/**
* @author Rene A primitive icon that displays a GIF image.
*/
class IconWithGif extends BasicIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
Image I;
Color C;
int W, H, X, Y;
/**
* Initialize the icon and load its image. By changing the global parameter
* "icontype", png can be used too.
*/
public IconWithGif(final IconBar bar, String file) {
super(bar, file);
final String iconfile = getDisplay(file);
if (!iconfile.equals(""))
file = iconfile;
try {
final InputStream in = getClass().getResourceAsStream(
Bar.Resource + file + "."
+ Global.getParameter("icontype", "gif"));
int pos = 0;
int n = in.available();
final byte b[] = new byte[20000];
while (n > 0) {
final int k = in.read(b, pos, n);
if (k < 0)
break;
pos += k;
n = in.available();
}
in.close();
I = Toolkit.getDefaultToolkit().createImage(b, 0, pos);
final MediaTracker T = new MediaTracker(bar);
T.addImage(I, 0);
T.waitForAll();
} catch (final Exception e) {
try {
I = getToolkit().getImage(
file + "." + Global.getParameter("icontype", "gif"));
final MediaTracker mt = new MediaTracker(this);
mt.addImage(I, 0);
mt.waitForID(0);
if (!(mt.checkID(0) && !mt.isErrorAny()))
throw new Exception("");
} catch (final Exception ex) {
I = null;
return;
}
}
W = I.getWidth(this);
H = I.getHeight(this);
X = Size / 2 - W / 2;
Y = Size / 2 - H / 2;
}
public String getDisplay(final String name) {
if (!name.endsWith(")"))
return "";
final int n = name.lastIndexOf('(');
if (n < 0)
return "";
return name.substring(n + 1, name.length() - 1);
}
public IconWithGif(final IconBar bar, final String name, final Color color) {
super(bar, name);
C = color;
}
@Override
public void dopaint(final Graphics g) {
if (I != null) {
if (W > getSize().width)
g.drawImage(I, 1, 1, Size - 2, Size - 2, this);
else
g.drawImage(I, X, Y, this);
} else if (C != null) {
g.setColor(C);
g.fillRect(3, 3, Size - 6, Size - 6);
} else {
g.setFont(new Font("Courier", Font.BOLD, Size / 3));
final FontMetrics fm = getFontMetrics(getFont());
String s = getDisplay(Name);
if (s.length() > 3)
s = s.substring(0, 3);
final int w = fm.stringWidth(s);
final int h = fm.getHeight();
g.setColor(this.getForeground());
final Graphics2D G = (Graphics2D) g;
G.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
G
.drawString(s, Size / 2 - w / 2, Size / 2 - h / 2
+ fm.getAscent());
}
}
}
/**
* @author Rene A primitive icon that displays one of several GIF images.
*/
class MultipleIcon extends BasicIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
int N;
Image I[];
int Selected;
int X[], Y[], W[], H[];
public MultipleIcon(final IconBar bar, final String name, final int number) {
super(bar, name);
N = number;
I = new Image[N];
X = new int[N];
Y = new int[N];
W = new int[N];
H = new int[N];
final MediaTracker T = new MediaTracker(bar);
try {
for (int i = 0; i < N; i++) {
try {
final InputStream in = getClass().getResourceAsStream(
Bar.Resource + name + i + "."
+ Global.getParameter("icontype", "gif"));
int pos = 0;
int n = in.available();
final byte b[] = new byte[20000];
while (n > 0) {
final int k = in.read(b, pos, n);
if (k < 0)
break;
pos += k;
n = in.available();
}
in.close();
I[i] = Toolkit.getDefaultToolkit().createImage(b, 0, pos);
T.addImage(I[i], i);
} catch (final Exception e) {
I[i] = null;
}
}
T.waitForAll();
for (int i = 0; i < N; i++) {
W[i] = I[i].getWidth(this);
H[i] = I[i].getHeight(this);
X[i] = Size / 2 - W[i] / 2;
Y[i] = Size / 2 - H[i] / 2;
}
} catch (final Exception e) {
for (int i = 0; i < N; i++)
I[i] = null;
}
}
public MultipleIcon(final IconBar bar, final String name) {
super(bar, name);
Selected = 0;
}
/**
* Paint a button with an image
*/
@Override
public void dopaint(final Graphics g) {
if (I[Selected] != null) {
if (W[Selected] > getSize().width)
g.drawImage(I[Selected], 1, 1, Size - 2, Size - 2, this);
else
g.drawImage(I[Selected], X[Selected], Y[Selected], this);
}
}
/**
* Go up and down the pictures.
*/
@Override
public void pressed(final MouseEvent e) {
if (e.isMetaDown()) {
Selected--;
if (Selected < 0)
Selected = N - 1;
} else {
Selected++;
if (Selected >= N)
Selected = 0;
}
}
public void setSelected(final int s) {
if (Selected == s)
return;
Selected = s;
repaint();
}
public int getSelected() {
return Selected;
}
}
/**
* @author Rene An MultipleIcon that can be enabled externally.
*/
class MultipleToggleIcon extends MultipleIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
public MultipleToggleIcon(final IconBar bar, final String name,
final int number) {
super(bar, name, number);
}
public void setState(final boolean flag) {
On = flag;
repaint();
}
}
/**
* @author Rene A toggle icon for several colors.
*/
class ColorIcon extends MultipleIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
Color Colors[];
public ColorIcon(final IconBar bar, final String name, final Color colors[]) {
super(bar, name);
N = colors.length;
Colors = colors;
}
@Override
public void dopaint(final Graphics g) {
g.setColor(Colors[Selected]);
g.fill3DRect(5, 5, Size - 10, Size - 10, true);
}
}
/**
* @author Rene A toggle icon for several strings.
*/
class MultipleStringIcon extends MultipleIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
String S[];
public MultipleStringIcon(final IconBar bar, final String name,
final String s[]) {
super(bar, name);
S = s;
N = S.length;
}
@Override
public void dopaint(final Graphics g) {
g.setColor(getForeground());
final Font font = new Font("Dialog", Font.PLAIN, Size * 2 / 3);
g.setFont(font);
final FontMetrics fm = getFontMetrics(font);
final int w = fm.stringWidth(S[Selected]);
g.drawString(S[Selected], (Size - w) / 2, Size - fm.getDescent());
}
}
/**
* Button to get all icons, when there is not too much space.
*/
class OverflowButton extends JEricPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
IconBar IB;
boolean Left = true;
public OverflowButton(final IconBar ib, final boolean left) {
IB = ib;
Left = left;
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
IB.setShifted(!Left);
}
});
}
@Override
public void paint(final Graphics g) {
final int size = BasicIcon.Size;
g.setColor(getBackground());
g.fill3DRect(0, 0, 10, size, true);
g.setColor(getForeground());
final int x[] = new int[3], y[] = new int[3];
if (Left) {
x[0] = 2;
x[1] = x[2] = 8;
y[0] = size / 2;
y[1] = y[0] - 6;
y[2] = y[0] + 6;
} else {
x[0] = 8;
x[1] = x[2] = 2;
y[0] = size / 2;
y[1] = y[0] - 6;
y[2] = y[0] + 6;
}
g.fillPolygon(x, y, 3);
}
}
class PopupIcon extends BasicIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
public PopupIcon(final IconBar bar, final String name[]) {
super(bar, name[0]);
}
}
/**
* @author Rene An action icon for one click.
*/
class ToggleIcon extends IconWithGif {
/**
*
*/
private static final long serialVersionUID = 1L;
boolean State;
private final IconGroup G;
public ToggleIcon(final IconBar bar, final String file, final IconGroup g) {
super(bar, file);
State = false;
G = g;
}
public ToggleIcon(final IconBar bar, final String file, final Color c,
final IconGroup g) {
super(bar, file, c);
State = false;
G = g;
}
public ToggleIcon(final IconBar bar, final String file) {
this(bar, file, null);
}
@Override
public void pressed(final MouseEvent e) {
setState(!On);
}
public boolean getState() {
return State;
}
public void setState(final boolean state) {
if (G != null)
G.toggle(this);
else {
if (On == state) {
State = state;
return;
}
On = State = state;
repaint();
}
}
public void unselect() {
if (G != null)
G.unselect();
}
public void setStateInGroup(final boolean state) {
if (On == state) {
State = state;
return;
}
On = State = state;
repaint();
}
public int countPeers() {
if (G == null)
return 0;
return G.getN();
}
@Override
public void unset() {
if (G != null)
G.unset(true);
else
super.unset();
}
public void dounset(final boolean flag) {
super.unset(flag);
}
public void set() {
if (G != null)
G.unset(false);
else
super.unset(false);
}
public void doset() {
super.unset(false);
}
}
/**
* @author Rene An icon to display on/off state.
*/
class OnOffIcon extends ToggleIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
static int LampSize = 4;
public OnOffIcon(final IconBar bar, final String file) {
super(bar, file, null);
}
@Override
public void pressed(final MouseEvent e) {
State = On = !On;
}
}
/**
* This class can add several ToggleItems and will enable only one of them.
*/
class IconGroup {
String Files[], Breaks[];
IconBar Bar;
int N;
ToggleIcon Icons[];
public IconGroup(final IconBar bar, final String files[],
final String breaks[]) {
Files = files;
Breaks = breaks;
Bar = bar;
init();
}
public IconGroup(final IconBar bar, final String files[]) {
this(bar, files, files);
}
public void init() {
N = 0;
for (int i = 0; i < Files.length; i++)
if (!Files[i].equals(""))
N++;
Icons = new ToggleIcon[N];
int k = 0;
for (int i = 0; i < Files.length; i++) {
if (!Files[i].equals("")) {
Icons[k++] = new ToggleIcon(Bar, Files[i], this);
}
}
}
public IconGroup(final IconBar bar, final String name, final int n) {
Breaks = Files = new String[n];
for (int i = 0; i < n; i++) {
Files[i] = name + i;
}
Bar = bar;
init();
}
public IconGroup(final IconBar bar, final String name, final Color colors[]) {
N = colors.length;
Breaks = Files = new String[N];
for (int i = 0; i < N; i++) {
Files[i] = name + i;
}
Bar = bar;
Icons = new ToggleIcon[N];
for (int i = 0; i < N; i++) {
Icons[i] = new ToggleIcon(Bar, Files[i], colors[i], this);
}
}
public void addLeft() {
int i = 0;
for (int k = 0; k < Files.length; k++)
if (Files[k].equals(""))
Bar.addSeparatorLeft();
else {
if (Breaks[k].startsWith("!"))
Bar.addSeparatorLeft();
Bar.addLeft(Icons[i++]);
}
}
public void addRight() {
int i = 0;
for (int k = 0; k < Files.length; k++)
if (Files[k].equals(""))
Bar.addSeparatorRight();
else {
if (Breaks[k].startsWith("!"))
Bar.addSeparatorRight();
Bar.addRight(Icons[i++]);
}
}
public void toggle(final ToggleIcon icon) {
for (int i = 0; i < N; i++) {
if (Icons[i] == icon)
icon.setStateInGroup(true);
else
Icons[i].setStateInGroup(false);
}
}
public void unselect() {
for (int i = 0; i < N; i++) {
Icons[i].setStateInGroup(false);
}
}
public int getN() {
return N;
}
public void unset(final boolean flag) {
for (int i = 0; i < N; i++) {
Icons[i].dounset(flag);
}
}
}
/**
* An state display. Loads two images from a resource and display either of
* them, depending on the enabled state.
*/
class StateDisplay extends BasicIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
Image IOn, IOff;
int W, H, X, Y;
/**
* Initialize the icon and load its image.
*/
public StateDisplay(final IconBar bar, final String file) {
super(bar, file);
try {
InputStream in = getClass().getResourceAsStream(
Bar.Resource + file + "on" + "."
+ Global.getParameter("icontype", "gif"));
int pos = 0;
int n = in.available();
final byte b[] = new byte[20000];
while (n > 0) {
final int k = in.read(b, pos, n);
if (k < 0)
break;
pos += k;
n = in.available();
}
in.close();
IOn = Toolkit.getDefaultToolkit().createImage(b, 0, pos);
final MediaTracker T = new MediaTracker(bar);
T.addImage(IOn, 0);
in = getClass().getResourceAsStream(
Bar.Resource + file + "off" + "."
+ Global.getParameter("icontype", "gif"));
pos = 0;
n = in.available();
final byte b1[] = new byte[20000];
while (n > 0) {
final int k = in.read(b1, pos, n);
if (k < 0)
break;
pos += k;
n = in.available();
}
in.close();
IOff = Toolkit.getDefaultToolkit().createImage(b1, 0, pos);
T.addImage(IOff, 1);
T.waitForAll();
W = IOn.getWidth(this);
H = IOn.getHeight(this);
if (Bar.Vertical)
X = Size / 2 - W / 2;
else
X = 0;
Y = Size / 2 - H / 2;
} catch (final Exception e) {
IOn = IOff = null;
}
}
/**
* Paint a button with an image
*/
@Override
public void paintComponent(final Graphics g) {
if (Enabled && IOn != null) {
if (W > getSize().width)
g.drawImage(IOn, 1, 1, Size - 2, Size - 2, this);
else
g.drawImage(IOn, X, Y, this);
} else if (!Enabled && IOff != null) {
if (W > getSize().width)
g.drawImage(IOff, 1, 1, Size - 2, Size - 2, this);
else
g.drawImage(IOff, X, Y, this);
}
}
@Override
public void mousePressed(final MouseEvent e) {
}
@Override
public void mouseReleased(final MouseEvent e) {
T = null;
}
@Override
public void mouseClicked(final MouseEvent e) {
}
}
/**
* This panel displays icons and reacts on mouse actions. It can also interpret
* key strokes to traverse the icons.
*/
public class IconBar extends javax.swing.JPanel implements KeyListener,
FocusListener, IconBarListener {
/**
*
*/
private static final long serialVersionUID = 1L;
Vector Left = new Vector(), Right = new Vector();
int W;
Frame F;
public final int Offset = 2;
public String Resource = "/";
int Focus = 0;
public boolean TraverseFocus = true;
public boolean UseSize = true;
public boolean Vertical = false;
public IconBar(final Frame f, final boolean traversefocus) {
F = f;
TraverseFocus = traversefocus;
Resource = Global.getParameter("iconpath", "");
BasicIcon.Size = Global.getParameter("iconsize", 20);
setLayout(null);
W = Offset * 2;
addKeyListener(this);
if (TraverseFocus)
addFocusListener(this);
}
public IconBar(final Frame f) {
this(f, true);
}
public void add(final BasicIcon i) {
final java.net.URL myurl = getClass().getResource(
"/eric/GUI/icons/palette/" + i.Name + ".png");
if (myurl != null) {
super.add(i);
} else {
W -= i.width() + Offset;
Left.remove(i);
Right.remove(i);
}
i.repaint();
}
/**
* Do not know, if this is necessary. But sometimes the icons do not repaint
* after an update.
*/
public void forceRepaint() {
repaint();
Enumeration e = Left.elements();
while (e.hasMoreElements()) {
final BasicIcon i = (BasicIcon) e.nextElement();
i.repaint();
}
e = Right.elements();
while (e.hasMoreElements()) {
final BasicIcon i = (BasicIcon) e.nextElement();
i.repaint();
}
}
public void keyPressed(final KeyEvent e) {
}
public void keyReleased(final KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_RIGHT:
setFocus(Focus, false);
Focus++;
if (Focus >= Left.size() + Right.size())
Focus = 0;
while (!(getIcon(Focus) instanceof BasicIcon)) {
Focus++;
if (Focus >= Left.size() + Right.size()) {
Focus = 0;
break;
}
}
setFocus(Focus, true);
break;
case KeyEvent.VK_LEFT:
setFocus(Focus, false);
Focus--;
if (Focus < 0)
Focus = Left.size() + Right.size() - 1;
while (!(getIcon(Focus) instanceof BasicIcon)) {
Focus--;
if (Focus < 0) {
Focus = Left.size() + Right.size() - 1;
break;
}
}
setFocus(Focus, true);
break;
case KeyEvent.VK_SPACE:
try {
final BasicIcon icon = (BasicIcon) getIcon(Focus);
icon.mouseReleased(new MouseEvent(this,
MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, false));
} catch (final Exception ex) {
}
break;
}
}
public void keyTyped(final KeyEvent e) {
}
/*
* public boolean isFocusTraversable () { return TraverseFocus; }
*/
public Object getIcon(final int n) {
if (n < Left.size())
return Left.elementAt(n);
else
return Right.elementAt(Right.size() - 1 - (n - Left.size()));
}
public void focusGained(final FocusEvent e) {
if (TraverseFocus)
setFocus(Focus, true);
}
public void focusLost(final FocusEvent e) {
if (TraverseFocus)
setFocus(Focus, false);
}
public void setFocus(final int n, final boolean flag) {
if (!TraverseFocus)
return;
try {
if (n < Left.size()) {
final BasicIcon icon = (BasicIcon) Left.elementAt(n);
icon.setFocus(flag);
} else {
final BasicIcon icon = (BasicIcon) Right.elementAt(Right.size()
- 1 - (n - Left.size()));
icon.setFocus(flag);
}
} catch (final Exception e) {
}
}
/**
* Add an icon
*/
public void addLeft(final String name) {
addLeft(new IconWithGif(this, name));
}
public void addLeft(final BasicIcon i) {
Left.addElement(i);
add(i);
W += i.width() + Offset;
}
/**
* Add an icon at the right end
*/
public void addRight(final String name) {
addRight(new IconWithGif(this, name));
}
public void addRight(final BasicIcon i) {
Right.addElement(i);
add(i);
W += i.width() + Offset;
}
/**
* Add a toggle icon
*/
public void addToggleLeft(final String name) {
addLeft(new ToggleIcon(this, name));
}
public void addToggleRight(final String name) {
addRight(new ToggleIcon(this, name));
}
/**
* Add a toggle icon
*/
public void addOnOffLeft(final String name) {
addLeft(new OnOffIcon(this, name));
}
public void addOnOffRight(final String name) {
addRight(new OnOffIcon(this, name));
}
/**
* Add a complete groupe of toggle items.
*/
public void addToggleGroupLeft(final String names[], final String breaks[]) {
final IconGroup g = new IconGroup(this, names, breaks);
g.addLeft();
}
public void addToggleGroupRight(final String names[], final String breaks[]) {
final IconGroup g = new IconGroup(this, names, breaks);
g.addRight();
}
public void addToggleGroupLeft(final String names[]) {
addToggleGroupLeft(names, names);
}
public void addToggleGroupRight(final String names[]) {
addToggleGroupRight(names, names);
}
public void addToggleGroupLeft(final String name, final int n) {
final IconGroup g = new IconGroup(this, name, n);
g.addLeft();
}
public void addToggleGroupRight(final String name, final int n) {
final IconGroup g = new IconGroup(this, name, n);
g.addRight();
}
public void addToggleGroupLeft(final String name, final Color colors[]) {
final IconGroup g = new IconGroup(this, name, colors);
g.addLeft();
}
public void addToggleGroupRight(final String name, final Color colors[]) {
final IconGroup g = new IconGroup(this, name, colors);
g.addRight();
}
/**
* Add a separator
*/
public void addSeparatorLeft() {
if (Left.size() == 0)
return;
if (Left.lastElement() instanceof Separator)
return;
final Separator s = new Separator(this);
Left.addElement(s);
add(s);
W += s.width() + Offset;
}
public void addSeparatorRight() {
if (Right.size() == 0)
return;
if (Right.lastElement() instanceof Separator)
return;
final Separator s = new Separator(this);
Right.addElement(s);
add(s);
W += s.width() + Offset;
}
/**
* Add a multiple icon (can toggle between the icons)
*/
public void addMultipleIconLeft(final String name, final int number) {
addLeft(new MultipleIcon(this, name, number));
}
public void addMultipleIconRight(final String name, final int number) {
addRight(new MultipleIcon(this, name, number));
}
/**
* Add a multiple icon (can toggle between the icons)
*/
public void addMultipleStringIconLeft(final String name, final String s[]) {
addLeft(new MultipleStringIcon(this, name, s));
}
public void addMultipleStringIconRight(final String name, final String s[]) {
addRight(new MultipleStringIcon(this, name, s));
}
/**
* Add a multiple icon (can toggle between the icons)
*/
public void addMultipleToggleIconLeft(final String name, final int number) {
addLeft(new MultipleToggleIcon(this, name, number));
}
public void addMultipleToggleIconRight(final String name, final int number) {
addRight(new MultipleToggleIcon(this, name, number));
}
/**
* Add a multiple icon (can toggle between the colors)
*/
public void addColorIconLeft(final String name, final Color colors[]) {
addLeft(new ColorIcon(this, name, colors));
}
public void addColorIconRight(final String name, final Color colors[]) {
addRight(new ColorIcon(this, name, colors));
}
/**
* Add a state display at the left end.
*/
public void addStateLeft(final String name) {
addLeft(new StateDisplay(this, name));
}
public void addStateRight(final String name) {
addRight(new StateDisplay(this, name));
}
boolean Overflow = false, Shifted = false;
OverflowButton OB;
int OverflowX;
/**
* Override the layout and arange the icons from the left and the right.
*/
@Override
public void doLayout() {
if (OB != null) {
remove(OB);
OB = null;
}
if (Vertical) {
int x;
x = getSize().height;
for (int k = 0; k < Right.size(); k++) {
final IconBarElement i = (IconBarElement) Right.elementAt(k);
x -= i.width();
i.setPosition(2, x);
x -= Offset;
}
final int xmax = x;
x = 0;
for (int k = 0; k < Left.size(); k++) {
final IconBarElement i = (IconBarElement) Left.elementAt(k);
i.setPosition(2, x);
x += i.width();
x += Offset;
if (x + IconWithGif.Size > xmax)
x = -1000;
}
} else {
int x;
x = getSize().width;
for (int k = 0; k < Right.size(); k++) {
final IconBarElement i = (IconBarElement) Right.elementAt(k);
x -= i.width();
i.setPosition(x, 2);
x -= Offset;
}
final int xmax = x;
x = 0;
for (int k = 0; k < Left.size(); k++) {
IconBarElement i = (IconBarElement) Left.elementAt(k);
i.setPosition(x, 2);
x += i.width();
x += Offset;
if (x + IconWithGif.Size > xmax - 10 && k < Left.size() - 1) {
Overflow = true;
OverflowX = x;
OB = new OverflowButton(this, Shifted);
add(OB);
OB.setSize(10, BasicIcon.Size);
OB.setLocation(xmax - 10 - Offset, 2);
if (!Shifted) {
x = -1000;
} else {
x = xmax - 10 - 2 * Offset;
for (int l = Left.size() - 1; l >= 0; l--) {
i = (IconBarElement) Left.elementAt(l);
x -= i.width();
i.setPosition(x, 2);
x -= Offset;
if (x - IconWithGif.Size < 0)
x -= 1000;
}
break;
}
}
}
}
}
public void setShifted(final boolean flag) {
Shifted = flag;
doLayout();
}
/**
* Override the preferred sizes.
*/
@Override
public Dimension getPreferredSize() {
if (Vertical) {
if (!UseSize)
return new Dimension(IconWithGif.Size + 4, 10);
return new Dimension(IconWithGif.Size + 4, W + 10);
} else {
if (!UseSize)
return new Dimension(10, IconWithGif.Size + 4);
return new Dimension(W + 10, IconWithGif.Size + 4);
}
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
// The IconBar can notify one IconBarListener on icon
// clicks.
IconBarListener L = null;
public void setIconBarListener(final IconBarListener l) {
L = l;
}
public void removeIconBarListener(final IconBarListener l) {
L = null;
}
boolean Shift, Control;
public void iconPressed(final String name, final boolean shift,
final boolean control) {
Shift = shift;
Control = control;
removeHelp();
if (L != null)
L.iconPressed(name);
}
public boolean isShiftPressed() {
return Shift;
}
public boolean isControlPressed() {
return Control;
}
public void clearShiftControl() {
Shift = Control = false;
}
// The tool tip help, initiated by the icons.
JDialog WHelp = null;
public synchronized void displayHelp(final IconBarElement i,
final String text) {
if (F == null || WHelp != null)
return;
if (rene.gui.Global.isApplet())
return;
final Point P = i.getPosition();
WHelp = new JDialog(F);
WHelp.setAlwaysOnTop(true);
WHelp
.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
WHelp.setFocusable(false);
WHelp.setFocusableWindowState(false);
WHelp.setUndecorated(true);
final JEricPanel p = new JEricPanel();
final StringTokenizer t = new StringTokenizer(text, "+");
p.setLayout(new GridLayout(0, 1));
while (t.hasMoreTokens()) {
p.add(new MyLabel(t.nextToken()));
}
WHelp.add("Center", p);
WHelp.pack();
final Dimension d = WHelp.getSize();
final Dimension ds = getToolkit().getScreenSize();
int x = P.x, y = P.y + i.width() + 10;
if (x + d.width > ds.width)
x = ds.width - d.width;
if (y + d.height > ds.height)
y = P.y - i.width() - d.height;
WHelp.setLocation(x, y);
WHelp.setBackground(new Color(255, 255, 220));
WHelp.setForeground(Color.black);
WHelp.setVisible(true);
WHelp.toFront();
}
public synchronized void removeHelp() {
if (WHelp == null)
return;
WHelp.setVisible(false);
WHelp.dispose();
WHelp = null;
}
private BasicIcon find(final String name) {
int k;
for (k = 0; k < Left.size(); k++) {
try {
final BasicIcon i = (BasicIcon) Left.elementAt(k);
if (i.getName().equals(name))
return i;
} catch (final Exception e) {
}
}
for (k = 0; k < Right.size(); k++) {
try {
final BasicIcon i = (BasicIcon) Right.elementAt(k);
if (i.getName().equals(name))
return i;
} catch (final Exception e) {
}
}
return null;
}
/**
* Enable the tool with the specified name.
*/
public void setEnabled(final String name, final boolean flag) {
final BasicIcon icon = find(name);
if (icon == null)
return;
icon.setEnabled(flag);
}
/**
* Select
*/
public void toggle(final String name) {
final BasicIcon icon = find(name);
if (icon == null || !(icon instanceof ToggleIcon))
return;
((ToggleIcon) icon).setState(true);
}
/**
* Have an Icon?
*/
public boolean have(final String name) {
return find(name) != null;
}
/**
* Deselect all icons in the group of an icon
*/
public void unselect(final String name) {
final BasicIcon icon = find(name);
if (icon == null || !(icon instanceof ToggleIcon))
return;
((ToggleIcon) icon).unselect();
}
/**
* Toggle an item of an item group (known by name and number).
*/
public void toggle(final String name, final int n) {
toggle(name + n);
}
/**
* Set the state of a single toggle icon.
*/
public void setState(final String name, final boolean flag) {
final BasicIcon icon = find(name);
if (icon != null && (icon instanceof ToggleIcon))
((ToggleIcon) icon).setState(flag);
if (icon != null && (icon instanceof MultipleToggleIcon))
((MultipleToggleIcon) icon).setState(flag);
}
/**
* Get the state of the specified toggle icon
*/
public boolean getState(final String name) {
final BasicIcon icon = find(name);
if (icon == null || !(icon instanceof ToggleIcon))
return false;
return ((ToggleIcon) icon).getState();
}
/**
* Return the state of a toggle icon.
*/
public int getToggleState(final String name) {
final BasicIcon icon = find(name + 0);
if (icon == null || !(icon instanceof ToggleIcon))
return -1;
final int n = ((ToggleIcon) icon).countPeers();
for (int i = 0; i < n; i++) {
if (getState(name + i))
return i;
}
return -1;
}
/**
* Get the state of the specified multiple icon
*/
public int getMultipleState(final String name) {
int k;
for (k = 0; k < Left.size(); k++) {
final IconBarElement i = (IconBarElement) Left.elementAt(k);
if (i.getName().equals(name) && i instanceof MultipleIcon) {
return ((MultipleIcon) i).getSelected();
}
}
for (k = 0; k < Right.size(); k++) {
final IconBarElement i = (IconBarElement) Right.elementAt(k);
if (i.getName().equals(name) && i instanceof MultipleIcon) {
return ((MultipleIcon) i).getSelected();
}
}
return -1;
}
/**
* Set the state of the specified multiple icon
*/
public void setMultipleState(final String name, final int state) {
int k;
for (k = 0; k < Left.size(); k++) {
final IconBarElement i = (IconBarElement) Left.elementAt(k);
if (i.getName().equals(name) && i instanceof MultipleIcon) {
((MultipleIcon) i).setSelected(state);
}
}
for (k = 0; k < Right.size(); k++) {
final IconBarElement i = (IconBarElement) Right.elementAt(k);
if (i.getName().equals(name) && i instanceof MultipleIcon) {
((MultipleIcon) i).setSelected(state);
}
}
}
/**
* See, if the specific icon has been set.
*/
public boolean isSet(final String name) {
final BasicIcon icon = find(name);
if (icon == null)
return false;
return icon.isSet();
}
/**
* Set the specific icon to unset.
*/
public void unset(final String name) {
final BasicIcon icon = find(name);
if (icon != null)
icon.unset();
}
public void getKey(final KeyEvent e) {
processKeyEvent(e);
}
public void setSize(final int size) {
BasicIcon.Size = size;
}
@Override
public void removeAll() {
Enumeration e = Left.elements();
while (e.hasMoreElements()) {
remove((BasicIcon) e.nextElement());
}
e = Right.elements();
while (e.hasMoreElements()) {
remove((BasicIcon) e.nextElement());
}
Left.removeAllElements();
Right.removeAllElements();
}
/**
* Overwrite in children!
*
* @param name
* @return Help text
*/
public String getHelp(final String name) {
return "";
}
public static void main(final String args[]) {
final CloseFrame f = new CloseFrame("Test");
final IconBar IA = new IconBar(f);
IA.Vertical = true;
IA.setSize(30);
IA.Resource = "/icons/";
IA.addLeft("back");
IA.addLeft("undo");
IA.addSeparatorLeft();
IA.addOnOffLeft("grid");
IA.addSeparatorLeft();
IA.addToggleLeft("delete");
IA.addSeparatorLeft();
final String tg[] = { "zoom", "draw", "", "rename", "edit" };
IA.addToggleGroupLeft(tg);
IA.addSeparatorLeft();
IA.addMultipleToggleIconLeft("macro", 3);
IA.addSeparatorLeft();
final String tga[] = { "zoom", "draw", "rename", "edit" };
IA.addLeft(new PopupIcon(IA, tga));
IA.addSeparatorLeft();
final String st[] = { "A", "B", "C", "D" };
IA.addMultipleStringIconLeft("strings", st);
final Color col[] = { Color.BLACK, Color.RED, Color.GREEN };
IA.addStateLeft("needsave");
IA.addColorIconLeft("color", col);
f.add("Center", new IconBarPanel(new Panel3D(IA), new Panel3D(
new JEricPanel())));
f.pack();
f.center();
IA.setIconBarListener(IA);
f.setVisible(true);
}
public void iconPressed(final String name) {
System.out.println(name);
}
}