/* 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 . */ 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); } }