Software Engineer and NASA contractor in the Washington D.C. area. Specializes in Java, the NetBeans Platform, D3.JS and ANSI C. Sean is a DZone MVB and is not an employee of DZone and has posted 9 posts at DZone. You can read more from them at their website. View Full User Profile

From Tabs to TabuLESS for the NetBeans Platform using JavaFX and CSS!

06.19.2013
| 5003 views |
  • submit to reddit

This article will demonstrate several tricks to visually enhance a NetBeans Platform app with JavaFX controls embedded.  It will build upon previous tutorials that demonstrate complete replacements for the default NetBeans Swing components using JavaFX.  Code examples will feature NetBeans Platform, JavaFX and CSS.

Previous tutorials in the Integrating JavaFX with the NetBeans Platform series we showed how to replace the NetBeans Swing MenuBar and Toolbar with JavaFX based Accordion type controls which slide out from the side of the screen.  We called them the AccordionMenu and Accordion Toolbar and they not only freed up valuable vertical space but were also more conducive to Touch Screen displays.  When not in use these controls slide back in and minimize automatically. 

You can find these tutorials here: 

And they are extensions themselves of these great articles written by Geertjan Wielenga:

To fully understand and follow this tutorial you will need to start with the previous tutorials mentioned above. 

Hide the SlideIn Tab and Border 

As nice as Accordion components looked when embedded within a NetBeans Platform Slide In TopComponent, there were little visual issues.  For example a slide-in TopComponent is displayed within a TabDisplayer container component which renders its own border.  So anytime your Slide In component is resized you will likely see this border:



That border is annoying and so is the Tab TitleBar too.  I want to see Geertjan's Blog  not component artifacts.  After much annoying searching I found that the Platform does support hiding these things with a published interface of any kind.  However a little hacking and we can do it.

First Make everything opaque and transparent. Below is my TopComponent constructor modified to support transparency:

public final class SlidingAccordionTopComponent extends TopComponent {
    public AccordionMenu accordionMenu = new AccordionMenu();
    private TopComponent me;
    
    public SlidingAccordionTopComponent() {
        initComponents();
        setName(Bundle.CTL_SlidingAccordionTopComponent());
        setToolTipText(Bundle.HINT_SlidingAccordionTopComponent());
        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_KEEP_PREFERRED_SIZE_WHEN_SLIDED_IN, Boolean.TRUE);

        me = this;
        setLayout(new BorderLayout());
        add(accordionMenu,BorderLayout.CENTER);
        Color transparent = new Color(0.0f, 0.0f, 0.0f, 0.0f);
        setOpaque(true);
        setBackground(transparent);
        accordionMenu.setOpaque(true);
        accordionMenu.setBackground(transparent);
        validate();
    }
Next add the "Tab Control" library dependency to your module. Finally we @Override the TopComponent's componentShowing() to search for the TabDisplayer and hide it and its ugly border:
    @Override
    protected void componentShowing() {
        super.componentShowing(); 
        Container parent = me.getParent();
        Container parent2 = parent.getParent();

        Component [] comps = parent2.getComponents();
        for(int i=0;i<comps.length;i++) {
            if(comps[i].getClass().getName().equals(TabDisplayer.class.getName())) {
                TabDisplayer td = (TabDisplayer)comps[i];
                td.setVisible(false);
            }
            else {
                JPanel theJPanel = (JPanel) comps[i];
                theJPanel.setBorder(BorderFactory.createEmptyBorder());
            }
        }        
        this.validate();
    }

I suppose the way I searched for the TabDisplayer through the ancestor tree is a little hackish but it is quite effective.  Below is the same component with the above fix, rendered in Fullscreen mode:

Style the JavaFX components with CSS

Now that we have visually isolated our JavaFX component from the underlying Swing platform, we can make it look a bit more striking.  Using CSS with JavaFX is nothing new.  Below I merely want to demonstrate the points to add the CSS and what is possible when CSS and JavaFX are combined with the NetBeans Platform. Its tremendously easy to do which of course is the obvious benefit of embedding JavaFX components within the NetBeans Platform in the first place.  Below is the update to my createScene() method where the JavaFX scene is constructed.


        Group g = new Group();        
        Scene scene = new Scene(g, 400, 500,new Color(0.0,0.0,0.0,0.0));
        //PlatformImpl.setDefaultPlatformUserAgentStylesheet();
        //Application.setUserAgentStylesheet(null);
        scene.getStylesheets().add(metroDarkCSS);
        scene.getStylesheets().add(control2CSS);
 
        accordionPane = new Accordion();
        accordionPane.getPanes().addAll(titledPaneList); 
        g.getChildren().add(accordionPane);
        setScene(scene);
        validate();
        setOpaque(true);
        setBackground(new java.awt.Color(0.0f, 0.0f, 0.0f, 0.0f));

Some key points... I've left commented out two lines of code that you may need if you are using an early developers release of JDK 8.  With JDK 7u21 I did not need them. 

