/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.ui.toolbars.system; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.border.LineBorder; /** * This class controls a collection of toolbar panels which can be added and removed from it. * * @author Michelle Bachler */ public class UIToolBarController extends JPanel implements SwingConstants { /** Indicates a top/north positioning*/ public final static int TOP = 0; /** Indicates a botton/south positioning.*/ public final static int BOTTOM = 1; /** Indicates a left/west positioning.*/ public final static int LEFT = 2; /** Indicates a right/east positioning.*/ public final static int RIGHT = 3; /** Indicates a horizontal alignment.*/ protected static int HORIZONTAL_ALIGNMENT = 0; /** Indicates a vertical alignment.*/ protected static int VERTICAL_ALIGNMENT = 1; /** The toolbar manager managing this toolbar controller instance.*/ private IUIToolBarManager oManager = null; /** Holds the current alignment of this toolbar controller panel.*/ private int nAlignment = 0; /** Holds the current position (TOP / BOTTOM / LEFT / RIGHT), of this toolbar controller panel.*/ private int nPosition = 0; /** Used to paint the expand/collapse button used on this toolbar controller panel.*/ private JButton button = null; /** Indicates if this toolbar controller panel has been collapsed.*/ private boolean isClosed = false; /** The layout used by this panel*/ private GridBagLayout gb = null; /** The constraint instance used by this panel for the layout.*/ private GridBagConstraints gc = null; /** Holds the objects representing a row of toolbars*/ private Vector vtRows = new Vector(5); private int nRowCount = 0; /** * Constructor. * * @param IUIToolBarManager manager, the manager responsible for this tollbar controller panel. */ public UIToolBarController(IUIToolBarManager manager) { this(manager, UIToolBarController.NORTH, false); } /** * Constructor. * * @param IUIToolBarManager manager, the manager responsible for this tollbar controller panel. * @param int pos, the position this toolbar will be drawn in (TOP / BOTTOM / LEFT / RIGHT). * @param boolean isClosed, indicates whether to draw this toolbar conroller panel collapsed or expanded. */ public UIToolBarController(IUIToolBarManager manager, int pos, boolean isClosed) { oManager = manager; this.isClosed = isClosed; nPosition = pos; if (nPosition == UIToolBarController.TOP || nPosition == UIToolBarController.BOTTOM) nAlignment = UIToolBarController.HORIZONTAL_ALIGNMENT; else nAlignment = UIToolBarController.VERTICAL_ALIGNMENT; button = new JButton(); setButtonIcon(); button.setToolTipText("Click to open/close"); button.setMargin(new Insets(0,0,0,0)); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { togglePosition(); } }); button.setFocusPainted(false); gb = new GridBagLayout(); setLayout(gb); gc = new GridBagConstraints(); gc.insets = new Insets(0,0,0,0); if (nAlignment == UIToolBarController.HORIZONTAL_ALIGNMENT) { gc.anchor = GridBagConstraints.WEST; } else { gc.anchor = GridBagConstraints.NORTH; } add(button); UIToolBarControllerRow row = new UIToolBarControllerRow(this, 0); vtRows.addElement(row); if (nAlignment == UIToolBarController.HORIZONTAL_ALIGNMENT) { gc.gridx = 0; gc.gridy = 0; gb.setConstraints(button, gc); gc.gridx = 1; gc.gridy = 0; gc.gridwidth = 1; gc.fill = GridBagConstraints.HORIZONTAL; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx=10; gb.setConstraints(row, gc); nRowCount++; } else { gc.gridx = 0; gc.gridy = 0; gb.setConstraints(button, gc); gc.gridx = 0; gc.gridy = 1; gc.gridheight = 1; gc.fill = GridBagConstraints.VERTICAL; gc.gridheight = GridBagConstraints.REMAINDER; gc.weighty=10; gb.setConstraints(row, gc); nRowCount++; } add(row); setVisible(false); } /** * Set the icon used on the controler panel button, depending on the panel position and state. */ private void setButtonIcon() { if (!isClosed) { if (nPosition == UIToolBarController.TOP) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_UP_NORTH_ICON)); else if (nPosition == UIToolBarController.BOTTOM) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_UP_SOUTH_ICON)); else if (nPosition == UIToolBarController.LEFT) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_UP_WEST_ICON)); else if (nPosition == UIToolBarController.RIGHT) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_UP_EAST_ICON)); } else { if (nPosition == UIToolBarController.TOP) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_DOWN_NORTH_ICON)); else if (nPosition == UIToolBarController.BOTTOM) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_DOWN_SOUTH_ICON)); else if (nPosition == UIToolBarController.LEFT) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_DOWN_WEST_ICON)); else if (nPosition == UIToolBarController.RIGHT) button.setIcon(UIToolBarImages.get(UIToolBarImages.TOOLBAR_DOWN_EAST_ICON)); } } /** * Remove all <code>UIToolBarPanel</code> instances from all rows. */ public void clear() { int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); row.clear(); } } /** * Remove the given row from this area. * @param row the UIToolBarControllerRow to remove. * @param nRow the row count of the row being removed. */ protected void removeRow(UIToolBarControllerRow row, int nRow) { if (nRow > 0) { vtRows.remove(row); remove(row); gb.invalidateLayout(this); gb.layoutContainer(this); } } /** * Create a new row for the given row number, and return the row. * @param nRow the row number for the new row. * @return the new UIToolbarControllerRow object. */ protected UIToolBarControllerRow createNewRow(int nRow) { UIToolBarControllerRow row = new UIToolBarControllerRow(this, nRow); vtRows.addElement(row); if (nAlignment == UIToolBarController.HORIZONTAL_ALIGNMENT) { gc.gridx = 0; gc.gridy = nRowCount; nRowCount++; gc.fill = GridBagConstraints.HORIZONTAL; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx=10; gb.setConstraints(row, gc); } else { gc.gridy = 0; gc.gridx = nRowCount; nRowCount++; gc.fill = GridBagConstraints.VERTICAL; gc.gridheight = GridBagConstraints.REMAINDER; gc.weighty=10; gb.setConstraints(row, gc); } add(row); gb.invalidateLayout(this); gb.layoutContainer(this); return row; } /** * Add the given <code>UIToolBar</code> to this controller panel. * * @param bar the toolbar to add. * @param type the type of the toolbar being added. * @param isVisible indicating if this toolbar should be drawn visible. * @param wasVisible indicates if the toolbar was visible. * @param bSwitchOn indicating if this toolbar should be visible. * @param nRow the row to add the toolbar to. */ public void addToolBar(UIToolBar bar, int type, boolean isVisible, boolean wasVisible, boolean bSwitchOn, int nRow) { if (!isVisible() && bSwitchOn) { setVisible(true); } if (nAlignment == UIToolBarController.HORIZONTAL_ALIGNMENT) { if (bar.getOrientation() == SwingConstants.VERTICAL) { bar.setOrientation(SwingConstants.HORIZONTAL); } } else { if (bar.getOrientation() == SwingConstants.HORIZONTAL) { bar.setOrientation(SwingConstants.VERTICAL); } } UIToolBarControllerRow row = null; if (vtRows.size() >= nRow+1) { row = (UIToolBarControllerRow)vtRows.elementAt(nRow); } // Don't add a second row if the first row is empty. if (row == null && nRow > 0) { UIToolBarControllerRow inner_row = (UIToolBarControllerRow)vtRows.elementAt(0); if (inner_row.getPositionCount() == 0) { row = inner_row; } } if (row == null) { row = createNewRow(nRow); } row.addToolBar(bar, type, isVisible, wasVisible, bSwitchOn, isClosed); validate(); repaint(); getParent().validate(); getParent().repaint(); } /** * Toggle the visibility of the toolbar panel for the given toolbar. * * @param bar the toolbar to switch on/off. * @param switchOn indicating if this toolbar should be visible. * @return boolean true if the toolbar is on this controller panel else false. */ public boolean toggleToolBar(UIToolBar bar, boolean switchOn) { boolean bFound = false; int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); bFound = row.toggleToolBar(bar, switchOn); if (bFound && !isVisible() && switchOn) { setVisible(true); } } return bFound; } /** * Return if this toolbar controller panel currently contains the given toolbar. * @param JToolBar bar, the bar to check for. * @return boolean, true if the given toolbar is currently in this toolbar controller panel, else false. */ public boolean containsBar(JToolBar bar) { int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); if (row.containsBar(bar)) { return true; } } return false; } /** * Creates an XML string representation of the data in this object. * * @return String, an XML string representation of this object. */ public String toXML() { StringBuffer data = new StringBuffer(100); data.append("<controller position=\""+nPosition+"\" isClosed=\""+isClosed+"\">\n"); data.append("<toolbars>"); data.append("\n"); int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); data.append(row.toXML()); } data.append("</toolbars>\n"); data.append("</controller>\n"); return data.toString(); } /** * Reverse (Expand/Collapse) the toolbar panels current state. */ protected void togglePosition() { if (isClosed) { isClosed = false; int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); row.togglePosition(isClosed); } setButtonIcon(); button.setToolTipText("Close up bar"); } else { isClosed = true; int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); row.togglePosition(isClosed); } setButtonIcon(); button.setToolTipText("Open up bar"); } validate(); repaint(); } /** * Check if all rows are empty and if so, close area. */ protected void validateController() { int count = vtRows.size(); boolean hasPanel = false; int panelCount = 0; UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); panelCount = row.getVisibleCount(); if (panelCount != 0) { hasPanel = true; break; } } if (!hasPanel) { setVisible(false); } } /** * Called when this panel is resized to determine if one of more toolbar panel should be collapsed * due to lack of visible space. * @param Component comp the UIToolBarPanel calling this method. */ protected void validateResize(UIToolBarPanel panel) { int count = vtRows.size(); UIToolBarControllerRow row = null; for (int i=0; i<count; i++) { row = (UIToolBarControllerRow)vtRows.elementAt(i); row.validateResize(panel); } } /** * * @return */ protected int getRowCount() { return vtRows.size(); } /** * Return the alignment of this toolbar area. * @return the alignment of this toolbar area. */ protected int getAlignment() { return nAlignment; } /** * Return the position of this controller (NORTH | SOUTH | EAST | WEST) * @return */ protected int getPosition() { return nPosition; } protected IUIToolBarManager getManager() { return oManager; } /** * Add a filler JLabel to fill any spare space and thereby align the toolbar panels correctly. * @param nRow the row to add the filler to. */ private JLabel addFiller() { JLabel filler = new JLabel(" "); filler.setBorder(new LineBorder(Color.black, 1)); if (nAlignment == UIToolBarController.HORIZONTAL_ALIGNMENT) { gc.fill = GridBagConstraints.HORIZONTAL; gc.gridwidth = GridBagConstraints.REMAINDER; gc.gridx = 300; gc.weightx=10; gb.setConstraints(filler, gc); } else { gc.fill = GridBagConstraints.VERTICAL; gc.gridheight = GridBagConstraints.REMAINDER; gc.gridy = 300; gc.weighty=10; gb.setConstraints(filler, gc); } add(filler); validate(); gc.fill = GridBagConstraints.NONE; gc.weightx=0; gc.weighty=0; return filler; } }