Closed mgarin closed 4 years ago
I quickly checked if this can be implemented added it right away because I didn't require any extensive changes at all. You will now be able to provide StyleId
for any particular Tab
component that are used in WebLaF's JTabbedPane
UI implementation.
To give a small example, here is a random tabbed pane:
public class TabStyleTest
{
public static void main ( final String[] args )
{
SwingTest.run ( new Runnable ()
{
@Override
public void run ()
{
final WebTabbedPane tabbedPane = new WebTabbedPane ();
tabbedPane.addTab ( "Tab 1", WebLookAndFeel.getIcon ( 16 ), createContent () );
tabbedPane.addTab ( "Tab 2", WebLookAndFeel.getIcon ( 16 ), createContent () );
tabbedPane.addTab ( "Tab 3", WebLookAndFeel.getIcon ( 16 ), createContent () );
tabbedPane.addTab ( "Tab 4", WebLookAndFeel.getIcon ( 16 ), createContent () );
TestFrame.show ( tabbedPane );
}
private Component createContent ()
{
final JLabel label = new JLabel ( "Sample content", JLabel.CENTER );
label.setPreferredSize ( new Dimension ( 400, 300 ) );
return label;
}
} );
}
}
There are two methods now available in WebTabbedPane
to change Tab
's style:
/**
* Changes {@link StyleId} for {@link Tab} component at the specified index.
* Use this method to provide a standalone {@link StyleId} for any particular {@link Tab}.
*
* @param index {@link Tab} index
* @param styleId new {@link StyleId}
*/
public void setStyleIdAt ( final int index, @NotNull final StyleId styleId )
{
firePropertyChange ( STYLE_ID_AT_PROPERTY, null, new Object[]{ index, styleId } );
}
/**
* Changes {@link StyleId} for {@link Tab} component at the specified index.
* Use this method to provide a {@link StyleId} with {@link TabContainer} as parent for any particular {@link Tab}.
* Resulting {@link StyleId} will be retrieved through {@link ChildStyleId#at(JComponent)} with {@link TabContainer} provided.
*
* @param index {@link Tab} index
* @param styleId new {@link ChildStyleId}, {@link TabContainer} will become it's parent
*/
public void setStyleIdAt ( final int index, @NotNull final ChildStyleId styleId )
{
firePropertyChange ( STYLE_ID_AT_PROPERTY, null, new Object[]{ index, styleId } );
}
First, here is what will happen with a custom standalone style:
tabbedPane.setStyleIdAt ( 1, StyleId.styledlabelVerticalCCW );
Note: Since each Tab
(component that is used for representing each tab in JTabbedPane
) is basically a WebStyledLabel
- I simply used an existing styledlabel
style with text rotation.
Result:
It obviously lost all custom tab decorations because normal styledlabel
styles do not support custom Tab
states. This will most probably not suffice for any particular case, so there are two options:
Tab
styleFirst you will need a custom styledlabel
style:
<!-- Custom tab title -->
<style type="styledlabel" id="mytab" padding="4">
<painter>
<decorations>
<decoration>
<WebShape round="3" sides="1,1,0,1" />
<WebShadow type="outer" width="2" />
<LineBorder color="170,170,170" />
<GradientBackground>
<color>white</color>
<color>223,223,223</color>
</GradientBackground>
<LabelLayout>
<LabelIcon constraints="icon" />
<TabText constraints="text" color="60,60,60" />
</LabelLayout>
</decoration>
<decoration states="hover">
<ColorBackground color="210,210,210" />
<LabelLayout>
<TabText constraints="text" color="black" />
</LabelLayout>
</decoration>
</decorations>
</painter>
</style>
Next you provide it for the particular tab:
tabbedPane.setStyleIdAt ( 1, StyleId.of ( "mytab" ) );
This is an oversimplified example, but it works for our basic case:
Pros: No need to deal with complicated default Tab
styling
Cons: Might be a lot of work (or copy-paste) if you want to preserve most of default Tab
styling
Tab
styleFirst you will need to make a custom tabbedpane
style with an extra tab style in it:
<!-- Tabbed pane with extra custom tab styles -->
<style type="tabbedpane" id="mytabbedpane">
<style type="panel" id="tab-area">
<style type="viewport" id="viewport">
<style type="panel" id="container">
<!-- Bridge to the default tab style so we can extend it below -->
<style type="styledlabel" id="tab" />
<!-- Our custom extra tab title style -->
<style type="styledlabel" id="mytab" extends="tab">
<painter>
<decorations>
<decoration states="has-no-children,selected">
<ColorBackground color="41,33,114" />
<LabelLayout>
<TabText color="white" />
</LabelLayout>
</decoration>
<decoration states="has-no-children,selected,in-focused-parent">
<LabelLayout>
<TabText color="white" />
</LabelLayout>
</decoration>
</decorations>
</painter>
</style>
</style>
</style>
</style>
</style>
And we will need to define both JTabbedPane
and particular tab styles:
final WebTabbedPane tabbedPane = new WebTabbedPane ( StyleId.of ( "mytabbedpane" ) );
...
tabbedPane.setStyleIdAt ( 1, ChildStyleId.of ( "mytab" ) );
Result:
This will probably work better for simple cases when tab style needs to be slightly customized and not fully replaced. It does look more complicated, but mostly due to a large styles structure that is used for all different JTabbedPane
parts - that structure have to be preserved in the custom style so that we can keep the overall default look of JTabbedPane
.
Pros: Default Tab
styling is preserved unless explicitly modified
Cons: More complicated to setup since custom StyleId
also needs to be provided in JTabbedPane
itself on top of custom StyleId
for particular Tab
You can also use 1st approach and simply fully copy-paste the default tab style:
<!-- Tab title -->
<style type="styledlabel" id="tab" padding="6,10,6,8">
<component>
<horizontalAlignment>0</horizontalAlignment>
</component>
<painter>
<decorations overwrite="true">
<decoration>
<BoundsShape />
<ColorBackground color="237,237,237" />
<Stripes orientation="horizontal" align="bottom" bounds="margin">
<Stripe>
<color>170,170,170</color>
</Stripe>
</Stripes>
</decoration>
<decoration states="left">
<Stripes orientation="vertical" align="right" bounds="margin" />
</decoration>
<decoration states="right">
<Stripes orientation="vertical" align="left" bounds="margin" />
</decoration>
<decoration states="bottom">
<Stripes align="top" />
</decoration>
<decoration states="enabled,hover">
<ColorBackground color="218,218,218" />
</decoration>
<decoration states="selected">
<ColorBackground color="white" />
<Stripes>
<Stripe stroke="basic;5">
<color>156,167,184</color>
</Stripe>
</Stripes>
</decoration>
<decoration states="enabled,selected,hover">
<ColorBackground color="218,218,218" />
</decoration>
<decoration states="selected,in-focused-parent">
<Stripes>
<Stripe stroke="basic;5">
<color>64,131,201</color>
</Stripe>
</Stripes>
</decoration>
<decoration states="has-no-children">
<LabelLayout>
<LabelIcon constraints="icon" />
<TabText constraints="text" color="60,60,60" />
</LabelLayout>
</decoration>
<decoration states="has-no-children,hover">
<LabelLayout>
<TabText color="black" />
</LabelLayout>
</decoration>
<decoration states="has-no-children,selected">
<LabelLayout>
<TabText color="black" />
</LabelLayout>
</decoration>
<decoration states="has-no-children,selected,in-focused-parent">
<LabelLayout>
<TabText color="0,50,160" />
</LabelLayout>
</decoration>
<decoration states="has-no-children,disabled">
<LabelLayout>
<TabText color="180,180,180" ignoreCustomColor="true" ignoreStyleColors="true" />
</LabelLayout>
</decoration>
</decorations>
</painter>
</style>
But I would not recommend that unless you are ready to copy-paste all future changes/adjustments in the default tab style to your custom tab style. It will become exponentially harder with each new skin you are going to support.
There is a small catch with styling specific tabs though - unfortunately the menu available with tab scroll layout would still display the default styling for all tabs, including the one you customized.
I might look into possible options later on, but overall it would be hard to workaround that in current implementation without providing a separate custom style for the menu item. It might generally not be worth the hassle.
Right now there is no easy way to restyle any particular tab, tab style can only be modified based on existing states (hover/selected/disabled).
A good way would be adding
setStyleIdAt ( int, StyleId )
method inWebTabbedPane
to allow customization of any particular tab to your liking with a custom style.It is important to note that the custom style would need to provide all default decorations or extend existing default style, otherwise tab will have no extra decorations except for the provided ones. I'll add some examples here once this feature is implemented.