I've added two different CSS and they'll mix with each other for some Frankenstienish results but its all fun.  I got the metroDarkCSS sheet from Pedro Duque Vieira.  Amazing job Pedro, honestly way more work then this tutorial really.  Below is just the control2css style sheet:


.root{
    -fx-font-size: 16pt;
    -fx-font-family: "Courier New";
    -fx-base: rgb(132, 145, 47);
    -fx-background: rgb(225, 228, 203);
}

.button{
    -fx-text-fill: rgb(49, 89, 23);
    -fx-border-color: rgb(49, 89, 23);
    -fx-border-radius: 5;
    -fx-padding: 3 6 6 6;
}

.borders{
    -fx-border-color: rgb(103, 100, 78);
    -fx-border-style: dotted;
    -fx-border-width: 1.5;
    -fx-border-insets: -5;
}

And here is what our AccordionMenu component looks like skinned with the control2css style sheet:

Which really looks nice overlayed on a WorldWind tool because it has a cool Earthy look and feel.

Now lets switch to the Dark Metro look:

Not bad... I like the blocky look but not the grey... lets gob them together:

Hey pretty neat.  One thing... notice in the above screenshot the grey bar at the bottom of the menu?  That is where the JavaFX scene extends past the menu components.  But didn't we implement transparency all over the place?  Sure but as of right now JavaFX scenes don't play nice with Z-ordering with Native heavyweight components, which WorldWind is one.  You won't have that problem with any other Swing or JavaFX components of course.

For example lets apply all these types of changes to our similar Toolbar component.  Below is the CSS that I'm inlining to the AccordionToolbar:

newToolbarFromFileObject.setStyle("    -fx-text-fill: rgb(49, 89, 23);\n" +
"    -fx-border-color: rgb(49, 89, 23);\n" +
"    -fx-border-radius: 5;\n" +     
"    -fx-border-style: dotted;" +
"    -fx-border-width: 1.5;"  +
"    -fx-padding: 3 6 6 6;");

and I even mix it with an existing CSS like in the AccordionMenu example above using the scene.getStylesheets().add() pattern.  Below is that CSS:


.root{
    -fx-font-size: 14pt;
    -fx-font-family: "Tahoma";
    -fx-base: #DFB951;
    -fx-background: #A78732;
    -fx-focus-color: #B6A678;
}

.button1{
    -fx-text-fill: #006464;
    -fx-background-color: #DFB951;
    -fx-border-radius: 20;
    -fx-background-radius: 20;
    -fx-padding: 5;
}

.button2{
    -fx-text-fill: #c10000;
    -fx-background-color: #DFB951;
    -fx-border-radius: 20;
    -fx-background-radius: 20;
    -fx-padding: 5;
}

.slider{
    -fx-border-color: white;
    -fx-border-style: dashed;
    -fx-border-width: 2;
}

And we get something like this:

Oh but UGH that TabDisplayer is biting us!!!  Let's apply the tab hack:

Hey that's nice!  We got rid of all the remnants of borders and tabs yet completely retained our access to the Menu and Toolbar.  

Congratulations!  You've gone from tabs... to ** TABULESS **!!

Published at DZone with permission of Sean Phillips, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Sean Phillips replied on Wed, 2013/06/19 - 10:59am

One addendum:

The "**" in  ** TABULESS ** are indicative of flair.

Muhammad Danial replied on Mon, 2014/03/31 - 10:14am

 It will build upon previous tutorials that demonstrate complete replacements for the default NetBeans Swing components using JavaFX.  Code examples will feature NetBeans Platform, JavaFX and CSS. 

Miele fridge repairs (london)

Muhammad Danial replied on Sat, 2014/04/05 - 6:34am

  We called them the AccordionMenu and Accordion Toolbar and they not only freed up valuable vertical space but were also more conducive to Touch Screen displays.  When not in use these controls slide back in and minimize automatically.  

http://www.san-diego-solar.com

Black Men replied on Tue, 2014/04/15 - 6:58am

 It will build upon previous tutorials that demonstrate complete replacements for the default NetBeans Swing components using JavaFX.  Code examples will feature NetBeans Platform, JavaFX and CSS.  

caveman diet

Black Men replied on Fri, 2014/04/18 - 2:47am

  We called them the AccordionMenu and Accordion Toolbar and they not only freed up valuable vertical space but were also more conducive to Touch Screen displays.  When not in use these controls slide back in and minimize automatically.  

the best flight simulator games for ps3

Samad Khatri replied on Sat, 2014/04/19 - 6:28am in response to: Sean Phillips

 admit that I downloaded and watched the E! reality show about these girls, Pretty Wild. Some ingenious producer https://www.rebelmouse.com/undeniablepassionsystemreview/

Samad Khatri replied on Sun, 2014/04/27 - 9:51am in response to: Sean Phillips

 The "**" in  ** TABULESS ** are indicative of flairwww.tapes.com.pl 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.