/** * L2FProd.com Common Components 7.3 License. * * Copyright 2005-2007 L2FProd.com * * 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.l2fprod.common.swing; import com.l2fprod.common.swing.plaf.JTaskPaneGroupAddon; import com.l2fprod.common.swing.plaf.LookAndFeelAddons; import com.l2fprod.common.swing.plaf.TaskPaneGroupUI; import javax.swing.*; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; /** * <code>JTaskPaneGroup</code> is a container for tasks and other * arbitrary components. * <p/> * <p/> * Several <code>JTaskPaneGroup</code>s are usually grouped together within a * {@link JTaskPane}. However it is not mandatory * to use a JTaskPane as the parent for JTaskPaneGroup. The JTaskPaneGroup can * be added to any other container. See * {@link JTaskPane} to understand the benefits of * using it as the parent container. * <p/> * <p/> * <code>JTaskPaneGroup</code> provides control to expand and * collapse the content area in order to show or hide the task list. It can have an * <code>icon</code>, a <code>title</code> and can be marked as * <code>special</code>. Marking a <code>JTaskPaneGroup</code> as * <code>special</code> is only a hint for the pluggable UI which * will usually paint it differently (by example by using another * color for the border of the pane). * <p/> * <p/> * When the JTaskPaneGroup is expanded or collapsed, it will be * animated with a fade effect. The animated can be disabled on a per * component basis through {@link #setAnimated(boolean)}. * <p/> * To disable the animation for all newly created <code>JTaskPaneGroup</code>, * use the UIManager property: * <code>UIManager.put("TaskPaneGroup.animate", Boolean.FALSE);</code>. * <p/> * <p/> * Example: * <pre> * <code> * JXFrame frame = new JXFrame(); * * // a container to put all JTaskPaneGroup together * JTaskPane taskPaneContainer = new JTaskPane(); * * // create a first taskPane with common actions * JTaskPaneGroup actionPane = new JTaskPaneGroup(); * actionPane.setTitle("Files and Folders"); * actionPane.setSpecial(true); * * // actions can be added, an hyperlink will be created * Action renameSelectedFile = createRenameFileAction(); * actionPane.add(renameSelectedFile); * actionPane.add(createDeleteFileAction()); * * // add this taskPane to the taskPaneContainer * taskPaneContainer.add(actionPane); * * // create another taskPane, it will show details of the selected file * JTaskPaneGroup details = new JTaskPaneGroup(); * details.setTitle("Details"); * * // add standard components to the details taskPane * JLabel searchLabel = new JLabel("Search:"); * JTextField searchField = new JTextField(""); * details.add(searchLabel); * details.add(searchField); * * taskPaneContainer.add(details); * * // put the action list on the left * frame.add(taskPaneContainer, BorderLayout.EAST); * * // and a file browser in the middle * frame.add(fileBrowser, BorderLayout.CENTER); * * frame.pack(). * frame.setVisible(true); * </code> * </pre> * * @author <a href="mailto:fred@L2FProd.com">Frederic Lavigne</a> * @javabean.attribute name="isContainer" * value="Boolean.TRUE" * rtexpr="true" * @javabean.attribute name="containerDelegate" * value="getContentPane" * @javabean.class name="JTaskPaneGroup" * shortDescription="JTaskPaneGroup is a container for tasks and other arbitrary components." * stopClass="java.awt.Component" * @javabean.icons mono16="JTaskPaneGroup16-mono.gif" * color16="JTaskPaneGroup16.gif" * mono32="JTaskPaneGroup32-mono.gif" * color32="JTaskPaneGroup32.gif" * @see JTaskPane * @see JCollapsiblePane */ public class JTaskPaneGroup extends JPanel implements JCollapsiblePane.JCollapsiblePaneContainer { public final static String UI_CLASS_ID = "TaskPaneGroupUI"; // ensure at least the default ui is registered static { LookAndFeelAddons.contribute(new JTaskPaneGroupAddon()); } /** * Used when generating PropertyChangeEvents for the "expanded" property */ public static final String EXPANDED_CHANGED_KEY = "expanded"; /** * Used when generating PropertyChangeEvents for the "collapsable" property */ public static final String COLLAPSABLE_CHANGED_KEY = "collapsable"; /** * Used when generating PropertyChangeEvents for the "scrollOnExpand" property */ public static final String SCROLL_ON_EXPAND_CHANGED_KEY = "scrollOnExpand"; /** * Used when generating PropertyChangeEvents for the "title" property */ public static final String TITLE_CHANGED_KEY = "title"; /** * Used when generating PropertyChangeEvents for the "icon" property */ public static final String ICON_CHANGED_KEY = "icon"; /** * Used when generating PropertyChangeEvents for the "special" property */ public static final String SPECIAL_CHANGED_KEY = "special"; /** * Used when generating PropertyChangeEvents for the "animated" property */ public static final String ANIMATED_CHANGED_KEY = "animated"; private String title; private Icon icon; private boolean special; private boolean expanded = true; private boolean scrollOnExpand; private boolean collapsable = true; private JCollapsiblePane collapsePane; /** * Creates a new empty <code>JTaskPaneGroup</code>. */ public JTaskPaneGroup() { collapsePane = new JCollapsiblePane(); super.setLayout(new BorderLayout(0, 0)); super.addImpl(collapsePane, BorderLayout.CENTER, -1); updateUI(); setFocusable(true); setOpaque(false); // disable animation if specified in UIManager setAnimated(!Boolean.FALSE.equals(UIManager.get("TaskPaneGroup.animate"))); // listen for animation events and forward them to registered listeners collapsePane.addPropertyChangeListener(JCollapsiblePane.ANIMATION_STATE_KEY, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { JTaskPaneGroup.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); } }); } /** * Returns the contentPane object for this JTaskPaneGroup. * * @return the contentPane property */ public Container getContentPane() { return collapsePane.getContentPane(); } /** * Notification from the <code>UIManager</code> that the L&F has changed. * Replaces the current UI object with the latest version from the <code>UIManager</code>. * * @see javax.swing.JComponent#updateUI */ public void updateUI() { // collapsePane is null when updateUI() is called by the "super()" // constructor if (collapsePane == null) { return; } setUI((TaskPaneGroupUI) LookAndFeelAddons.getUI(this, TaskPaneGroupUI.class)); } /** * Sets the L&F object that renders this component. * * @param ui the <code>TaskPaneGroupUI</code> L&F object * @beaninfo bound: true hidden: true description: The UI object that * implements the taskpane group's LookAndFeel. * @see javax.swing.UIDefaults#getUI */ public void setUI(TaskPaneGroupUI ui) { super.setUI(ui); } /** * Returns the name of the L&F class that renders this component. * * @return the string {@link #UI_CLASS_ID} * @see javax.swing.JComponent#getUIClassID * @see javax.swing.UIDefaults#getUI */ public String getUIClassID() { return UI_CLASS_ID; } /** * Returns the title currently displayed in the border of this pane. * * @return the title currently displayed in the border of this pane * @since 0.2 */ public String getTitle() { return title; } /** * Sets the title to be displayed in the border of this pane. * * @param title the title to be displayed in the border of this pane * @javabean.property bound="true" * preferred="true" * @since 0.2 */ public void setTitle(String title) { String old = title; this.title = title; firePropertyChange(TITLE_CHANGED_KEY, old, title); } /** * @param text * @see #setTitle(String) * @deprecated */ public void setText(String text) { setTitle(text); } /** * @see #getTitle() * @deprecated */ public String getText() { return getTitle(); } /** * Returns the icon currently displayed in the border of this pane. * * @return the icon currently displayed in the border of this pane */ public Icon getIcon() { return icon; } /** * Sets the icon to be displayed in the border of this pane. Some pluggable * UIs may impose size constraints for the icon. A size of 16x16 pixels is * the recommended icon size. * * @param icon the icon to be displayed in the border of this pane * @javabean.property bound="true" * preferred="true" */ public void setIcon(Icon icon) { Icon old = icon; this.icon = icon; firePropertyChange(ICON_CHANGED_KEY, old, icon); } /** * Returns true if this pane is "special". * * @return true if this pane is "special" */ public boolean isSpecial() { return special; } /** * Sets this pane to be "special" or not. Marking a <code>JTaskPaneGroup</code> * as <code>special</code> is only a hint for the pluggable UI which will * usually paint it differently (by example by using another color for the * border of the pane). * <p/> * <p/> * Usually the first JTaskPaneGroup in a JTaskPane is marked as special * because it contains the default set of actions which can be executed given * the current context. * * @param special true if this pane is "special", false otherwise * @javabean.property bound="true" * preferred="true" */ public void setSpecial(boolean special) { if (this.special != special) { this.special = special; firePropertyChange(SPECIAL_CHANGED_KEY, !special, special); } } /** * Should this group be scrolled to be visible on expand. * * @param scrollOnExpand true to scroll this group to be * visible if this group is expanded. * @javabean.property bound="true" * preferred="true" * @see #setExpanded(boolean) */ public void setScrollOnExpand(boolean scrollOnExpand) { if (this.scrollOnExpand != scrollOnExpand) { this.scrollOnExpand = scrollOnExpand; firePropertyChange(SCROLL_ON_EXPAND_CHANGED_KEY, !scrollOnExpand, scrollOnExpand); } } /** * Should this group scroll to be visible after * this group was expanded. * * @return true if we should scroll false if nothing * should be done. */ public boolean isScrollOnExpand() { return scrollOnExpand; } /** * Expands or collapses this group. * * @param expanded true to expand the group, false to collapse it * @javabean.property bound="true" * preferred="true" */ public void setExpanded(boolean expanded) { if (this.expanded != expanded) { this.expanded = expanded; collapsePane.setCollapsed(!expanded); firePropertyChange(EXPANDED_CHANGED_KEY, !expanded, expanded); } } /** * Returns true if this taskpane is expanded, false if it is collapsed. * * @return true if this taskpane is expanded, false if it is collapsed. */ public boolean isExpanded() { return expanded; } /** * Sets whether or not this group can be collapsed by the user * * @param collapsable false to prevent the group to be manually collapsed * @javabean.property bound="true" preferred="true" */ public void setCollapsable(boolean collapsable) { if (this.collapsable != collapsable) { this.collapsable = collapsable; firePropertyChange(COLLAPSABLE_CHANGED_KEY, !collapsable, collapsable); } } /** * @return true if this taskpane can be collapsed by the user. */ public boolean isCollapsable() { return collapsable; } /** * Enables or disables animation during expand/collapse transition. * * @param animated * @javabean.property bound="true" * preferred="true" */ public void setAnimated(boolean animated) { if (isAnimated() != animated) { collapsePane.setAnimated(animated); firePropertyChange(ANIMATED_CHANGED_KEY, !isAnimated(), isAnimated()); } } /** * Returns true if this taskpane is animated during expand/collapse * transition. * * @return true if this taskpane is animated during expand/collapse * transition. */ public boolean isAnimated() { return collapsePane.isAnimated(); } /** * Adds an action to this <code>JTaskPaneGroup</code>. Returns a * component built from the action. The returned component has been * added to the <code>JTaskPaneGroup</code>. * * @param action * @return a component built from the action */ public Component add(Action action) { Component c = ((TaskPaneGroupUI) ui).createAction(action); add(c); return c; } public Container getValidatingContainer() { return getParent(); } /** * Overriden to redirect call to the content pane. */ protected void addImpl(Component comp, Object constraints, int index) { getContentPane().add(comp, constraints, index); } /** * Overriden to redirect call to the content pane. */ public void setLayout(LayoutManager mgr) { if (collapsePane != null) { getContentPane().setLayout(mgr); } } /** * Overriden to redirect call to the content pane */ public void remove(Component comp) { getContentPane().remove(comp); } /** * Overriden to redirect call to the content pane. */ public void remove(int index) { getContentPane().remove(index); } /** * Overriden to redirect call to the content pane. */ public void removeAll() { getContentPane().removeAll(); } /** * Overriden to prevent focus to group header when group is not collapsable */ public boolean isFocusable() { return super.isFocusable() && isCollapsable(); } /** * @see JComponent#paramString() */ protected String paramString() { return super.paramString() + ",title=" + getTitle() + ",icon=" + getIcon() + ",expanded=" + String.valueOf(isExpanded()) + "," + "special=" + String.valueOf(isSpecial()) + ",scrollOnExpand=" + String.valueOf(isScrollOnExpand()) + ",ui=" + getUI(); } }