001: /**
002: * L2FProd.com Common Components 7.3 License.
003: *
004: * Copyright 2005-2007 L2FProd.com
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package com.l2fprod.common.swing;
018:
019: import com.l2fprod.common.swing.plaf.JOutlookBarAddon;
020: import com.l2fprod.common.swing.plaf.LookAndFeelAddons;
021: import com.l2fprod.common.swing.plaf.OutlookBarUI;
022:
023: import java.awt.Color;
024: import java.awt.Component;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.WeakHashMap;
028:
029: import javax.swing.Icon;
030: import javax.swing.JScrollPane;
031: import javax.swing.JTabbedPane;
032: import javax.swing.UIManager;
033: import javax.swing.plaf.TabbedPaneUI;
034:
035: /**
036: * <code>JOutlookBar</code> brings the famous Outlook component to
037: * Swing. The component shows stacks of components where only one
038: * stack is visible at a time. <br>
039: *
040: * The tab orientation of the {@link javax.swing.JTabbedPane}is
041: * mapped to the JOutlookBar orientation as follow:
042: * <ul>
043: * <li>with JTabbedPane.TOP or JTabbedPane.BOTTOM, JOutlookBar will
044: * layout the components horizontally
045: * <li>with JTabbedPane.LEFT or JTabbedPane.RIGHT, JOutlookBar will
046: * layout the components vertically (default)
047: * </ul>
048: *
049: * @javabean.class
050: * name="JOutlookBar"
051: * shortDescription="JOutlookBar brings the famous Outlook component to Swing"
052: * stopClass="javax.swing.JTabbedPane"
053: *
054: * @javabean.icons
055: * mono16="JOutlookBar16-mono.gif"
056: * color16="JOutlookBar16.gif"
057: * mono32="JOutlookBar32-mono.gif"
058: * color32="JOutlookBar32.gif"
059: */
060: public class JOutlookBar extends JTabbedPane {
061:
062: public static final String UI_CLASS_ID = "OutlookBarUI";
063:
064: static {
065: LookAndFeelAddons.contribute(new JOutlookBarAddon());
066: }
067:
068: /**
069: * Used when generating PropertyChangeEvents for the "animated" property
070: */
071: public static final String ANIMATED_CHANGED_KEY = "animated";
072:
073: protected Map extendedPages;
074: private boolean animated = true;
075:
076: /**
077: *
078: */
079: public JOutlookBar() {
080: this (LEFT);
081: }
082:
083: /**
084: * @param tabPlacement
085: */
086: public JOutlookBar(int tabPlacement) {
087: super (tabPlacement, WRAP_TAB_LAYOUT);
088: extendedPages = new WeakHashMap();
089: updateUI();
090: }
091:
092: /**
093: * Notification from the <code>UIManager</code> that the L&F has
094: * changed. Replaces the current UI object with the latest version
095: * from the <code>UIManager</code>.
096: *
097: * @see javax.swing.JComponent#updateUI
098: */
099: public void updateUI() {
100: setUI((OutlookBarUI) LookAndFeelAddons.getUI(this ,
101: OutlookBarUI.class));
102: }
103:
104: /**
105: * Sets the L&F object that renders this component.
106: *
107: * @param ui the <code>OutlookBarUI</code> L&F object
108: * @see javax.swing.UIDefaults#getUI
109: *
110: * @beaninfo bound: true hidden: true description: The UI object
111: * that implements the buttonbar's LookAndFeel.
112: */
113: public void setUI(OutlookBarUI ui) {
114: super .setUI((TabbedPaneUI) ui);
115: }
116:
117: /**
118: * Returns the name of the L&F class that renders this component.
119: *
120: * @return the string {@link #UI_CLASS_ID}
121: * @see javax.swing.JComponent#getUIClassID
122: * @see javax.swing.UIDefaults#getUI
123: */
124: public String getUIClassID() {
125: return UI_CLASS_ID;
126: }
127:
128: /**
129: * Enables or disables animation during tab transition.
130: *
131: * @param animated
132: * @javabean.property
133: * bound="true"
134: * preferred="true"
135: */
136: public void setAnimated(boolean animated) {
137: if (this .animated != animated) {
138: this .animated = animated;
139: firePropertyChange(ANIMATED_CHANGED_KEY, !animated,
140: animated);
141: }
142: }
143:
144: /**
145: * @return true if this taskpane is animated during expand/collapse
146: * transition.
147: */
148: public boolean isAnimated() {
149: return animated;
150: }
151:
152: /**
153: * Builds a JScrollPane to hold the component. By default tabs are
154: * not scrollable. They can be made scrollable by putting them in a
155: * JScrollPane and adding the JScrollPane instead of the tab to the
156: * JOutlookBar. It is recommended to use this method to create the
157: * scrollbar as the UI may choose to return a JScrollPane specially
158: * configured for the JOutlookBar component (ex. with different
159: * scrollbars)
160: *
161: * @param component
162: * @return a JScrollPane with <code>component</code> as view
163: */
164: public JScrollPane makeScrollPane(Component component) {
165: return ((OutlookBarUI) getUI()).makeScrollPane(component);
166: }
167:
168: public void removeTabAt(int index) {
169: checkIndex(index);
170: removeExtendedPage(index);
171: super .removeTabAt(index);
172: }
173:
174: /**
175: * Sets the title alignment for all tabs
176: *
177: * @param alignment
178: * one of {@link javax.swing.SwingConstants#LEFT},
179: * {@link javax.swing.SwingConstants#CENTER},
180: * {@link javax.swing.SwingConstants#RIGHT}.
181: */
182: public void setAllTabsAlignment(int alignment) {
183: for (Iterator iter = extendedPages.values().iterator(); iter
184: .hasNext();) {
185: ExtendedPage page = (ExtendedPage) iter.next();
186: page.setTabAlignment(alignment);
187: }
188: }
189:
190: /**
191: * Sets the title alignment of the tab at <code>index</code>
192: *
193: * @param index
194: * @param alignment
195: * one of {@link javax.swing.SwingConstants#LEFT},
196: * {@link javax.swing.SwingConstants#CENTER},
197: * {@link javax.swing.SwingConstants#RIGHT}.
198: */
199: public void setAlignmentAt(int index, int alignment) {
200: getExtendedPage(index).setTabAlignment(alignment);
201: }
202:
203: /**
204: * @param index
205: * @return the title alignment of the tab at <code>index</code>
206: */
207: public int getAlignmentAt(int index) {
208: return getExtendedPage(index).getTabAlignment();
209: }
210:
211: /**
212: * Overriden to notify the UI about the change
213: */
214: public void setTitleAt(int index, String title) {
215: super .setTitleAt(index, title);
216: firePropertyChange("tabPropertyChangedAtIndex", null,
217: new Integer(index));
218: }
219:
220: /**
221: * Overriden to notify the UI about the change
222: */
223: public void setIconAt(int index, Icon icon) {
224: super .setIconAt(index, icon);
225: firePropertyChange("tabPropertyChangedAtIndex", null,
226: new Integer(index));
227: }
228:
229: public Color getBackgroundAt(int index) {
230: return getExtendedPage(index).getBackground();
231: }
232:
233: /**
234: * Overriden to notify the UI about the change
235: */
236: public void setBackgroundAt(int index, Color background) {
237: getExtendedPage(index).setBackground(background);
238: firePropertyChange("tabPropertyChangedAtIndex", null,
239: new Integer(index));
240: }
241:
242: public Color getForegroundAt(int index) {
243: return getExtendedPage(index).getForeground();
244: }
245:
246: /**
247: * Overriden to notify the UI about the change
248: */
249: public void setForegroundAt(int index, Color foreground) {
250: getExtendedPage(index).setForeground(foreground);
251: firePropertyChange("tabPropertyChangedAtIndex", null,
252: new Integer(index));
253: }
254:
255: /**
256: * Overriden to notify the UI about the change
257: */
258: public void setToolTipTextAt(int index, String toolTipText) {
259: super .setToolTipTextAt(index, toolTipText);
260: firePropertyChange("tabPropertyChangedAtIndex", null,
261: new Integer(index));
262: }
263:
264: /**
265: * Overriden to notify the UI about the change
266: */
267: public void setDisplayedMnemonicIndexAt(int tabIndex,
268: int mnemonicIndex) {
269: super .setDisplayedMnemonicIndexAt(tabIndex, mnemonicIndex);
270: firePropertyChange("tabPropertyChangedAtIndex", null,
271: new Integer(tabIndex));
272: }
273:
274: /**
275: * Overriden to notify the UI about the change
276: */
277: public void setMnemonicAt(int index, int mnemonic) {
278: super .setMnemonicAt(index, mnemonic);
279: firePropertyChange("tabPropertyChangedAtIndex", null,
280: new Integer(index));
281: }
282:
283: /**
284: * Overriden to notify the UI about the change
285: */
286: public void setDisabledIconAt(int index, Icon disabledIcon) {
287: super .setDisabledIconAt(index, disabledIcon);
288: firePropertyChange("tabPropertyChangedAtIndex", null,
289: new Integer(index));
290: }
291:
292: /**
293: * Overriden to notify the UI about the change
294: */
295: public void setEnabledAt(int index, boolean enabled) {
296: super .setEnabledAt(index, enabled);
297: firePropertyChange("tabPropertyChangedAtIndex", null,
298: new Integer(index));
299: }
300:
301: protected void addImpl(Component comp, Object constraints, int index) {
302: if (index != -1) {
303: super .addImpl(comp, constraints, index);
304: } else {
305: // insertTab always add component at the end of the components array
306: // however the look and feel classes of JOutlookBar expect the component
307: // to be in the right order when it calls getComponents().
308: // We must make sure the component gets inserted in the right place
309: int pageIndex = indexOfComponent(comp);
310: if (pageIndex == -1) {
311: super .addImpl(comp, constraints, index);
312: } else {
313: // this is one of our component, attempt to insert it in the right
314: // position
315: super .addImpl(comp, constraints, pageIndex * 2);
316: }
317: }
318: }
319:
320: protected void removeExtendedPage(int index) {
321: Component component = getComponentAt(index);
322: extendedPages.remove(component);
323: }
324:
325: protected ExtendedPage getExtendedPage(int index) {
326: checkIndex(index);
327:
328: Component component = getComponentAt(index);
329: ExtendedPage page = (ExtendedPage) extendedPages.get(component);
330: if (page == null) {
331: page = new ExtendedPage();
332: page.component = component;
333: extendedPages.put(component, page);
334: }
335: return page;
336: }
337:
338: private void checkIndex(int index) {
339: if (index < 0 || index >= getTabCount()) {
340: throw new IndexOutOfBoundsException("Index: " + index
341: + ", Tab count: " + getTabCount());
342: }
343: }
344:
345: private class ExtendedPage {
346: Component component;
347:
348: int alignment = UIManager.getInt("OutlookBar.tabAlignment");
349: Color background = null;
350: Color foreground = null;
351:
352: public void setTabAlignment(int alignment) {
353: if (this .alignment != alignment) {
354: this .alignment = alignment;
355: JOutlookBar.this .firePropertyChange(
356: "tabPropertyChangedAtIndex", null, new Integer(
357: getIndex()));
358: }
359: }
360:
361: public int getIndex() {
362: return indexOfComponent(component);
363: }
364:
365: public int getTabAlignment() {
366: return alignment;
367: }
368:
369: public Color getBackground() {
370: return background;
371: }
372:
373: public void setBackground(Color background) {
374: this .background = background;
375: }
376:
377: public Color getForeground() {
378: return foreground;
379: }
380:
381: public void setForeground(Color foreground) {
382: this.foreground = foreground;
383: }
384:
385: }
386:
387: }
|