001: /*
002: * ToolBar.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.toolbar;
023:
024: import java.awt.BorderLayout;
025: import java.awt.Color;
026: import java.awt.Component;
027: import java.awt.Cursor;
028: import java.awt.Dimension;
029: import java.awt.Graphics;
030: import java.awt.GridBagConstraints;
031: import java.awt.GridBagLayout;
032: import java.awt.Shape;
033: import java.awt.event.MouseEvent;
034: import java.awt.event.MouseListener;
035: import java.awt.event.MouseMotionListener;
036:
037: import java.util.ArrayList;
038:
039: import javax.swing.BorderFactory;
040: import javax.swing.ButtonGroup;
041: import javax.swing.JComboBox;
042: import javax.swing.JComponent;
043: import javax.swing.JPanel;
044: import javax.swing.JToggleButton;
045: import javax.swing.UIManager;
046: import javax.swing.border.Border;
047: import org.underworldlabs.swing.GUIUtils;
048:
049: import org.underworldlabs.swing.RolloverButton;
050:
051: /* ----------------------------------------------------------
052: * CVS NOTE: Changes to the CVS repository prior to the
053: * release of version 3.0.0beta1 has meant a
054: * resetting of CVS revision numbers.
055: * ----------------------------------------------------------
056: */
057:
058: /**
059: *
060: * @author Takis Diakoumis
061: * @version $Revision: 1.8 $
062: * @date $Date: 2006/08/11 12:32:07 $
063: */
064: public class ToolBar extends AbstractToolBarPanel implements
065: MouseListener, MouseMotionListener {
066:
067: /** The tool bar separator width */
068: public static final int SEPARATOR_WIDTH = 4;
069:
070: // ---------------------------------------------
071: // --- Bound properties for tool bar changes ---
072: // ---------------------------------------------
073:
074: /** Selected property */
075: public static final String TOOL_BAR_BEGIN_MOVING = "toolBarBeginMoving";
076: /** Moving property */
077: public static final String TOOL_BAR_MOVING = "toolBarMoving";
078: /** Moved property */
079: public static final String TOOL_BAR_MOVED = "toolBarMoved";
080: /** Selected property */
081: public static final String TOOL_BAR_SELECTED = "toolBarSelected";
082: /** Deselected property */
083: public static final String TOOL_BAR_DESELECTED = "toolBarDeselected";
084: /** Resize property */
085: public static final String TOOL_BAR_RESIZING = "toolBarResizing";
086:
087: /** The tool bar's border */
088: protected static Border toolBarBorder;
089:
090: /** The top parent container */
091: protected ToolBarBase parent;
092:
093: /** The button panel */
094: protected JPanel buttonPanel;
095:
096: /** This tool bar's name */
097: protected String name;
098:
099: /** Button group for toggle buttons */
100: protected ButtonGroup buttonGroup;
101:
102: /** Component constraints */
103: protected GridBagConstraints gbc;
104:
105: /** The tool buttons added */
106: protected ArrayList toolButtons;
107:
108: /** Dummy object for separator */
109: private static final Object SEPARATOR = new Object();
110:
111: // --------------------------------
112: // --- Tracking mouse movements ---
113: // --------------------------------
114:
115: /** The initial X position */
116: private int m_XDifference;
117:
118: /** The initial Y position */
119: private int m_YDifference;
120:
121: /** Whether the tool bar is being dragged */
122: private boolean dragging;
123:
124: /** The tool bar width + the x position */
125: private int rightX;
126:
127: /** Whether the tool bar is being resized */
128: private boolean resizing;
129:
130: /** The mouse region where resizing will begin */
131: private static final int resizeRegionX = 2;
132:
133: public ToolBar(ToolBarBase parent) {
134: super (new BorderLayout());
135: this .parent = parent;
136:
137: toolButtons = new ArrayList();
138:
139: ToolBarSelectionWidget moveWidget = new ToolBarSelectionWidget();
140: moveWidget.addMouseListener(this );
141: moveWidget.addMouseMotionListener(this );
142:
143: buttonPanel = new JPanel(new GridBagLayout());
144: buttonPanel.setOpaque(false);
145:
146: add(moveWidget, BorderLayout.WEST);
147: add(buttonPanel, BorderLayout.CENTER);
148:
149: if (toolBarBorder == null) {
150: toolBarBorder = BorderFactory.createEtchedBorder();
151: }
152:
153: gbc = new GridBagConstraints();
154: gbc.anchor = GridBagConstraints.WEST;
155: gbc.insets.left = 2;
156: gbc.insets.top = 1;
157: gbc.insets.bottom = 1;
158:
159: setBorder(toolBarBorder);
160: }
161:
162: public ToolBar(ToolBarBase parent, String name) {
163: this (parent);
164: this .name = name;
165: }
166:
167: public void enableButtonsSelection(boolean enable) {
168: for (int i = 0, k = toolButtons.size(); i < k; i++) {
169: Object obj = toolButtons.get(i);
170: if (obj instanceof RolloverButton) {
171: ((RolloverButton) obj).enableSelectionRollover(enable);
172: }
173: }
174: }
175:
176: public void addSeparator() {
177: toolButtons.add(SEPARATOR);
178: }
179:
180: public void addToggleButton(JToggleButton button) {
181: if (buttonGroup == null) {
182: buttonGroup = new ButtonGroup();
183: }
184:
185: buttonGroup.add(button);
186: gbc.gridx++;
187: buttonPanel.add(button, gbc);
188: button.setSelected(true);
189: }
190:
191: public void removeToggleButton(JToggleButton button) {
192: buttonGroup.remove(button);
193: buttonPanel.remove(button);
194: repaint();
195: }
196:
197: public void addButton(JComponent button) {
198: toolButtons.add(button);
199: }
200:
201: public void buildToolBar() {
202: Object obj = null;
203: int buttonCount = toolButtons.size();
204: gbc.weightx = 0;
205:
206: for (int i = 0; i < buttonCount; i++) {
207: gbc.gridx++;
208:
209: if (i + 1 == buttonCount - 1) {
210: obj = toolButtons.get(i + 1);
211:
212: if (obj == SEPARATOR) {
213: gbc.weightx = 1.0;
214: }
215:
216: }
217:
218: obj = toolButtons.get(i);
219:
220: if (obj == SEPARATOR) {
221: gbc.insets.left = SEPARATOR_WIDTH;
222: continue;
223: } else if (obj instanceof JComboBox) {
224: gbc.insets.top = 1;
225: }
226:
227: if (i == buttonCount - 1) {
228: gbc.weightx = 1.0;
229: }
230:
231: buttonPanel.add((JComponent) obj, gbc);
232: gbc.insets.left = 0;
233: gbc.insets.top = 1;
234: }
235:
236: }
237:
238: public void removeAllButtons() {
239: int size = toolButtons.size();
240:
241: for (int i = 0; i < size; i++) {
242:
243: Object obj = toolButtons.get(i);
244: if (obj instanceof Component) {
245: buttonPanel.remove((Component) obj);
246: }
247:
248: }
249:
250: toolButtons.clear();
251: }
252:
253: public void setName(String name) {
254: this .name = name;
255: }
256:
257: public String getName() {
258: return name;
259: }
260:
261: public void mouseDragged(MouseEvent e) {
262: int ex = e.getX();
263: int ey = e.getY();
264: int x = getX();
265: int y = getY();
266: int w = getParent().getWidth();
267: int h = getParent().getHeight();
268:
269: int locX = -1;
270: int locY = -1;
271:
272: if (resizing) {
273:
274: if (getWidth() - ex - m_XDifference >= resizeRegionX) {
275: locX = getX() + ex - m_XDifference;
276: setBounds(locX, getY(),
277: getWidth() - ex - m_XDifference, getHeight());
278: }
279:
280: else {
281:
282: if (ex + resizeRegionX < rightX) {
283: locX = rightX - resizeRegionX;
284: setBounds(locX, getY(), resizeRegionX, getHeight());
285: } else {
286: locX = ex;
287: setBounds(locX, getY(), resizeRegionX, getHeight());
288: }
289:
290: }
291:
292: validate();
293: firePropertyChange(TOOL_BAR_RESIZING, x, locX);
294: }
295:
296: else if (dragging) {
297:
298: if ((ey + y > 0 && ey + y < h)
299: && (ex + x > 0 && ex + x < w)) {
300: locX = ex - m_XDifference + x;
301: locY = ey - m_YDifference + y;
302: }
303:
304: else if (!(ey + y > 0 && ey + y < h)
305: && (ex + x > 0 && ex + x < w)) {
306:
307: if (!(ey + y > 0) && ey + y < h) {
308: locX = ex - m_XDifference + x;
309: locY = 0 - m_YDifference;
310: } else if (ey + y > 0 && !(ey + y < h)) {
311: locX = ex - m_XDifference + x;
312: locY = h - m_YDifference;
313: }
314:
315: }
316:
317: else if ((ey + y > 0 && ey + y < h)
318: && !(ex + x > 0 && ex + x < w)) {
319:
320: if (!(ex + x > 0) && ex + x < w) {
321: locX = 0 - m_XDifference;
322: locY = ey - m_YDifference + y;
323: } else if (ex + x > 0 && !(ex + x < w)) {
324: locX = w - m_XDifference;
325: locY = ey - m_YDifference + y;
326: }
327:
328: }
329:
330: else if (!(ey + y > 0) && ey + y < h && !(ex + x > 0)
331: && ex + x < w) {
332: locX = 0 - m_XDifference;
333: locY = 0 - m_YDifference;
334: }
335:
336: else if (!(ey + y > 0) && ey + y < h && ex + x > 0
337: && !(ex + x < w)) {
338: locX = w - m_XDifference;
339: locY = 0 - m_YDifference;
340: }
341:
342: else if (ey + y > 0 && !(ey + y < h) && !(ex + x > 0)
343: && ex + x < w) {
344: locX = 0 - m_XDifference;
345: locY = h - m_YDifference;
346: }
347:
348: else if (ey + y > 0 && !(ey + y < h) && ex + x > 0
349: && !(ex + x < w)) {
350: locX = w - m_XDifference;
351: locY = h - m_YDifference;
352: }
353:
354: if (locX < 0) {
355: locX = 0;
356: }
357:
358: int parentHeight = parent.getHeight();
359: //int maxY = parentHeight - (ToolBarLayout.getRowHeight() / 2);
360: int maxY = parentHeight - (getHeight() / 2);
361:
362: if (locY < 0) {
363: locY = 0;
364: } else if (locY > maxY) {
365: firePropertyChange(TOOL_BAR_MOVING, m_YDifference, locY);
366: parentHeight = parent.getHeight();
367:
368: if (locY > parentHeight) {
369: locY = parentHeight;
370: }
371:
372: }
373:
374: setLocation(locX, locY);
375:
376: }
377:
378: }
379:
380: public void mousePressed(MouseEvent e) {
381: int xPos = getX();
382: rightX = xPos + getWidth();
383: m_XDifference = e.getX();
384: m_YDifference = e.getY();
385:
386: if (m_XDifference <= resizeRegionX && xPos != 0) {
387: resizing = true;
388: } else {
389: firePropertyChange(TOOL_BAR_BEGIN_MOVING, 0, 1);
390: dragging = true;
391: }
392:
393: }
394:
395: public void mouseReleased(MouseEvent e) {
396: if (dragging) {
397: firePropertyChange(TOOL_BAR_MOVED, 0, 1);
398: }
399:
400: firePropertyChange(TOOL_BAR_DESELECTED, 0, 1);
401: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
402: dragging = false;
403: resizing = false;
404: }
405:
406: public void mouseExited(MouseEvent e) {
407: if (!resizing) {
408: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
409: }
410: }
411:
412: public void mouseMoved(MouseEvent e) {
413: if (e.getX() > resizeRegionX && !resizing) {
414: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
415: }
416: }
417:
418: public void mouseEntered(MouseEvent e) {
419: if (!dragging && !resizing && e.getX() <= resizeRegionX
420: && getX() != 0) {
421: setCursor(Cursor
422: .getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
423: }
424: }
425:
426: public void mouseClicked(MouseEvent e) {
427: }
428:
429: public String toString() {
430: return "Tool Bar: " + name;
431: }
432:
433: private static Border widgetBorder;
434: private static Color middleground;
435: private static Color background;
436: private static Color foreground;
437:
438: /** <p>Small widget placed on the left edge of the tool bar. */
439: class ToolBarSelectionWidget extends JPanel {
440:
441: /** fixed width - 9px */
442: protected static final int WIDTH = 9;
443:
444: /** indicates whether the Java L&F (or a derivative) is used */
445: private boolean isJavaLookAndFeel;
446:
447: public ToolBarSelectionWidget() {
448: isJavaLookAndFeel = GUIUtils.isMetalLookAndFeel();
449:
450: if (background == null) {
451: background = UIManager.getDefaults().getColor(
452: "InternalFrame.borderDarkShadow");
453: }
454:
455: if (foreground == null) {
456: foreground = Color.WHITE;
457: }
458:
459: //int width = 9;
460: //int height = 29;
461: //setPreferredSize(new Dimension(width, height));
462: }
463:
464: public int getWidth() {
465: return WIDTH;
466: }
467:
468: public boolean isOpaque() {
469: return false;
470: }
471:
472: public void paintComponent(Graphics g) {
473: int height = getHeight();
474: if (!isJavaLookAndFeel) {
475:
476: if (middleground == null) {
477: middleground = UIManager.getDefaults().getColor(
478: "control");
479: }
480:
481: int start = (height - 13) / 2;
482: for (int i = 0; i < 3; i++) {
483: g.setColor(background);
484: g.drawLine(2, start, 3, start);
485: g.drawLine(2, start, 2, start + 2);
486:
487: g.setColor(middleground);
488: g.drawLine(4, start, 4, start);
489: g.drawLine(3, start + 1, 3, start + 1);
490: g.drawLine(2, start + 2, 2, start + 2);
491:
492: g.setColor(foreground);
493: g.drawLine(3, start + 2, 4, start + 2);
494: g.drawLine(4, start + 1, 4, start + 1);
495: start += 6;
496: }
497:
498: } else {
499: Shape clip = g.getClip();
500: g.setClip(1, 1, getWidth() - 2, height - 4);
501:
502: g.setColor(foreground);
503: for (int x = 1; x <= height; x += 4) {
504:
505: for (int y = 1; y <= height; y += 4) {
506: g.drawLine(x, y, x, y);
507: g.drawLine(x + 2, y + 2, x + 2, y + 2);
508: }
509:
510: }
511:
512: g.setColor(background);
513: for (int x = 1; x <= height; x += 4) {
514:
515: for (int y = 1; y <= height; y += 4) {
516: g.drawLine(x + 1, y + 1, x + 1, y + 1);
517: g.drawLine(x + 3, y + 3, x + 3, y + 3);
518: }
519:
520: }
521: g.setClip(clip);
522: }
523:
524: }
525:
526: } // ToolBarSelectionWidget
527:
528: }
|