?? jcollapsiblepane.java
字號:
/**
* L2FProd.com Common Components 6.9.1 License.
*
* Copyright 2005-2006 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 java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
/**
* <code>JCollapsiblePane</code> provides a component which can collapse or
* expand its content area with animation and fade in/fade out effects.
* It also acts as a standard container for other Swing components.
*
* <p>
* In this example, the <code>JCollapsiblePane</code> is used to build
* a Search pane which can be shown and hidden on demand.
*
* <pre>
* <code>
* JCollapsiblePane cp = new JCollapsiblePane();
*
* // JCollapsiblePane can be used like any other container
* cp.setLayout(new BorderLayout());
*
* // the Controls panel with a textfield to filter the tree
* JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 0));
* controls.add(new JLabel("Search:"));
* controls.add(new JTextField(10));
* controls.add(new JButton("Refresh"));
* controls.setBorder(new TitledBorder("Filters"));
* cp.add("Center", controls);
*
* JFrame frame = new JFrame();
* frame.setLayout(new BorderLayout());
*
* // Put the "Controls" first
* frame.add("North", cp);
*
* // Then the tree - we assume the Controls would somehow filter the tree
* JScrollPane scroll = new JScrollPane(new JTree());
* frame.add("Center", scroll);
*
* // Show/hide the "Controls"
* JButton toggle = new JButton(cp.getActionMap().get(JCollapsiblePane.TOGGLE_ACTION));
* toggle.setText("Show/Hide Search Panel");
* frame.add("South", toggle);
*
* frame.pack();
* frame.setVisible(true);
* </code>
* </pre>
*
* <p>
* Note: <code>JCollapsiblePane</code> requires its parent container to have a
* {@link java.awt.LayoutManager} using {@link #getPreferredSize()} when
* calculating its layout (example {@link com.l2fprod.common.swing.PercentLayout},
* {@link java.awt.BorderLayout}).
*
* @javabean.attribute
* name="isContainer"
* value="Boolean.TRUE"
* rtexpr="true"
*
* @javabean.attribute
* name="containerDelegate"
* value="getContentPane"
*
* @javabean.class
* name="JCollapsiblePane"
* shortDescription="A pane which hides its content with an animation."
* stopClass="java.awt.Component"
*
* @author rbair (from the JDNC project)
* @author <a href="mailto:fred@L2FProd.com">Frederic Lavigne</a>
*/
public class JCollapsiblePane extends JPanel {
/**
* Used when generating PropertyChangeEvents for the "animationState" property
*/
public final static String ANIMATION_STATE_KEY = "animationState";
/**
* JCollapsible has a built-in toggle action which can be bound to buttons.
* Accesses the action through
* <code>collapsiblePane.getActionMap().get(JCollapsiblePane.TOGGLE_ACTION)</code>.
*/
public final static String TOGGLE_ACTION = "toggle";
/**
* The icon used by the "toggle" action when the JCollapsiblePane is
* expanded, i.e the icon which indicates the pane can be collapsed.
*/
public final static String COLLAPSE_ICON = "collapseIcon";
/**
* The icon used by the "toggle" action when the JCollapsiblePane is
* collapsed, i.e the icon which indicates the pane can be expanded.
*/
public final static String EXPAND_ICON = "expandIcon";
/**
* Indicates whether the component is collapsed or expanded
*/
private boolean collapsed = false;
/**
* Timer used for doing the transparency animation (fade-in)
*/
private Timer animateTimer;
private AnimationListener animator;
private int currentHeight = -1;
private WrapperContainer wrapper;
private boolean useAnimation = true;
private AnimationParams animationParams;
/**
* Constructs a new JCollapsiblePane with a {@link JPanel} as content pane and
* a vertical {@link PercentLayout} with a gap of 2 pixels as layout manager.
*/
public JCollapsiblePane() {
super.setLayout(new BorderLayout(0, 0));
JPanel panel = new JPanel();
panel.setLayout(new PercentLayout(PercentLayout.VERTICAL, 2));
setContentPane(panel);
animator = new AnimationListener();
setAnimationParams(new AnimationParams(30, 8, 0.01f, 1.0f));
// add an action to automatically toggle the state of the pane
getActionMap().put(TOGGLE_ACTION, new ToggleAction());
}
/**
* Toggles the JCollapsiblePane state and updates its icon based on the
* JCollapsiblePane "collapsed" status.
*/
private class ToggleAction extends AbstractAction implements
PropertyChangeListener {
public ToggleAction() {
super(TOGGLE_ACTION);
updateIcon();
// the action must track the collapsed status of the pane to update its
// icon
JCollapsiblePane.this.addPropertyChangeListener("collapsed", this);
}
public void putValue(String key, Object newValue) {
super.putValue(key, newValue);
if (EXPAND_ICON.equals(key) || COLLAPSE_ICON.equals(key)) {
updateIcon();
}
}
public void actionPerformed(ActionEvent e) {
setCollapsed(!isCollapsed());
}
public void propertyChange(PropertyChangeEvent evt) {
updateIcon();
}
void updateIcon() {
if (isCollapsed()) {
putValue(SMALL_ICON, getValue(EXPAND_ICON));
} else {
putValue(SMALL_ICON, getValue(COLLAPSE_ICON));
}
}
}
/**
* Sets the content pane of this JCollapsiblePane. Components must be added
* to this content pane, not to the JCollapsiblePane.
*
* @param contentPanel
* @throws IllegalArgumentException
* if contentPanel is null
*/
public void setContentPane(Container contentPanel) {
if (contentPanel == null) {
throw new IllegalArgumentException("Content pane can't be null");
}
if (wrapper != null) {
super.remove(wrapper);
}
wrapper = new WrapperContainer(contentPanel);
super.addImpl(wrapper, BorderLayout.CENTER, -1);
}
/**
* @return the content pane
*/
public Container getContentPane() {
return wrapper.c;
}
/**
* Overriden to redirect call to the content pane.
*/
public void setLayout(LayoutManager mgr) {
// wrapper can be null when setLayout is called by "super()" constructor
if (wrapper != null) {
getContentPane().setLayout(mgr);
}
}
/**
* 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 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();
}
/**
* If true, enables the animation when pane is collapsed/expanded. If false,
* animation is turned off.
*
* <p>
* When animated, the <code>JCollapsiblePane</code> will progressively
* reduce (when collapsing) or enlarge (when expanding) the height of its
* content area until it becomes 0 or until it reaches the preferred height of
* the components it contains. The transparency of the content area will also
* change during the animation.
*
* <p>
* If not animated, the <code>JCollapsiblePane</code> will simply hide
* (collapsing) or show (expanding) its content area.
*
* @param animated
* @javabean.property bound="true" preferred="true"
*/
public void setAnimated(boolean animated) {
if (animated != useAnimation) {
useAnimation = animated;
firePropertyChange("animated", !useAnimation, useAnimation);
}
}
/**
* @return true if the pane is animated, false otherwise
* @see #setAnimated(boolean)
*/
public boolean isAnimated() {
return useAnimation;
}
/**
* @return true if the pane is collapsed, false if expanded
*/
public boolean isCollapsed() {
return collapsed;
}
/**
* Expands or collapses this <code>JCollapsiblePane</code>.
*
* <p>
* If the component is collapsed and <code>val</code> is false, then this
* call expands the JCollapsiblePane, such that the entire JCollapsiblePane
* will be visible. If {@link #isAnimated()} returns true, the expansion will
* be accompanied by an animation.
*
* <p>
* However, if the component is expanded and <code>val</code> is true, then
* this call collapses the JCollapsiblePane, such that the entire
* JCollapsiblePane will be invisible. If {@link #isAnimated()} returns true,
* the collapse will be accompanied by an animation.
*
* @see #isAnimated()
* @see #setAnimated(boolean)
* @javabean.property
* bound="true"
* preferred="true"
*/
public void setCollapsed(boolean val) {
if (collapsed != val) {
collapsed = val;
if (isAnimated()) {
if (collapsed) {
setAnimationParams(new AnimationParams(30, Math.max(8, wrapper
.getHeight() / 10), 1.0f, 0.01f));
animator.reinit(wrapper.getHeight(), 0);
animateTimer.start();
} else {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -