Skip to content

How to use WebPopup

Mikle edited this page Jan 30, 2020 · 5 revisions

Available since WebLaF v1.2.9 release, updated for WebLaF v1.2.12 release
Requires weblaf-ui module and Java 6 update 30 or any later to run


What is it for?

WebPopup is a JComponent extension providing easy-to-use and convenient popup window API to replace Swing Popup and PopupFactory which have quite a few limitations and issues. It provides transparent access to the underlying WebPopupWindow it uses to display itself as a heavyweight popup and can be easily configured and re-styled in runtime. It is also used as a base for WebNotification and WebDynamicMenu custom WebLaF components.


What should I know about it?

WebPopup uses WebPopupWindow, based on JWindow, to display itself. WebPopup handles all window configurations on its own based on the popup settings and style provided.

There are quite a few settings you can configure:

  • resizable - Whether or not this popup should be resizable
  • closeOnOuterAction - Whether or not should close popup on any action outside of this popup
  • closeOnFocusLoss - Whether should close popup on focus loss or not
  • followInvoker - Whether or not popup should follow invoker's window
  • alwaysOnTop - Whether or not popup window should always be on top of other windows
  • opacity - Popup window opacity
  • animate - Whether should fade popup in/out on display/hide or not
  • fadeStepSize - Single fade step size, should be larger than 0f and lesser than 1f

A visible invoker component should always be provided into any of WebPopup.showPopup methods used to display the popup. Invoker is used to determine popup position on the screen and also used as a parent window for WebPopupWindow which is very important to avoid various native issues with window focus handling.

One more important thing about WebPopup is that unlike Swing Popup implementation it allows focusable component within itself and they will properly obtain focus and function in the way they would on a normal frame or dialog. This might be a quite important thing if you want to have a popup with not just information, but some interactive UI as well.


How to use it?

WebPopup usage is very similar to JPopupMenu usage, here is a short example:

public class SimplePopup
{
    public static void main ( final String[] args )
    {
        SwingUtilities.invokeLater ( new Runnable ()
        {
            @Override
            public void run ()
            {
                WebLookAndFeel.install ();

                final WebPopup popup = new WebPopup ();
                popup.add ( new WebLabel ( "Sample content", WebLabel.CENTER ) );

                final WebButton button = new WebButton ( "Show popup" );
                button.addActionListener ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        popup.showPopup ( button, 0, button.getHeight () );
                    }
                } );

                TestFrame.show ( button, 150 );
            }
        } );
    }
}

And here is what you should see:

WebPopup

WebPopup always get packed to its preferred size on display. To make its initial size bigger you need to either provide an appropriate content or set WebPopup preferred size to some specific value, for example:

popup.setPreferredSize ( 150, 100 );

And here is how it would look like now:

WebPopup

Now let's try to move the parent window and see what happens:

WebPopup

Popup is not really attached to anything that is why it haven't moved anywhere from its position, but you can configure it to follow its invoker:

popup.setFollowInvoker ( true );

That way it will always keep itself relative to its invoker.


How to style it?

If you are new to WebLaF styling system - I recommend reading Styling Introduction wiki article first. It explains how styling works in WebLaF and has a bunch of code examples for you to try out.

WebPopup only has two default styles - StyleId.popup and StyleId.popupUndecorated. Those are enough for most general cases, but some additional styling would never hurt.

WebPopup has its own type for the style - popup - which you need to specify in any style you will be attaching to the popup. Style for WebPopup itself is the same as a style for any plain panel.

Let's create a custom-looking popup with a larger shadow and some more colors.

First of all we will need a skin extension with our custom style:

<skin xmlns="http://weblookandfeel.com/XmlSkinExtension">

    <!-- Extension settings -->
    <id>weblaf.wiki.popup</id>
    <extends>weblaf.light.skin</extends>
    <extends>weblaf.dark.skin</extends>

    <style type="popup" id="styled">
        <painter>
            <decorations>
                <decoration>
                    <WebShape round="6" />
                    <WebShadow type="outer" width="15" />
                    <LineBorder color="170,170,170" />
                    <GradientBackground>
                        <color>white</color>
                        <color>223,223,223</color>
                    </GradientBackground>
                </decoration>
            </decorations>
        </painter>
    </style>

</skin>

And we need to register that extension to use provided style:

public class StyledPopup
{
    public static void main ( final String[] args )
    {
        SwingUtilities.invokeLater ( new Runnable ()
        {
            @Override
            public void run ()
            {
                WebLookAndFeel.install ();
                StyleManager.addExtensions ( new XmlSkinExtension (
                        new ClassResource ( StyledPopup.class, "extension.xml" )
                ) );

                final WebPopup popup = new WebPopup ( StyleId.of ( "styled" ) );
                popup.setFollowInvoker ( true );
                popup.add ( new WebLabel ( "Sample content", WebLabel.CENTER ) );
                popup.setPreferredSize ( 150, 100 );

                final WebButton button = new WebButton ( "Show popup" );
                button.addActionListener ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        final int x = button.getWidth () / 2 - popup.getPreferredSize ().width / 2;
                        final int y = button.getHeight ();
                        popup.showPopup ( button, x, y );
                    }
                } );

                TestFrame.show ( button, 150 );
            }
        } );
    }
}

Now we can launch our example and see how it would look like:

WebPopup

This is just a simple example of styling a popup - you can of course use more complicated shape, custom shadow, border and background or even provide some preset IContent implementations if you want to.