com.alee.extended.accordion.AccordionPane 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.accordion;
import com.alee.api.Identifiable;
import com.alee.api.annotations.NotNull;
import com.alee.api.annotations.Nullable;
import com.alee.api.data.BoxOrientation;
import com.alee.extended.collapsible.AbstractControlButton;
import com.alee.extended.collapsible.AbstractHeaderPanel;
import com.alee.extended.collapsible.AbstractTitleLabel;
import com.alee.extended.collapsible.HeaderLayout;
import com.alee.laf.panel.WebPanel;
import com.alee.managers.style.StyleId;
import com.alee.utils.SwingUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
/**
* {@link AccordionPane} for a single collapsible content {@link Component} within {@link WebAccordion}.
* This is basically a collapsible panel made and optimized specifically for {@link WebAccordion} needs.
* It doesn't have it's own UI but uses some abstract UI elements from {@link com.alee.extended.collapsible.WebCollapsiblePane}.
*
* @author Mikle Garin
* @see How to use WebAccordion
* @see WebAccordion
* @see AccordionModel
* @see WebAccordionModel
*/
public class AccordionPane extends WebPanel implements Identifiable
{
/**
* {@link AccordionPane} unique identifier.
*/
@NotNull
protected final String id;
/**
* Header {@link Component}.
*/
@NotNull
protected Component header;
/**
* Content {@link Component}.
*/
@NotNull
protected Component content;
/**
* Constructs new {@link AccordionPane}.
*
* @param accordion {@link WebAccordion} this {@link AccordionPane} is created for
* @param id unique {@link AccordionPane} identifier
* @param icon {@link AccordionPane} title icon
* @param title {@link AccordionPane} title
* @param content {@link Component} which this {@link AccordionPane} describes
*/
public AccordionPane ( @NotNull final WebAccordion accordion, @NotNull final String id,
@Nullable final Icon icon, @Nullable final String title, @NotNull final Component content )
{
this ( StyleId.accordionPane.at ( accordion ), accordion, id, icon, title, content );
}
/**
* Constructs new {@link AccordionPane}.
*
* @param styleId {@link StyleId}
* @param accordion {@link WebAccordion} this {@link AccordionPane} is created for
* @param id {@link AccordionPane} unique identifier
* @param icon {@link AccordionPane} title icon
* @param title {@link AccordionPane} title
* @param content {@link Component} which this {@link AccordionPane} describes
*/
public AccordionPane ( @NotNull final StyleId styleId, @NotNull final WebAccordion accordion, @NotNull final String id,
@Nullable final Icon icon, @Nullable final String title, @NotNull final Component content )
{
super ( styleId );
this.id = id;
this.header = createHeaderComponent ( icon, title );
add ( this.header );
this.content = content;
add ( this.content );
}
@Override
@NotNull
public String getId ()
{
return id;
}
/**
* Returns header {@link Component}.
*
* @return header {@link Component}
*/
@NotNull
public Component getHeader ()
{
return header;
}
/**
* Replaces header {@link Component}.
*
* @param header new header {@link Component}
*/
public void setHeader ( @NotNull final Component header )
{
remove ( this.header );
this.header = header;
add ( this.header );
SwingUtils.update ( this );
}
/**
* Returns content {@link Component}.
*
* @return content {@link Component}
*/
@NotNull
public Component getContent ()
{
return content;
}
/**
* Replaces content {@link Component}.
*
* @param content new content {@link Component}
*/
public void setContent ( @NotNull final Component content )
{
remove ( this.content );
this.content = content;
add ( this.content );
SwingUtils.update ( this );
}
/**
* Returns newly created header {@link Component}.
*
* @param icon header {@link Icon}
* @param title header title
* @return newly created header {@link Component}
*/
@NotNull
protected JComponent createHeaderComponent ( @Nullable final Icon icon, @Nullable final String title )
{
final AbstractHeaderPanel headerPanel = new AbstractHeaderPanel ( StyleId.accordionPaneHeaderPanel.at ( this ) )
{
@Override
@NotNull
public BoxOrientation getHeaderPosition ()
{
return AccordionPane.this.getHeaderPosition ();
}
@Override
public boolean isExpanded ()
{
return AccordionPane.this.isExpanded ();
}
@Override
public boolean isInTransition ()
{
return AccordionPane.this.isInTransition ();
}
@Override
protected void onHeaderAction ( @NotNull final InputEvent e )
{
expandOrCollapse ( e );
}
};
headerPanel.add ( createTitleComponent ( headerPanel, icon, title ), HeaderLayout.TITLE );
headerPanel.add ( createControlComponent ( headerPanel ), HeaderLayout.CONTROL );
return headerPanel;
}
/**
* Returns newly created title {@link Component}.
*
* @param header header {@link JComponent}
* @param icon header {@link Icon}
* @param title header title
* @return newly created title {@link Component}
*/
@NotNull
protected JComponent createTitleComponent ( @NotNull final JComponent header, @Nullable final Icon icon, @Nullable final String title )
{
final AbstractTitleLabel titleLabel = new AbstractTitleLabel ( StyleId.accordionPaneTitleLabel.at ( header ) )
{
@Override
@NotNull
public BoxOrientation getHeaderPosition ()
{
return AccordionPane.this.getHeaderPosition ();
}
@Override
public boolean isExpanded ()
{
return AccordionPane.this.isExpanded ();
}
@Override
public boolean isInTransition ()
{
return AccordionPane.this.isInTransition ();
}
};
titleLabel.setIcon ( icon );
titleLabel.setText ( title );
return titleLabel;
}
/**
* Returns newly created control {@link Component}.
*
* @param header header {@link JComponent}
* @return newly created control {@link Component}
*/
@NotNull
protected JComponent createControlComponent ( @NotNull final JComponent header )
{
return new AbstractControlButton ( StyleId.accordionPaneControlButton.at ( header ) )
{
@Override
@NotNull
public BoxOrientation getHeaderPosition ()
{
return AccordionPane.this.getHeaderPosition ();
}
@Override
public boolean isExpanded ()
{
return AccordionPane.this.isExpanded ();
}
@Override
public boolean isInTransition ()
{
return AccordionPane.this.isInTransition ();
}
@Override
protected void onControlAction ( @NotNull final ActionEvent e )
{
expandOrCollapse ( e );
}
};
}
/**
* Either expands or collapses this {@link AccordionPane}.
*
* @param e {@link AWTEvent}
*/
protected void expandOrCollapse ( final AWTEvent e )
{
final Container parent = AccordionPane.this.getParent ();
if ( parent instanceof WebAccordion )
{
final WebAccordion accordion = ( WebAccordion ) parent;
if ( isExpanded () )
{
accordion.collapse ( getId () );
}
else
{
accordion.expand ( getId () );
}
if ( e instanceof MouseEvent || e instanceof ActionEvent )
{
if ( accordion.isShowing () )
{
if ( accordion.isFocusable () )
{
accordion.requestFocusInWindow ();
}
else
{
AccordionPane.this.transferFocus ();
}
}
}
}
}
/**
* Returns unique view identifier.
*
* @return unique view identifier
*/
@NotNull
public String id ()
{
return id;
}
/**
* Returns {@link Component} which this {@link AccordionPane} describes.
*
* @return {@link Component} which this {@link AccordionPane} describes
*/
@NotNull
public Component component ()
{
return content;
}
/**
* Returns header panel position.
*
* @return header panel position
*/
@NotNull
public BoxOrientation getHeaderPosition ()
{
final Container parent = getParent ();
return parent instanceof WebAccordion ? ( ( WebAccordion ) parent ).getHeaderPosition () : BoxOrientation.top;
}
/**
* Returns whether or not this {@link AccordionPane} is expanded.
*
* @return {@code true} if this {@link AccordionPane} is expanded, {@code false} otherwise
*/
public boolean isExpanded ()
{
final Container parent = getParent ();
return parent instanceof WebAccordion && ( ( WebAccordion ) parent ).isExpanded ( getId () );
}
/**
* Returns whether or not {@link AccordionPane} is in transition to either of two expansion states.
*
* @return {@code true} if {@link AccordionPane} is in transition, {@code false} otherwise
*/
public boolean isInTransition ()
{
final Container parent = getParent ();
return parent instanceof WebAccordion && ( ( WebAccordion ) parent ).isInTransition ( getId () );
}
/**
* Returns minimum size in pixels of a single {@link AccordionPane}'s content.
* Can be any value from {@code 0} to any reasonable amount of pixels you want for each {@link AccordionPane}'s content.
* It is used instead of the content's preferred size to ensure that {@link WebAccordion} preserves it's preferred size at all times.
* Otherwise whenever you expand/collapse something {@link WebAccordion} preferred size would vary wildly and negatively affect layout.
*
* @return minimum size in pixels of a single {@link AccordionPane}'s content
*/
public int getMinimumPaneContentSize ()
{
final Container parent = getParent ();
return parent instanceof WebAccordion ? ( ( WebAccordion ) parent ).getMinimumPaneContentSize () : 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy