All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.globalmentor.swing.BasicToolBar Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 1996-2009 GlobalMentor, Inc. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.globalmentor.swing;

import java.awt.Component;
import java.awt.Container;
import javax.swing.*;

/**
 * A toolbar that has basic convenience methods, such as those to update status.
 * 

* This toolbar maintains whether contained buttons should display text. When a button is added, whether the button has text will depend on the status of the * toolbar buttonTextVisible property unless the button has no icon. When this property is changed using {@link #setButtonTextVisible(boolean)}, * all buttons on the toolbar change to match the new setting. The default value of the buttonTextVisible property is true. *

*

* If an added button's action defines an accelerator, it is added to the parent, either when the button is added to the toolbar or when the toolbar is added to * a component container. *

* @author Garret Wilson */ public class BasicToolBar extends JToolBar { /** Whether buttons should have text displayed. */ private boolean buttonTextVisible = true; /** @return Whether buttons should have text displayed. */ public boolean isButtonTextVisible() { return buttonTextVisible; } /** * Sets whether buttons should have text displayed. * @param newVisible true if buttons should display text, else false. */ public void setButtonTextVisible(final boolean newVisible) { final boolean oldVisible = buttonTextVisible; //get the current visibility of button text if(oldVisible != newVisible) { //if the button text visibility is changing buttonTextVisible = newVisible; //change to the new visibility final Component[] components = getComponents(); //get all child components for(int i = components.length - 1; i >= 0; --i) { //look at each child component if(components[i] instanceof AbstractButton) { //if this child component is a button setupButton((AbstractButton)components[i]); //set up this button to reflect our new button text visibility } } } } /** Default constructor with no name and horizontal orientation. */ public BasicToolBar() { this(true); //construct a toolbar and initialize it } /** * Constructor with horizontal orientation and optional initialization. * @param initialize true if the toolbar should initialize itself by calling the initialization methods. */ public BasicToolBar(final boolean initialize) { this(null, initialize); //construct and initialize the toolbar } /** * Name constructor with horizontal orientation. * @param name The name of the toolbar, used as the title of an undocked toolbar. */ public BasicToolBar(final String name) { this(name, true); //construct and initialize the toolbar } /** * Orientation constructor with no name. * @param orientation The orientation of the toolbar, either HORIZONTAL or VERTICAL. */ public BasicToolBar(final int orientation) { this(orientation, true); //construct and initialize the toolbar with the given orientation } /** * Name constructor with optional initialization. * @param name The name of the toolbar, used as the title of an undocked toolbar. * @param initialize true if the toolbar should initialize itself by calling the initialization methods. */ public BasicToolBar(final String name, final boolean initialize) { this(name, HORIZONTAL, initialize); //construct the toolbar with horizontal orientation } /** * Orientation constructor with optional initialization. * @param orientation The orientation of the toolbar, either HORIZONTAL or VERTICAL. */ public BasicToolBar(final int orientation, final boolean initialize) { this(null, orientation, initialize); //construct the toolbar with no name } /** * Name and orientation constructor. * @param name The name of the toolbar, used as the title of an undocked toolbar. * @param orientation The orientation of the toolbar, either HORIZONTAL or VERTICAL. */ public BasicToolBar(final String name, final int orientation) { this(name, orientation, true); //construct and initialize the toolbar with the given name and orientation } /** * Name and orientation constructor with optional initialization. * @param name The name of the toolbar, used as the title of an undocked toolbar. * @param orientation The orientation of the toolbar, either HORIZONTAL or VERTICAL. * @param initialize true if the toolbar should initialize itself by calling the initialization methods. */ public BasicToolBar(final String name, final int orientation, final boolean initialize) { super(name, orientation); //construct the parent class if(initialize) //if we should initialize initialize(); //initialize the toolbar } /** * Initializes the toolbar. Should only be called once per instance. * @see #initializeUI */ public void initialize() { //TODO set a flag that will only allow initialization once per instance initializeUI(); //initialize the user interface updateStatus(); //update the actions } /** * Initializes the user interface. Any derived class that overrides this method should call this version. */ protected void initializeUI() { } /** * Updates the states of the actions, including enabled/disabled status, proxied actions, etc. */ protected void updateStatus() { } /** * Adds the specified component to this container at the specified index. *

* If a button is added, whether it has text will depend on the state of the buttonTextVisible property. *

* @param component The component to be added. * @param constraints An object expressing layout constraints for this component. * @param index The position in the container's list at which to insert the component, where -1 means append to the end. * @throws IllegalArgumentException Thrown if index is invalid. * @throws IllegalArgumentException Thrown if adding the container's parent to itself. * @throws IllegalArgumentException Thrown if adding a window to a container. * @see AbstractButton * @see #setupButton */ protected void addImpl(final Component component, final Object constraints, final int index) { if(component instanceof AbstractButton) { //if this component is a button setupButton((AbstractButton)component); //set up the button } super.addImpl(component, constraints, index); //do the default adding } /** * Sets up a button to display text based on whether text should be visible. *

* If a button has no icon, its text will always be visible. *

*

* If a button's action has an accelerator key, it will be installed in the toolbar's parent container, if that parent is a JComponent. *

* @param button The button to set up. * @see #isButtonTextVisible * @see #addAccelerator(Action) */ protected void setupButton(final AbstractButton button) { final Icon icon = button.getIcon(); //see if the button has an icon final Action action = button.getAction(); //get the button's action, if there is one final boolean hideText = icon != null ? !isButtonTextVisible() : false; //always show the text if there is no icon; otherwise, show or hide the text appropriately button.putClientProperty(Buttons.HIDE_ACTION_TEXT_PROPERTY, Boolean.valueOf(hideText)); //tell the button whether its text should be hidden final String text = button.getText(); //get the button text if(hideText) { //if we should hide text if(text != null && text.length() > 0) { //if there is text button.setText(null); //clear the button text //TODO fix button.repaint(); //TODO fix } } else if(text == null || text.length() == 0) { //if we should show the text, but there is no text if(action != null) { //if the button has a corresponding action button.setText((String)action.getValue(Action.NAME)); //set the text to the name of the action } //TODO fix for buttons that don't have corresponding actions } if(action != null) { //if this button has an action addAccelerator(action); //add any action accelerator } } /** * Adds an accelerator from an action to the parent component. *

* If the action has an accelerator key, it will be installed in the toolbar's parent container, if that parent is a component. *

* @param action The action which may contain an accelerator. */ protected void addAccelerator(final Action action) { final Object acceleratorValue = action.getValue(Action.ACCELERATOR_KEY); //get this action's accelerator value if(acceleratorValue instanceof KeyStroke) { //if this action has an accelerator keystroke final KeyStroke keyStroke = (KeyStroke)acceleratorValue; //cast the accelerator value to a keystroke final Container parent = getParent(); //get the parent container if(parent instanceof JComponent) { //if the parent is a component TODO maybe search up the chain for a component final JComponent parentComponent = (JComponent)parent; //cast the parent to a component //store the keystroke in the parent's input map pointing to the action name parentComponent.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keyStroke, action.getValue(Action.NAME)); //place the action in the parent's action map keyed to the action name parentComponent.getActionMap().put(action.getValue(Action.NAME), action); } } } /** * Adds accelerators for all contained buttons with actions that have accelerator keys. If the parent component is not a JComponent, or if there * is no parent component, no action occurs. * @see #addAccelerator(Action) */ protected void addAccelerators() { for(int i = getComponentCount() - 1; i >= 0; --i) { //look at each component on the toolbar and add accelerators as needed final Component component = getComponent(i); //get this toolbar component if(component instanceof AbstractButton) { //if this is a button on the toolbar final AbstractButton button = (AbstractButton)component; //cast the toolbar component to a button final Action action = button.getAction(); //get the button's action, if there is one if(action != null) { //if this button has an action addAccelerator(action); //add an accelerator for this action, if the action has an accelerator } } } } /** * Makes this Component displayable by connecting it to a native screen resource. *

* This version adds any accelerators contained in any toolbar button actions to the parent component, as this method is called whenever the toolbar has been * added to a parent. *

* @see #addAccelerators() */ public void addNotify() { super.addNotify(); //do the default add notification addAccelerators(); //add any accelerators, which might not have been possible earlier if we had no parent } //TODO override removeNotify() to remove accelerators /** * Retrieves a toolbar component that represents the given action. * @param action The action for which a component should be returned. * @return The child component, such as a button, that represents the given action, or null if no child component represents the given action. */ public Component getComponent(final Action action) { for(int i = getComponentCount() - 1; i >= 0; --i) { //look at each component on the toolbar and add accelerators as needed final Component component = getComponent(i); //get this toolbar component if(component instanceof AbstractButton) { //if this is a button on the toolbar final AbstractButton button = (AbstractButton)component; //cast the toolbar component to a button if(button.getAction() == action) { //if this button has the correct action return button; //return the button } } } return null; //show that we found no component that represents the given action } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy