/** * 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.JOutlookBarAddon; import com.l2fprod.common.swing.plaf.LookAndFeelAddons; import com.l2fprod.common.swing.plaf.OutlookBarUI; import javax.swing.*; import javax.swing.plaf.TabbedPaneUI; import java.awt.*; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; /** * <code>JOutlookBar</code> brings the famous Outlook component to * Swing. The component shows stacks of components where only one * stack is visible at a time. <br> * <p/> * The tab orientation of the {@link javax.swing.JTabbedPane}is * mapped to the JOutlookBar orientation as follow: * <ul> * <li>with JTabbedPane.TOP or JTabbedPane.BOTTOM, JOutlookBar will * layout the components horizontally * <li>with JTabbedPane.LEFT or JTabbedPane.RIGHT, JOutlookBar will * layout the components vertically (default) * </ul> * * @javabean.class name="JOutlookBar" * shortDescription="JOutlookBar brings the famous Outlook component to Swing" * stopClass="javax.swing.JTabbedPane" * @javabean.icons mono16="JOutlookBar16-mono.gif" * color16="JOutlookBar16.gif" * mono32="JOutlookBar32-mono.gif" * color32="JOutlookBar32.gif" */ public class JOutlookBar extends JTabbedPane { public static final String UI_CLASS_ID = "OutlookBarUI"; static { LookAndFeelAddons.contribute(new JOutlookBarAddon()); } /** * Used when generating PropertyChangeEvents for the "animated" property */ public static final String ANIMATED_CHANGED_KEY = "animated"; protected Map extendedPages; private boolean animated = true; /** * */ public JOutlookBar() { this(LEFT); } /** * @param tabPlacement */ public JOutlookBar(int tabPlacement) { super(tabPlacement, WRAP_TAB_LAYOUT); extendedPages = new WeakHashMap(); updateUI(); } /** * 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() { setUI((OutlookBarUI) LookAndFeelAddons.getUI(this, OutlookBarUI.class)); } /** * Sets the L&F object that renders this component. * * @param ui the <code>OutlookBarUI</code> L&F object * @beaninfo bound: true hidden: true description: The UI object * that implements the buttonbar's LookAndFeel. * @see javax.swing.UIDefaults#getUI */ public void setUI(OutlookBarUI ui) { super.setUI((TabbedPaneUI) 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; } /** * Enables or disables animation during tab transition. * * @param animated * @javabean.property bound="true" * preferred="true" */ public void setAnimated(boolean animated) { if (this.animated != animated) { this.animated = animated; firePropertyChange(ANIMATED_CHANGED_KEY, !animated, animated); } } /** * @return true if this taskpane is animated during expand/collapse * transition. */ public boolean isAnimated() { return animated; } /** * Builds a JScrollPane to hold the component. By default tabs are * not scrollable. They can be made scrollable by putting them in a * JScrollPane and adding the JScrollPane instead of the tab to the * JOutlookBar. It is recommended to use this method to create the * scrollbar as the UI may choose to return a JScrollPane specially * configured for the JOutlookBar component (ex. with different * scrollbars) * * @param component * @return a JScrollPane with <code>component</code> as view */ public JScrollPane makeScrollPane(Component component) { return ((OutlookBarUI) getUI()).makeScrollPane(component); } public void removeTabAt(int index) { checkIndex(index); removeExtendedPage(index); super.removeTabAt(index); } /** * Sets the title alignment for all tabs * * @param alignment one of {@link javax.swing.SwingConstants#LEFT}, * {@link javax.swing.SwingConstants#CENTER}, * {@link javax.swing.SwingConstants#RIGHT}. */ public void setAllTabsAlignment(int alignment) { for (Iterator iter = extendedPages.values().iterator(); iter.hasNext(); ) { ExtendedPage page = (ExtendedPage) iter.next(); page.setTabAlignment(alignment); } } /** * Sets the title alignment of the tab at <code>index</code> * * @param index * @param alignment one of {@link javax.swing.SwingConstants#LEFT}, * {@link javax.swing.SwingConstants#CENTER}, * {@link javax.swing.SwingConstants#RIGHT}. */ public void setAlignmentAt(int index, int alignment) { getExtendedPage(index).setTabAlignment(alignment); } /** * @param index * @return the title alignment of the tab at <code>index</code> */ public int getAlignmentAt(int index) { return getExtendedPage(index).getTabAlignment(); } /** * Overriden to notify the UI about the change */ public void setTitleAt(int index, String title) { super.setTitleAt(index, title); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } /** * Overriden to notify the UI about the change */ public void setIconAt(int index, Icon icon) { super.setIconAt(index, icon); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } public Color getBackgroundAt(int index) { return getExtendedPage(index).getBackground(); } /** * Overriden to notify the UI about the change */ public void setBackgroundAt(int index, Color background) { getExtendedPage(index).setBackground(background); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } public Color getForegroundAt(int index) { return getExtendedPage(index).getForeground(); } /** * Overriden to notify the UI about the change */ public void setForegroundAt(int index, Color foreground) { getExtendedPage(index).setForeground(foreground); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } /** * Overriden to notify the UI about the change */ public void setToolTipTextAt(int index, String toolTipText) { super.setToolTipTextAt(index, toolTipText); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } /** * Overriden to notify the UI about the change */ public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex) { super.setDisplayedMnemonicIndexAt(tabIndex, mnemonicIndex); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(tabIndex)); } /** * Overriden to notify the UI about the change */ public void setMnemonicAt(int index, int mnemonic) { super.setMnemonicAt(index, mnemonic); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } /** * Overriden to notify the UI about the change */ public void setDisabledIconAt(int index, Icon disabledIcon) { super.setDisabledIconAt(index, disabledIcon); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } /** * Overriden to notify the UI about the change */ public void setEnabledAt(int index, boolean enabled) { super.setEnabledAt(index, enabled); firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(index)); } protected void addImpl(Component comp, Object constraints, int index) { if (index != -1) { super.addImpl(comp, constraints, index); } else { // insertTab always add component at the end of the components array // however the look and feel classes of JOutlookBar expect the component // to be in the right order when it calls getComponents(). // We must make sure the component gets inserted in the right place int pageIndex = indexOfComponent(comp); if (pageIndex == -1) { super.addImpl(comp, constraints, index); } else { // this is one of our component, attempt to insert it in the right // position super.addImpl(comp, constraints, pageIndex * 2); } } } protected void removeExtendedPage(int index) { Component component = getComponentAt(index); extendedPages.remove(component); } protected ExtendedPage getExtendedPage(int index) { checkIndex(index); Component component = getComponentAt(index); ExtendedPage page = (ExtendedPage) extendedPages.get(component); if (page == null) { page = new ExtendedPage(); page.component = component; extendedPages.put(component, page); } return page; } private void checkIndex(int index) { if (index < 0 || index >= getTabCount()) { throw new IndexOutOfBoundsException("Index: " + index + ", Tab count: " + getTabCount()); } } private class ExtendedPage { Component component; int alignment = UIManager.getInt("OutlookBar.tabAlignment"); Color background = null; Color foreground = null; public void setTabAlignment(int alignment) { if (this.alignment != alignment) { this.alignment = alignment; JOutlookBar.this.firePropertyChange("tabPropertyChangedAtIndex", null, new Integer(getIndex())); } } public int getIndex() { return indexOfComponent(component); } public int getTabAlignment() { return alignment; } public Color getBackground() { return background; } public void setBackground(Color background) { this.background = background; } public Color getForeground() { return foreground; } public void setForeground(Color foreground) { this.foreground = foreground; } } }