com.alee.extended.panel.WebCollapsiblePane Maven / Gradle / Ivy
/*
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WebLookAndFeel library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WebLookAndFeel library. If not, see .
*/
package com.alee.extended.panel;
import com.alee.extended.icon.OrientedIcon;
import com.alee.extended.label.WebVerticalLabel;
import com.alee.global.StyleConstants;
import com.alee.laf.WebLookAndFeel;
import com.alee.laf.button.WebButton;
import com.alee.laf.label.WebLabel;
import com.alee.laf.panel.WebPanel;
import com.alee.managers.hotkey.Hotkey;
import com.alee.managers.language.LanguageManager;
import com.alee.managers.language.LanguageMethods;
import com.alee.managers.language.updaters.LanguageUpdater;
import com.alee.managers.settings.DefaultValue;
import com.alee.managers.settings.SettingsManager;
import com.alee.managers.settings.SettingsMethods;
import com.alee.managers.settings.SettingsProcessor;
import com.alee.utils.CollectionUtils;
import com.alee.utils.ImageUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.laf.ShapeProvider;
import com.alee.utils.swing.DataProvider;
import com.alee.utils.swing.WebTimer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
/**
* This extended components allows you to quickly create and manipulate a collapsible pane.
* Pane title, content and style can be modified in any way you like.
*
* @author Mikle Garin
*/
public class WebCollapsiblePane extends WebPanel implements SwingConstants, ShapeProvider, LanguageMethods, SettingsMethods
{
/**
* Whether animate transition between states or not.
*/
protected boolean animate = WebCollapsiblePaneStyle.animate;
/**
* Collapsed state icon.
*/
protected ImageIcon expandIcon = WebCollapsiblePaneStyle.expandIcon;
/**
* Expanded state icon.
*/
protected ImageIcon collapseIcon = WebCollapsiblePaneStyle.collapseIcon;
/**
* State icon margin.
*/
protected Insets stateIconMargin = WebCollapsiblePaneStyle.stateIconMargin;
/**
* Whether rotate state icon according to title pane position or not.
*/
protected boolean rotateStateIcon = WebCollapsiblePaneStyle.rotateStateIcon;
/**
* Whether display state icon in title pane or not.
*/
protected boolean showStateIcon = WebCollapsiblePaneStyle.showStateIcon;
/**
* State icon position in title pane.
*/
protected int stateIconPostion = WebCollapsiblePaneStyle.stateIconPostion;
/**
* Title pane position in collapsible pane.
*/
protected int titlePanePostion = WebCollapsiblePaneStyle.titlePanePostion;
/**
* Content margin.
*/
protected Insets contentMargin = WebCollapsiblePaneStyle.contentMargin;
/**
* Collapsible pane listeners.
*/
protected List listeners = new ArrayList ( 1 );
/**
* Cached collapsed state icon.
*/
protected ImageIcon cachedExpandIcon = null;
/**
* Cached disabled collapsed state icon.
*/
protected ImageIcon cachedDisabledExpandIcon = null;
/**
* Cached expanded state icon.
*/
protected ImageIcon cachedCollapseIcon = null;
/**
* Cached disabled expanded state icon.
*/
protected ImageIcon cachedDisabledCollapseIcon = null;
/**
* Handler that dynamically enable and disable collapsible pane state changes by providing according boolean value.
*/
protected DataProvider stateChangeHandler = null;
/**
* Whether collapsible pane is expanded or not.
*/
protected boolean expanded = true;
/**
* Current collapsible pane transition progress.
* When pane is fully expanded this variable becomes 1f.
* When pane is fully collapsed this variable becomes 0f.
*/
protected float transitionProgress = 1f;
/**
* Collapsible pane expand and collapse speed.
*/
protected float expandSpeed = 0.1f;
/**
* State change animation timer.
*/
protected WebTimer animator = null;
/**
* Whether custom title component is set or not.
*/
protected boolean customTitle = false;
/**
* Header panel.
*/
protected WebPanel headerPanel;
/**
* Title component.
*/
protected Component titleComponent;
/**
* State change button.
*/
protected WebButton expandButton;
/**
* Content panel.
*/
protected WebPanel contentPanel;
/**
* Collapsible pane content.
*/
protected Component content = null;
/**
* Constructs empty collapsible pane.
*/
public WebCollapsiblePane ()
{
this ( "" );
}
/**
* Constructs empty collapsible pane with specified title text.
*
* @param title collapsible pane title text
*/
public WebCollapsiblePane ( final String title )
{
this ( null, title );
}
/**
* Constructs empty collapsible pane with specified title icon and text.
*
* @param icon collapsible pane title icon
* @param title collapsible pane title text
*/
public WebCollapsiblePane ( final ImageIcon icon, final String title )
{
this ( icon, title, null );
}
/**
* Constructs collapsible pane with specified title text and content.
*
* @param title collapsible pane title text
* @param content collapsible pane content
*/
public WebCollapsiblePane ( final String title, final Component content )
{
this ( null, title, content );
}
/**
* Constructs collapsible pane with specified title icon, text and content.
*
* @param icon collapsible pane title icon
* @param title collapsible pane title text
* @param content collapsible pane content
*/
public WebCollapsiblePane ( final Icon icon, final String title, final Component content )
{
super ();
// todo Handle enable/disable
// putClientProperty ( SwingUtils.HANDLES_ENABLE_STATE, true );
this.content = content;
setFocusable ( true );
setPaintFocus ( true );
setUndecorated ( false );
setWebColoredBackground ( false );
setRound ( StyleConstants.smallRound );
setLayout ( new BorderLayout ( 0, 0 ) );
// Header
headerPanel = new WebPanel ();
headerPanel.setOpaque ( true );
headerPanel.setUndecorated ( false );
headerPanel.setShadeWidth ( 0 );
headerPanel.setLayout ( new BorderLayout () );
headerPanel.addMouseListener ( new MouseAdapter ()
{
@Override
public void mouseReleased ( final MouseEvent e )
{
if ( isAllowAction ( e ) )
{
invertExpandState ();
takeFocus ();
}
}
private boolean isAllowAction ( final MouseEvent e )
{
return SwingUtilities.isLeftMouseButton ( e ) && SwingUtils.size ( WebCollapsiblePane.this ).contains ( e.getPoint () );
}
} );
headerPanel.addKeyListener ( new KeyAdapter ()
{
@Override
public void keyReleased ( final KeyEvent e )
{
if ( Hotkey.ENTER.isTriggered ( e ) || Hotkey.SPACE.isTriggered ( e ) )
{
invertExpandState ();
}
}
} );
updateHeaderPosition ();
updateDefaultTitleComponent ( icon, title );
updateDefaultTitleBorder ();
expandButton = new WebButton ( collapseIcon );
expandButton.setUndecorated ( true );
expandButton.setFocusable ( false );
expandButton.setMoveIconOnPress ( false );
expandButton.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
invertExpandState ();
takeFocus ();
}
} );
setStateIcons ();
updateStateIconMargin ();
updateStateIconPosition ();
// Content
contentPanel = new WebPanel ()
{
@Override
public Dimension getPreferredSize ()
{
final Dimension ps = super.getPreferredSize ();
if ( titlePanePostion == TOP || titlePanePostion == BOTTOM )
{
if ( WebCollapsiblePane.this.content != null )
{
final Insets insets = getInsets ();
ps.width = insets.left + WebCollapsiblePane.this.content.getPreferredSize ().width + insets.right;
}
if ( transitionProgress < 1f )
{
ps.height = Math.round ( ps.height * transitionProgress );
}
}
else
{
if ( WebCollapsiblePane.this.content != null )
{
final Insets insets = getInsets ();
ps.height = insets.top + WebCollapsiblePane.this.content.getPreferredSize ().height + insets.bottom;
}
if ( transitionProgress < 1f )
{
ps.width = Math.round ( ps.width * transitionProgress );
}
}
return ps;
}
};
contentPanel.setOpaque ( false );
contentPanel.setLayout ( new BorderLayout ( 0, 0 ) );
contentPanel.setMargin ( contentMargin );
add ( contentPanel, BorderLayout.CENTER );
if ( this.content != null )
{
contentPanel.add ( this.content, BorderLayout.CENTER );
}
addPropertyChangeListener ( WebLookAndFeel.ORIENTATION_PROPERTY, new PropertyChangeListener ()
{
@Override
public void propertyChange ( final PropertyChangeEvent evt )
{
updateStateIcons ();
}
} );
}
/**
* Transfers application focus to this collapsible pane.
*/
protected void takeFocus ()
{
if ( isShowing () && isEnabled () )
{
if ( isFocusable () )
{
requestFocusInWindow ();
}
else
{
transferFocus ();
}
}
}
/**
* Updates default title component.
*/
protected void updateDefaultTitleComponent ()
{
updateDefaultTitleComponent ( getIcon (), getTitle () );
}
/**
* Updates default title component with the specified title icon and text.
*
* @param icon collapsible pane title icon
* @param title collapsible pane title text
*/
protected void updateDefaultTitleComponent ( final Icon icon, final String title )
{
if ( !customTitle )
{
if ( titleComponent != null )
{
headerPanel.remove ( titleComponent );
}
titleComponent = createDefaultTitleComponent ( icon, title );
headerPanel.add ( titleComponent, BorderLayout.CENTER );
}
}
/**
* Updates default title component border.
*/
protected void updateDefaultTitleBorder ()
{
if ( titleComponent != null && !customTitle )
{
// todo Proper updates for RTL
// boolean ltr = getComponentOrientation ().isLeftToRight ();
// Updating title margin according to title pane position
Insets margin = getIcon () != null || titlePanePostion != LEFT || titlePanePostion == RIGHT ? new Insets ( 2, 2, 2, 2 ) :
new Insets ( 2, 4, 2, 2 );
if ( titlePanePostion == LEFT )
{
margin = new Insets ( margin.right, margin.top, margin.left, margin.bottom );
}
else if ( titlePanePostion == RIGHT )
{
margin = new Insets ( margin.left, margin.bottom, margin.right, margin.top );
}
( ( WebLabel ) titleComponent ).setMargin ( margin );
}
}
/**
* Updates header panel position.
*/
protected void updateHeaderPosition ()
{
updateHeaderSides ();
if ( titlePanePostion == TOP )
{
add ( headerPanel, BorderLayout.NORTH );
}
else if ( titlePanePostion == BOTTOM )
{
add ( headerPanel, BorderLayout.SOUTH );
}
else if ( titlePanePostion == LEFT )
{
add ( headerPanel, BorderLayout.LINE_START );
}
else if ( titlePanePostion == RIGHT )
{
add ( headerPanel, BorderLayout.LINE_END );
}
revalidate ();
}
/**
* Updates header panel sides style.
*/
protected void updateHeaderSides ()
{
headerPanel.setPaintSides ( expanded && titlePanePostion == BOTTOM, expanded && titlePanePostion == RIGHT,
expanded && titlePanePostion == TOP, expanded && titlePanePostion == LEFT );
}
/**
* Updates state icon position.
*/
protected void updateStateIconPosition ()
{
if ( showStateIcon )
{
if ( titlePanePostion == TOP || titlePanePostion == BOTTOM )
{
headerPanel.add ( expandButton, stateIconPostion == RIGHT ? BorderLayout.LINE_END : BorderLayout.LINE_START );
}
else if ( titlePanePostion == LEFT )
{
headerPanel.add ( expandButton, stateIconPostion == RIGHT ? BorderLayout.PAGE_START : BorderLayout.PAGE_END );
}
else if ( titlePanePostion == RIGHT )
{
headerPanel.add ( expandButton, stateIconPostion == RIGHT ? BorderLayout.PAGE_END : BorderLayout.PAGE_START );
}
}
else
{
headerPanel.remove ( expandButton );
}
headerPanel.revalidate ();
}
/**
* Updates state icon margin.
*/
protected void updateStateIconMargin ()
{
expandButton.setMargin ( stateIconMargin );
}
/**
* Returns new default title component with specified icon and text.
*
* @param title collapsible pane title text
* @param icon collapsible pane title icon
* @return new default title component with specified icon and text
*/
protected JComponent createDefaultTitleComponent ( final Icon icon, final String title )
{
// todo RTL orientation support
final WebLabel defaultTitle;
if ( titlePanePostion == LEFT )
{
defaultTitle = new WebVerticalLabel ( title, icon, WebLabel.LEADING, false );
}
else if ( titlePanePostion == RIGHT )
{
defaultTitle = new WebVerticalLabel ( title, icon, WebLabel.LEADING, true );
}
else
{
defaultTitle = new WebLabel ( title, icon, WebLabel.LEADING );
}
defaultTitle.setDrawShade ( true );
return defaultTitle;
}
/**
* Returns handler that dynamically enable and disable collapsible pane state changes by providing according boolean value.
*
* @return state change handler
*/
public DataProvider getStateChangeHandler ()
{
return stateChangeHandler;
}
/**
* Sets handler that dynamically enable and disable collapsible pane state changes by providing according boolean value.
*
* @param stateChangeHandler new state change handler
*/
public void setStateChangeHandler ( final DataProvider stateChangeHandler )
{
this.stateChangeHandler = stateChangeHandler;
}
/**
* Returns whether collapsible pane state change is enabled or not.
*
* @return true if collapsible pane state change is enabled, false otherwise
*/
public boolean isStateChangeEnabled ()
{
return stateChangeHandler == null || stateChangeHandler.provide ();
}
/**
* Returns whether collapsible pane is performing animated transition at the moment or not.
*
* @return true if collapsible pane is performing animated transition at the moment, false otherwise
*/
public boolean isAnimating ()
{
return animator != null && animator.isRunning ();
}
/**
* Changes expanded state to opposite and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @return true if operation succeed, false otherwise
*/
public boolean invertExpandState ()
{
return invertExpandState ( animate );
}
/**
* Changes expanded state to opposite and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @param animate whether animate state change transition or not
* @return true if operation succeed, false otherwise
*/
public boolean invertExpandState ( final boolean animate )
{
return setExpanded ( !isExpanded (), animate );
}
/**
* Returns whether this collapsible pane is expanded or not.
*
* @return true if this collapsible pane is expanded, false otherwise
*/
public boolean isExpanded ()
{
return expanded;
}
/**
* Changes expanded state to specified one and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @return true if operation succeed, false otherwise
*/
public boolean setExpanded ( final boolean expanded )
{
return setExpanded ( expanded, isShowing () && animate );
}
/**
* Changes expanded state to specified one and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @param animate whether animate state change transition or not
* @return true if operation succeed, false otherwise
*/
public boolean setExpanded ( final boolean expanded, final boolean animate )
{
if ( isEnabled () )
{
if ( expanded )
{
return expand ( animate );
}
else
{
return collapse ( animate );
}
}
return false;
}
/**
* Changes expanded state to collapsed and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @return true if operation succeed, false otherwise
*/
public boolean collapse ()
{
return collapse ( animate );
}
/**
* Changes expanded state to collapsed and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @param animate whether animate state change transition or not
* @return true if operation succeed, false otherwise
*/
public boolean collapse ( final boolean animate )
{
if ( !expanded || !isStateChangeEnabled () )
{
return false;
}
stopAnimation ();
expanded = false;
setStateIcons ();
fireCollapsing ();
if ( animate && isShowing () )
{
animator = new WebTimer ( "WebCollapsiblePane.collapseTimer", StyleConstants.fastAnimationDelay, new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( transitionProgress > 0f )
{
transitionProgress = Math.max ( 0f, transitionProgress - expandSpeed );
revalidate ();
}
else
{
transitionProgress = 0f;
finishCollapseAction ();
animator.stop ();
}
}
} );
animator.start ();
}
else
{
transitionProgress = 0f;
finishCollapseAction ();
}
return true;
}
/**
* Finishes collapse action.
*/
protected void finishCollapseAction ()
{
// Hide title border
updateHeaderSides ();
// Hide content
if ( content != null )
{
content.setVisible ( false );
}
// Update collapsible pane
revalidate ();
repaint ();
// Inform about event
fireCollapsed ();
}
/**
* Changes expanded state to expanded and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @return true if operation succeed, false otherwise
*/
public boolean expand ()
{
return expand ( animate );
}
/**
* Changes expanded state to expanded and returns whether operation succeed or not.
* Operation might fail in case state change is disabled for some reason.
*
* @param animate whether animate state change transition or not
* @return true if operation succeed, false otherwise
*/
public boolean expand ( final boolean animate )
{
if ( expanded || !isStateChangeEnabled () )
{
return false;
}
stopAnimation ();
expanded = true;
setStateIcons ();
if ( content != null )
{
content.setVisible ( true );
}
// Show title border
updateHeaderSides ();
fireExpanding ();
if ( animate && isShowing () )
{
animator = new WebTimer ( "WebCollapsiblePane.expandTimer", StyleConstants.fastAnimationDelay, new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( transitionProgress < 1f )
{
transitionProgress = Math.min ( 1f, transitionProgress + expandSpeed );
revalidate ();
}
else
{
transitionProgress = 1f;
finishExpandAction ();
animator.stop ();
}
}
} );
animator.start ();
}
else
{
transitionProgress = 1f;
finishExpandAction ();
}
return true;
}
/**
* Finishes expand action.
*/
protected void finishExpandAction ()
{
// Update collapsible pane
revalidate ();
repaint ();
// Inform about event
fireExpanded ();
}
/**
* Stops state transition animation.
*/
protected void stopAnimation ()
{
if ( animator != null && animator.isRunning () )
{
animator.stop ();
}
}
/**
* Returns title pane position in collapsible pane.
*
* @return title pane position in collapsible pane
*/
public int getTitlePanePostion ()
{
return titlePanePostion;
}
/**
* Sets title pane position in collapsible pane.
*
* @param titlePanePostion new title pane position in collapsible pane
*/
public void setTitlePanePostion ( final int titlePanePostion )
{
this.titlePanePostion = titlePanePostion;
updateDefaultTitleComponent ();
updateDefaultTitleBorder ();
updateHeaderPosition ();
updateStateIcons ();
updateStateIconPosition ();
}
/**
* Returns content margin.
*
* @return content margin
*/
public Insets getContentMargin ()
{
return contentMargin;
}
/**
* Sets content margin.
*
* @param margin content margin
*/
public void setContentMargin ( final Insets margin )
{
this.contentMargin = margin;
contentPanel.setMargin ( margin );
revalidate ();
}
/**
* Sets content margin.
*
* @param top top content margin
* @param left left content margin
* @param bottom bottom content margin
* @param right right content margin
*/
public void setContentMargin ( final int top, final int left, final int bottom, final int right )
{
setContentMargin ( new Insets ( top, left, bottom, right ) );
}
/**
* Sets content margin.
*
* @param margin content margin
*/
public void setContentMargin ( final int margin )
{
setContentMargin ( margin, margin, margin, margin );
}
/**
* Returns whether animate transition between states or not.
*
* @return true if animate transition between states, false otherwise
*/
public boolean isAnimate ()
{
return animate;
}
/**
* Sets whether animate transition between states or not
*
* @param animate whether animate transition between states or not
*/
public void setAnimate ( final boolean animate )
{
this.animate = animate;
}
/**
* Returns default title component icon.
*
* @return default title component icon
*/
public Icon getIcon ()
{
return customTitle ? null : ( ( WebLabel ) titleComponent ).getIcon ();
}
/**
* Sets default title component icon.
*
* @param icon new default title component icon
*/
public void setIcon ( final Icon icon )
{
if ( !customTitle )
{
( ( WebLabel ) titleComponent ).setIcon ( icon );
updateDefaultTitleBorder ();
}
}
/**
* Returns default title component text.
*
* @return default title component text
*/
public String getTitle ()
{
return customTitle ? null : ( ( WebLabel ) titleComponent ).getText ();
}
/**
* Sets default title component text.
*
* @param title new default title component text
*/
public void setTitle ( final String title )
{
if ( !customTitle )
{
( ( WebLabel ) titleComponent ).setText ( title );
}
}
/**
* Sets default title component text alignment.
*
* @param alignment new default title component text alignment
*/
public void setTitleAlignment ( final int alignment )
{
if ( !customTitle )
{
( ( WebLabel ) titleComponent ).setHorizontalAlignment ( alignment );
}
}
/**
* Returns expanded state icon.
*
* @return expanded state icon
*/
public ImageIcon getCollapseIcon ()
{
return collapseIcon;
}
/**
* Sets expanded state icon.
*
* @param collapseIcon new expanded state icon
*/
public void setCollapseIcon ( final ImageIcon collapseIcon )
{
this.collapseIcon = collapseIcon;
clearCachedCollapseIcons ();
setStateIcons ();
}
/**
* Returns collapsed state icon.
*
* @return collapsed state icon
*/
public ImageIcon getExpandIcon ()
{
return expandIcon;
}
/**
* Sets collapsed state icon.
*
* @param expandIcon new collapsed state icon
*/
public void setExpandIcon ( final ImageIcon expandIcon )
{
this.expandIcon = expandIcon;
clearCachedExpandIcons ();
setStateIcons ();
}
/**
* Returns state icon margin.
*
* @return state icon margin
*/
public Insets getStateIconMargin ()
{
return stateIconMargin;
}
/**
* Sets state icon margin.
*
* @param margin new state icon margin
*/
public void setStateIconMargin ( final Insets margin )
{
this.stateIconMargin = margin;
updateStateIconMargin ();
}
/**
* Returns whether rotate state icon according to title pane position or not.
*
* @return true if stat icon must be rotated according to title pane position, false otherwise
*/
public boolean isRotateStateIcon ()
{
return rotateStateIcon;
}
/**
* Sets whether rotate state icon according to title pane position or not.
*
* @param rotateStateIcon whether rotate state icon according to title pane position or not
*/
public void setRotateStateIcon ( final boolean rotateStateIcon )
{
this.rotateStateIcon = rotateStateIcon;
updateStateIcons ();
}
/**
* Returns whether display state icon in title pane or not.
*
* @return true if state icon must be displayed in title pane, false otherwise
*/
public boolean isShowStateIcon ()
{
return showStateIcon;
}
/**
* Sets whether display state icon in title pane or not.
*
* @param showStateIcon whether display state icon in title pane or not
*/
public void setShowStateIcon ( final boolean showStateIcon )
{
this.showStateIcon = showStateIcon;
updateStateIconPosition ();
}
/**
* Returns state icon position in title pane.
*
* @return state icon position in title pane
*/
public int getStateIconPostion ()
{
return stateIconPostion;
}
/**
* Sets state icon position in title pane.
*
* @param stateIconPostion new state icon position in title pane
*/
public void setStateIconPostion ( final int stateIconPostion )
{
this.stateIconPostion = stateIconPostion;
updateStateIconPosition ();
}
/**
* Updates state icons.
*/
protected void updateStateIcons ()
{
clearCachedCollapseIcons ();
clearCachedExpandIcons ();
setStateIcons ();
}
/**
* Installs state icons into state change button.
*/
protected void setStateIcons ()
{
if ( expanded )
{
expandButton.setIcon ( getCachedCollapseIcon () );
expandButton.setDisabledIcon ( getCachedDisabledCollapseIcon () );
}
else
{
expandButton.setIcon ( getCachedExpandIcon () );
expandButton.setDisabledIcon ( getCachedDisabledExpandIcon () );
}
}
/**
* Clears cached expanded state icons.
*/
protected void clearCachedCollapseIcons ()
{
cachedCollapseIcon = null;
cachedDisabledCollapseIcon = null;
}
/**
* Returns cached expanded state icon.
*
* @return cached expanded state icon
*/
protected ImageIcon getCachedCollapseIcon ()
{
if ( cachedCollapseIcon == null )
{
// todo Proper icon for RTL
// boolean ltr = getComponentOrientation ().isLeftToRight ();
if ( !rotateStateIcon || titlePanePostion == TOP || titlePanePostion == BOTTOM )
{
cachedCollapseIcon = new OrientedIcon ( collapseIcon );
}
else if ( titlePanePostion == LEFT )
{
cachedCollapseIcon = ImageUtils.rotateImage90CCW ( collapseIcon );
}
else if ( titlePanePostion == RIGHT )
{
cachedCollapseIcon = ImageUtils.rotateImage90CW ( collapseIcon );
}
}
return cachedCollapseIcon;
}
/**
* Returns cached disabled expanded state icon.
*
* @return cached disabled expanded state icon
*/
protected ImageIcon getCachedDisabledCollapseIcon ()
{
if ( cachedDisabledCollapseIcon == null )
{
cachedDisabledCollapseIcon = ImageUtils.createDisabledCopy ( getCachedCollapseIcon () );
}
return cachedDisabledCollapseIcon;
}
/**
* Clears cached collapsed state icons.
*/
protected void clearCachedExpandIcons ()
{
cachedExpandIcon = null;
cachedDisabledExpandIcon = null;
}
/**
* Returns cached collapsed state icon.
*
* @return cached collapsed state icon
*/
protected ImageIcon getCachedExpandIcon ()
{
if ( cachedExpandIcon == null )
{
final boolean ltr = getComponentOrientation ().isLeftToRight ();
if ( !rotateStateIcon || titlePanePostion == TOP || titlePanePostion == BOTTOM )
{
cachedExpandIcon = expandIcon;
}
else if ( ltr ? titlePanePostion == LEFT : titlePanePostion == RIGHT )
{
cachedExpandIcon = ImageUtils.rotateImage90CCW ( expandIcon );
}
else if ( ltr ? titlePanePostion == RIGHT : titlePanePostion == LEFT )
{
cachedExpandIcon = ImageUtils.rotateImage90CW ( expandIcon );
}
}
return cachedExpandIcon;
}
/**
* Returns cached disabled collapsed state icon.
*
* @return cached disabled collapsed state icon
*/
protected ImageIcon getCachedDisabledExpandIcon ()
{
if ( cachedDisabledExpandIcon == null )
{
cachedDisabledExpandIcon = ImageUtils.createDisabledCopy ( getCachedExpandIcon () );
}
return cachedDisabledExpandIcon;
}
/**
* Returns header panel.
*
* @return header panel
*/
public WebPanel getHeaderPanel ()
{
return headerPanel;
}
/**
* Returns state change button.
*
* @return state change button
*/
public WebButton getExpandButton ()
{
return expandButton;
}
/**
* Returns title component.
*
* @return title component
*/
public Component getTitleComponent ()
{
return titleComponent;
}
/**
* Sets custom title component.
*
* @param titleComponent new custom title component
*/
public void setTitleComponent ( final Component titleComponent )
{
if ( this.titleComponent != null )
{
headerPanel.remove ( this.titleComponent );
}
if ( titleComponent != null )
{
headerPanel.add ( titleComponent, BorderLayout.CENTER );
}
this.titleComponent = titleComponent;
this.customTitle = true;
}
/**
* Returns collapsible pane content.
*
* @return collapsible pane content
*/
public Component getContent ()
{
return content;
}
/**
* Sets collapsible pane content.
*
* @param content new collapsible pane content
*/
public void setContent ( final Component content )
{
if ( this.content != null )
{
contentPanel.remove ( this.content );
}
this.content = content;
content.setVisible ( transitionProgress > 0f );
contentPanel.add ( content, BorderLayout.CENTER );
revalidate ();
}
/**
* Returns collapsible pane listeners.
*
* @return collapsible pane listeners
*/
public List getCollapsiblePaneListeners ()
{
return CollectionUtils.copy ( listeners );
}
/**
* Sets collapsible pane listeners.
*
* @param listeners new collapsible pane listeners
*/
public void setCollapsiblePaneListeners ( final List listeners )
{
this.listeners = listeners;
}
/**
* Adds collapsible pane listener.
*
* @param listener collapsible pane listener to add
*/
public void addCollapsiblePaneListener ( final CollapsiblePaneListener listener )
{
listeners.add ( listener );
}
/**
* Removes collapsible pane listener.
*
* @param listener collapsible pane listener to remove
*/
public void removeCollapsiblePaneListener ( final CollapsiblePaneListener listener )
{
listeners.remove ( listener );
}
/**
* Notifies when collapsible pane starts to expand.
*/
public void fireExpanding ()
{
for ( final CollapsiblePaneListener listener : CollectionUtils.copy ( listeners ) )
{
listener.expanding ( this );
}
}
/**
* Notifies when collapsible pane finished expanding.
*/
public void fireExpanded ()
{
for ( final CollapsiblePaneListener listener : CollectionUtils.copy ( listeners ) )
{
listener.expanded ( this );
}
}
/**
* Notifies when collapsible pane starts to collapse.
*/
public void fireCollapsing ()
{
for ( final CollapsiblePaneListener listener : CollectionUtils.copy ( listeners ) )
{
listener.collapsing ( this );
}
}
/**
* Notifies when collapsible pane finished collapsing.
*/
public void fireCollapsed ()
{
for ( final CollapsiblePaneListener listener : CollectionUtils.copy ( listeners ) )
{
listener.collapsed ( this );
}
}
/**
* Returns current collapsible pane transition progress.
* Returns 1f when pane is fully expanded and 0f when pane is fully collapsed.
*
* @return current collapsible pane transition progress
*/
public float getTransitionProgress ()
{
return transitionProgress;
}
/**
* Returns preferred size without taking collapsible pane content into account.
*
* @return preferred size without taking collapsible pane content into account
*/
public Dimension getBasePreferredSize ()
{
final Dimension ps = getPreferredSize ();
if ( content == null || transitionProgress <= 0 )
{
return ps;
}
else
{
final Dimension cps = content.getPreferredSize ();
if ( titlePanePostion == TOP || titlePanePostion == BOTTOM )
{
return new Dimension ( ps.width, ps.height - Math.round ( cps.height * transitionProgress ) );
}
else
{
return new Dimension ( ps.width - Math.round ( cps.width * transitionProgress ), ps.height );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void setLanguage ( final String key, final Object... data )
{
LanguageManager.registerComponent ( this, key, data );
}
/**
* {@inheritDoc}
*/
@Override
public void updateLanguage ( final Object... data )
{
LanguageManager.updateComponent ( this, data );
}
/**
* {@inheritDoc}
*/
@Override
public void updateLanguage ( final String key, final Object... data )
{
LanguageManager.updateComponent ( this, key, data );
}
/**
* {@inheritDoc}
*/
@Override
public void removeLanguage ()
{
LanguageManager.unregisterComponent ( this );
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLanguageSet ()
{
return LanguageManager.isRegisteredComponent ( this );
}
/**
* {@inheritDoc}
*/
@Override
public void setLanguageUpdater ( final LanguageUpdater updater )
{
LanguageManager.registerLanguageUpdater ( this, updater );
}
/**
* {@inheritDoc}
*/
@Override
public void removeLanguageUpdater ()
{
LanguageManager.unregisterLanguageUpdater ( this );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key )
{
SettingsManager.registerComponent ( this, key );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key, final Class defaultValueClass )
{
SettingsManager.registerComponent ( this, key, defaultValueClass );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key, final Object defaultValue )
{
SettingsManager.registerComponent ( this, key, defaultValue );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String group, final String key )
{
SettingsManager.registerComponent ( this, group, key );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String group, final String key, final Class defaultValueClass )
{
SettingsManager.registerComponent ( this, group, key, defaultValueClass );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String group, final String key, final Object defaultValue )
{
SettingsManager.registerComponent ( this, group, key, defaultValue );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key, final boolean loadInitialSettings, final boolean applySettingsChanges )
{
SettingsManager.registerComponent ( this, key, loadInitialSettings, applySettingsChanges );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key, final Class defaultValueClass,
final boolean loadInitialSettings, final boolean applySettingsChanges )
{
SettingsManager.registerComponent ( this, key, defaultValueClass, loadInitialSettings, applySettingsChanges );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String key, final Object defaultValue, final boolean loadInitialSettings,
final boolean applySettingsChanges )
{
SettingsManager.registerComponent ( this, key, defaultValue, loadInitialSettings, applySettingsChanges );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String group, final String key, final Class defaultValueClass,
final boolean loadInitialSettings, final boolean applySettingsChanges )
{
SettingsManager.registerComponent ( this, group, key, defaultValueClass, loadInitialSettings, applySettingsChanges );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final String group, final String key, final Object defaultValue, final boolean loadInitialSettings,
final boolean applySettingsChanges )
{
SettingsManager.registerComponent ( this, group, key, defaultValue, loadInitialSettings, applySettingsChanges );
}
/**
* {@inheritDoc}
*/
@Override
public void registerSettings ( final SettingsProcessor settingsProcessor )
{
SettingsManager.registerComponent ( this, settingsProcessor );
}
/**
* {@inheritDoc}
*/
@Override
public void unregisterSettings ()
{
SettingsManager.unregisterComponent ( this );
}
/**
* {@inheritDoc}
*/
@Override
public void loadSettings ()
{
SettingsManager.loadComponentSettings ( this );
}
/**
* {@inheritDoc}
*/
@Override
public void saveSettings ()
{
SettingsManager.saveComponentSettings ( this );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy