Česky   |  Deutsch   |  English   |  Español   |  Français   |  Indonesia   |  日本語   |  한글   |  Polski   |  Português (BR)   |  Türkçe   |  中文   |  正體中文   |  Your Language  
PlanetNetbeans
Planet NetBeans is an aggregation of NetBeans related musings from all over the Blogosphere.
Feeds
[RSS 1.0 Feed] [RSS 2.0 Feed]
[FOAF Subscriptions] [OPML Subscriptions]
Do you blog about NetBeans ? Add your blog to PlanetNetBeans.
Feed Subscriptions
NetBeans Zone - The social network for developers (feed)
APIDesign - Blogs (feed)
Pandaconstantin (feed)
blogtrader - Blog (feed)
David R. Heffelfinger (feed)
Winston Prakash's Weblog (feed)
markiewb's blog (feed)
Gualtiero Testa » Netbeans (feed)
James Selvakumar's Blog » netbeans (feed)
nB gUru » NetBeans (feed)
Newsintegrator Blog » netbeans (feed)
Praxis LIVE » NetBeans (feed)
ProNetBeans (feed)
TechAshram » NetBeans (feed)
There's no place like 127.0.0.1 » Netbeans (feed)
Carsten Zerbst's Weblog (feed)
Paulo Canedo » NetBeans English (feed)
Anchialas' Java Blog (feed)
Need to find a title (feed)
Roger Searjeant's blog (feed)
Optonline Webmail (feed)
Michael's blog » NetBeans (feed)
Allan Lykke Christensen » NetBeans (feed)
Inspiration and Expression » Netbeans (feed)
J. O'Conner » NetBeans (feed)
Adam Bien (feed)
Ignacio Sánchez Ginés » NetBeans (feed)
Bernhard's Weblog (feed)
Michel Graciano's Weblog (feed)
Ozone and Programming » netbeans (feed)
NetBeans Ruminations » NetBeans (feed)
Tiplite » netbeans (feed)
Bistro! 2.0 (feed)
Arun Gupta, Miles to go ... (feed)
Geertjan's Blog (feed)
.JARa's Bilingual Weblog (feed)
JavaFX Composer (feed)
The Java Jungle (feed)
Jesse Glick (feed)
Martin Grebac (feed)
The NetBeans Community Podcast (feed)
NetBeans Profiler (feed)
NetBeans for PHP (feed)
NetBeans Web Client (feed)
Rechtacek's (feed)
Virtual Steve (feed)
My First Blog - Satyajit Tripathi (feed)
The Aquarium (feed)
Tinuola Awopetu (feed)
Insert Witty Irony Here (feed)
mkleint (feed)
Anuradha (feed)
Netbeans6/6.5 my best practices (feed)
Java Evangelist John Yeary's Blog (feed)
Neil's Dev Stuff (feed)
Computer says null; (feed)
NetBeans Adventures, Java and more (feed)
Ramon.Ramos (feed)
NetBeans Community Docs Blog (feed)
The Netbeans Experience (feed)
NbPython/ jpydbg / pymvs (feed)
Wade Chandler's Programming Blog (feed)
Devlin's Lab (feed)
Big Al's Blog (feed)
Code Snakes (feed)
In perfect (spherical) shape (feed)
Van Couvering Is Not a Verb (feed)
Diego Torres Milano's blog (feed)
Vroom Framework (feed)
Messages from mrhaki (feed)
Jeff's Blog (feed)
Manikantan's Netbeans (feed)
Oliver Wahlen's Blog (feed)
Shuttle between Galaxies (feed)
Shanbag's Blog (ರಜತ ಲೋಕ) (feed)
Welcome to my live... (feed)
Netbeans IDE Blog by Tushar Joshi, Nagpur (feed)
Devel Blog (feed)
diamond-powder (feed)
Antonio's blog (feed)
Where's my Blog?!

Powered by:    Planet

Last updated:
April 16, 2014 10:06 PM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
NetBeans Zone - The social network for developers - April 15, 2014 09:09 PM
NetBeans Weekly News (Issue #635 - Apr 14, 2014)

Project News Plugin: Scala for NetBeans Caoyuan Deng has upgraded the Scala plugin for NetBeans 8! Get started with it today. Python in NetBeans IDE 8.0 Build Python projects in NetBeans 8 using the NetBeans-Python plugin. Preview Text:  In this issue: Working with Scala and Python in NetBeans 8.0; Using PrimeFaces' layout component; a...

Geertjan's Blog - April 15, 2014 06:08 PM
DukeScript Framework for Dummies

Jaroslav Tulach's Java/JavaScript framework DukeScript explained for dummies (e.g., me):

Or watch it here:

https://www.youtube.com/watch?v=v3ITo889ypI

Further info:

http://wiki.apidesign.org/wiki/DukeScript

http://www.slideshare.net/steveonjava/dukescript

http://nighthacking.com/dukescript-with-toni-epple/

APIDesign - Blogs - April 15, 2014 12:35 PM
Coolest NetBeans Plugin: MineSweeper!

MineSweeper is re-implementation of classical computer game available on each Microsoft Windows since the initial introduction in version 3.1. Surprisingly my kids (who otherwise spend hours with tablets) knew nothing about the game until...

I needed a demonstration for DukeScript technology that is using Java to code the application logic and HTML to render its UI. I decided to write a MineSweeper game as a basic demo. I've managed to execute the demo in a browser (via TeaVM), but today I achieved another milestone: the MineSweeper module is available for every user of NetBeans 8.0!

Get the module via Tools/Plugins or visit its plugin page and enjoy your productivity boost!

In case you are interested in trying the code yourself, here is a way to get the sources:

$ hg clone http://source.apidesign.org/html~demo/
$ cd html~demo/
$ hg up -C 3d99b96ffbd4
$ mvn install
$ cd minesweeper/
$ mvn -Pnbrwsr install
# generates target/minesweeper-1.0-SNAPSHOT.nbm

and the system generates an NBM (NetBeans module file) which can be installed into your NetBeans! Give it a try and let's make NetBeans better by using more DukeScript APIs! Don't forget that you can package the same application to run on Android or in a browser. Become a developer that can: Write once, run anywhere!

--JaroslavTulach 12:35, 15 April 2014 (UTC)

Adam Bien - April 15, 2014 08:37 AM
Java 8: Reducing a List Into A CSV String


import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Test;

public class CSVStreamTest {

    @Test
    public void listToString() {
        List<String> mascots = new ArrayList<>();
        mascots.add("duke");
        mascots.add("juggy");

        String expected = "duke,juggy";
        String actual = mascots.stream().
                reduce((t, u) -> t + "," + u).
                get();
        assertThat(actual, is(expected));
    }
}

See you at Java EE Workshops at MUC Airport!


Real World Java EE Workshops [Airport Munich]>

Michael's blog » NetBeans - April 14, 2014 09:24 PM
Using Lambda expressions with JSF 2.2

JSF 2.2 comes in conjunction with EL 3.0. This version of the expression language offers a rarely known highlight: It is capable of using lambda expressions and streams. Even thought defined withing the Jave EE 7 spec (and not Java … Continue reading

Adam Bien - April 14, 2014 11:48 AM
How To Tackle JavaEE - DevCrowd Keynote

How to structure a JavaEE application? How to organize your code? What are the essential ingredients of a maintainable JavaEE application? How to be productive with JavaEE?

I discussed such questions during the DevCrowd keynote: http://2014.devcrowd.pl/agenda/.

Warning: I used slides in the first part of the keynote :-).

Any questions left? Prepare your questions and I will attempt to answer them …live. Drop a comment / question && see you at each first Monday of the month at 6 p.m (CET) [http://www.ustream.tv/channel/adambien]!

See you at Java EE Workshops at MUC Airport, particularly at the Java EE Architectures workshop, screencasts at: http://tv.adam-bien.com or subscribe to http://www.youtube.com/user/bienadam.!


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - April 11, 2014 08:14 AM
Python in NetBeans IDE 8.0

Copy this to the clipboard:

http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/nbms/updates.xml.gz

Then go to Tools | Plugins and open the Settings tab. Add the above as a new update center:

Then switch to the Available Plugins tab and you'll see the Python plugin:

Install the Python plugin:

Then create a new Python project, using the New Project dialog:

Give it a name and choose your platform. Either import existing sources as a new Python project...

...or create a Python project from scratch:

Then you have an editor with code completion, other editor features, plus a debugger:

Right-click a project to see a bunch of Python commands:

Add to the classpath after right-clicking a project and choosing Properties:

That's it, you're now ready to use Python in NetBeans IDE.

Geertjan's Blog - April 10, 2014 07:00 AM
Context-Sensitive TopComponent (Part 2)

Another way a TopComponent can be context sensitive is in the requirement that the menubar and toolbar need to relate to a specific TopComponent. Below you see that when Win1 is active, a different group of menus and toolbars is available...

... than when Win2 is active:


Part of the solution to this is described here recently about multiple rows of toolbars. However, this only addresses the topic of toolbars. What about menubars? And maybe other components too? I.e., when a TopComponent is active, it would be great if a subfolder of the FileSystem would become enabled, while all other parts would become disabled.

The complete solution to this scenario has been described before, here. Jesse Glick has all the code for this here:

https://bitbucket.org/jglick/dynamicmenudemo

What the above lets you do is create layer entries like this:

<folder name="win1">
    <folder name="Menu">
        <folder name="First">
            <attr name="position" intvalue="150"/>
        </folder>
        <file name="Help.hidden"/>
    </folder>
    <folder name="Toolbars">
        <file name="UndoRedo.hidden"/>
    </folder>
</folder>
<folder name="win2">
    <folder name="Menu">
        <folder name="Second">
            <attr name="position" intvalue="250"/>
        </folder>
    </folder>
</folder>

Then, each TopComponent can specify which folder they want to own:

associateLookup(Lookups.singleton(new SystemSubPathLayerProvider("win1")));

The "SystemSubPathLayerProvider" does all the work in the background to enable and disable items appropriately, whether they are toolbars, menubars, or whatever else.

Nothing is written to disk, this is all done programmatically within the code, and not written to the user directory.

Geertjan's Blog - April 09, 2014 07:00 AM
Context-Sensitive TopComponent (Part 1)

I picked up a cool idea from a Polish developer, Dominik Cebula, recently. In the same way that the NetBeans Platform has context sensitive Actions, there should be context sensitive TopComponents.

Only if an Object of a specific type specified in the public constructor of the TopComponent is found in the Lookup should it be possible to open the TopComponent. And then the Object is available to the TopComponent, without the TopComponent needing to implement a LookupListener.

For example, below "FlightLeg Editor" and "Delay Editor" are both disabled, because no "FlightLeg" and no "Delay" is in the Lookup. Hence it doesn't make sense to open the editor, i.e., when the Object for which the editor exists is not available.


On the other hand, below a "FlightLeg" is available in the Lookup, because one of the flight legs has been selected and hence the underlying "FlightLeg" object is now in the Lookup. Therefore, the "FlightLeg Editor" menu item is enabled so that an editor can be opened for editing the selected flight leg:


In the same way, here the "Delay Editor" can be opened, because an Object of the type "Delay" is published when a DelayNode is selected:


Here is one of these TopComponents:

@TopComponent.Description(
        preferredID = "FlightLegEditorTopComponent",
        persistenceType = TopComponent.PERSISTENCE_ALWAYS
)
@TopComponent.Registration(
        mode = "editor", 
        openAtStartup = false)
@ActionID(
        category = "Window", 
        id = "org.cool.viewer.FlightLegEditorTopComponent")
@ActionReference(
        path = "Menu/Window")
@ObjectTopComponent.OpenActionForObjectRegistration(
        displayName = "#CTL_EditorAction",
        preferredID = "FlightLegEditorTopComponent"
)
@NbBundle.Messages({
    "CTL_EditorAction=FlightLeg Editor",
})
public class FlightLegEditorTopComponent extends ObjectTopComponent implements ActionListener{
    private FlightLeg fl;
    //no-arg constructor is required:
    private FlightLegEditorTopComponent() {}
    public FlightLegEditorTopComponent(FlightLeg fl) {
        this.fl = fl;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        setDisplayName(fl.getName());
        open();
        requestActive();
    }
}

In the above, notice there is a public constructor that receives the domain object "FlightLeg" (i.e., for an airline-type application). Also, there's a new annotation up there, "@ObjectTopComponent.OpenActionForObjectRegistration".

Here's what that annotation looks like (copied and then simply renamed from "@TopComponent.OpenActionRegistration"):

public class ObjectTopComponent extends TopComponent {
    @Retention(RetentionPolicy.SOURCE)
    @Target({ ElementType.TYPE, ElementType.METHOD })
    public static @interface OpenActionForObjectRegistration {
        String displayName();
        String preferredID() default "";
    }
} 

However, the annotation above is processed in such a way that a context-sensitive Action is created that uses the type in the constructor of the TopComponent:

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@ServiceProvider(service = Processor.class)
public final class ObjectTopComponentProcessor extends LayerGeneratingProcessor {
    public ObjectTopComponentProcessor() {
    }
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> hash = new HashSet<String>();
        hash.add(ObjectTopComponent.OpenActionForObjectRegistration.class.getCanonicalName());
        return hash;
    }
    @Override
    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
        for (Element e : roundEnv.getElementsAnnotatedWith(ObjectTopComponent.OpenActionForObjectRegistration.class)) {
            ObjectTopComponent.OpenActionForObjectRegistration reg = e.getAnnotation(ObjectTopComponent.OpenActionForObjectRegistration.class);
            assert reg != null;
            Description info = findInfo(e);
            ActionID aid = e.getAnnotation(ActionID.class);
            if (aid != null) {
                File actionFile = layer(e).
                        file("Actions/" + aid.category() + "/" + aid.id().replace('.', '-') + ".instance").
                        methodvalue("instanceCreate", "org.openide.windows.TopComponent", "openAction");
                actionFile.instanceAttribute("component", TopComponent.class, reg, null);
                if (reg.preferredID().length() > 0) {
                    actionFile.stringvalue("preferredID", reg.preferredID());
                }
                generateContext(e, actionFile);
                actionFile.bundlevalue("displayName", reg.displayName(), reg, "displayName");
                if (info != null && info.iconBase().length() > 0) {
                    actionFile.stringvalue("iconBase", info.iconBase());
                }
                actionFile.write();
            }
        }
        return true;
    }
    private void generateContext(Element e, File f) throws LayerGenerationException {
        ExecutableElement ee = null;
        ExecutableElement candidate = null;
        for (ExecutableElement element : ElementFilter.constructorsIn(e.getEnclosedElements())) {
            if (element.getKind() == ElementKind.CONSTRUCTOR) {
                candidate = element;
                if (!element.getModifiers().contains(Modifier.PUBLIC)) {
                    continue;
                }
                if (ee != null) {
                    throw new LayerGenerationException("Only one public constructor allowed", e, processingEnv, null); // NOI18N
                }
                ee = element;
            }
        }
        if (ee == null || ee.getParameters().size() != 1) {
            if (candidate != null) {
                throw new LayerGenerationException("Constructor has to be public with one argument", candidate);
            }
            throw new LayerGenerationException("Constructor must have one argument", ee);
        }
        VariableElement ve = (VariableElement) ee.getParameters().get(0);
        TypeMirror ctorType = ve.asType();
        switch (ctorType.getKind()) {
            case ARRAY:
                String elemType = ((ArrayType) ctorType).getComponentType().toString();
                throw new LayerGenerationException("Use List<" + elemType + "> rather than " + elemType + "[] in constructor", e, processingEnv, null);
            case DECLARED:
                break; // good
            default:
                throw new LayerGenerationException("Must use SomeType (or List<SomeType>) in constructor, not " + ctorType.getKind());
        }
        DeclaredType dt = (DeclaredType) ctorType;
        String dtName = processingEnv.getElementUtils().getBinaryName((TypeElement) dt.asElement()).toString();
        if ("java.util.List".equals(dtName)) {
            if (dt.getTypeArguments().isEmpty()) {
                throw new LayerGenerationException("Use List<SomeType>", ee);
            }
            f.stringvalue("type", binaryName(dt.getTypeArguments().get(0)));
            f.methodvalue("delegate", "org.openide.awt.Actions", "inject");
            f.stringvalue("injectable", processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString());
            f.stringvalue("selectionType", "ANY");
            f.methodvalue("instanceCreate", "org.openide.awt.Actions", "context");
            return;
        }
        if (!dt.getTypeArguments().isEmpty()) {
            throw new LayerGenerationException("No type parameters allowed in ", ee);
        }
        f.stringvalue("type", binaryName(ctorType));
        f.methodvalue("delegate", "org.openide.awt.Actions", "inject");
        f.stringvalue("injectable", processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString());
        f.stringvalue("selectionType", "EXACTLY_ONE");
        f.methodvalue("instanceCreate", "org.openide.awt.Actions", "context");
    }
    private String binaryName(TypeMirror t) {
        Element e = processingEnv.getTypeUtils().asElement(t);
        if (e != null && (e.getKind().isClass() || e.getKind().isInterface())) {
            return processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
        } else {
            return t.toString(); // fallback - might not always be right
        }
    }
    private Description findInfo(Element e) throws LayerGenerationException {
        Element type;
        switch (e.asType().getKind()) {
            case DECLARED:
                type = e;
                break;
            case EXECUTABLE:
                type = ((DeclaredType) ((ExecutableType) e.asType()).getReturnType()).asElement();
                break;
            default:
                throw new LayerGenerationException("" + e.asType().getKind(), e);
        }
        TopComponent.Description info = type.getAnnotation(TopComponent.Description.class);
        return info;
    }
}
 

The above processor is a combination of the TopComponentProcessor and the ActionProcessor in the NetBeans Platform.

And now you have a layer generating processor that creates a context sensitive Action for opening a TopComponent. If no Object of the type specified in the constructor of the TopComponent is in the Lookup, the Action will be disabled. If an Object of the specified type is available, the Action is enabled and immediately available to the TopComponent as soon as it is opened.

That's an example of a view that is bound to a model. Useful for editors that need to be created for one or more specific Objects. Data binding for TopComponents, hurray.

Geertjan's Blog - April 08, 2014 04:28 PM
Disable Module on Authentication Failure

The user starts the application. The splash screen is shown. Right after the modules are loaded, as indicated by the text in the splash screen, a small login screen appears. The user fills in the wrong login credentials and clicks OK. The text in the splash screen shows that one or more modules are being turned off. Then the main window of the application appears. Because the login credentials were wrong, one or more of the modules have been disabled. 

import java.util.List;
import org.netbeans.api.autoupdate.OperationContainer;
import org.netbeans.api.autoupdate.OperationException;
import org.netbeans.api.autoupdate.OperationSupport;
import org.netbeans.api.autoupdate.UpdateElement;
import org.netbeans.api.autoupdate.UpdateManager;
import org.netbeans.api.autoupdate.UpdateUnit;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.modules.OnStart;
import org.openide.util.Exceptions;

@OnStart
public class Startable implements Runnable {
    @Override
    public void run() {
        NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine("Name", "Login");
        //Got tired of typing it by hand:
        nd.setInputText("admin");
        Object response = DialogDisplayer.getDefault().notify(nd);
        if (response == NotifyDescriptor.OK_OPTION) {
            String username = nd.getInputText();
            NotifyDescriptor.Message msg;
            if (!username.equals("admin")) {
                List<UpdateUnit> updateUnits = 
                  UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE);
                for (UpdateUnit updateUnit : updateUnits) {
                    //Get each module that is installed:
                    UpdateElement el = updateUnit.getInstalled();
                    //Of those that are installed, if it has the code name base
                    //of the module we are interested in, and it is enabled,
                    //continue with this procedure to disable it:
                    if (el != null
                            && el.getCodeName().equals("com.mycompany.admin")
                            && el.isEnabled()) {
                        try {
                            //Specify how we want to handle the module; 
                            //here, we want to disable it:
                            OperationContainer oc = OperationContainer.createForDirectDisable();
                            oc.add(el);
                            //Finally, do the operation,
                            //passing a progress handle or, as in this case, null:
                            OperationSupport supp = (OperationSupport) oc.getSupport();
                            supp.doOperation(null);
                        } catch (OperationException ex) {
                            Exceptions.printStackTrace(ex);
                        }
                    }
                }
            }
        }
    }
}

Finally, the module is not shown in the Plugin Manager, so that it cannot be enabled from there. Only if the user logs in correctly is the module enabled.

Related reading:

Adam Bien - April 08, 2014 09:55 AM
1st Airhacks Q&A And The Answers Are:

Additional 10 live questions, 1h and 83 live views. The first edition Airhacks Q & A was fun for me. I started with answering the 10 proposed questions, then got additional blog comments, tweets and chats in real time. After a 1h I had to catch QuestionsOverflowException and postponed some answers to the 2nd edition of Airhacks Q & A (Monday, May 5th, 6 PM (CET)): http://www.ustream.tv/channel/adambien.

Thanks for all the interactions during the event. It was fun for me ...and I saved lots of time.

Write your questions as comments to this post, drop me a tweet or write a comment on my youtube channel: https://www.youtube.com/user/bienadam. I will pick again the 10 most recent questions and will answer them at the next edition of Airhacks Q & A.

We have sufficient stuff to cover, this blog has about 5000 comments, and probably 20% of that number are unanswered questions.

See you at the regular Java EE Workshops at MUC Airport and particularly at Distributed Computing and Persistence with Enterprise Java. ...and live each first Monday of the month at 6 P.M (CET) http://www.ustream.tv/channel/adambien!

See also other screencasts at: http://tv.adam-bien.com or subscribe to http://www.youtube.com/user/bienadam.


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - April 07, 2014 08:33 PM
Multiple Rows of Toolbars

Realized today that toolbars can be placed in different rows:

The above is a result of a file I named "All.xml" that has this content and is found in the same package as the layer.xml file:

<?xml version="1.0"?>
<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar//EN"
 "http://www.netbeans.org/dtds/toolbar.dtd">
<Configuration>
    <Row>
        <Toolbar name="File" />
    </Row>
    <Row>
        <Toolbar name="UndoRedo" />
        <Toolbar name="Clipboard"/>
    </Row>
    <Row>
        <Toolbar name="Memory"/>
    </Row>
</Configuration>

It is registered as follows in the layer.xml file:

<folder name="Toolbars">
    <file name="All.xml" url="All.xml"/>
</folder>

And then, as a handy final step, here's code in one of my TopComponents for switching between different toolbar definitions:

@Override
protected void componentActivated() {
    ToolbarPool.getDefault().setConfiguration("All");
}
@Override
public void componentDeactivated() {
    ToolbarPool.getDefault().setConfiguration("Standard");
}

Here's some related reading:

Michael's blog » NetBeans - April 07, 2014 05:32 PM
NetBeans 8 contribution

Due to less time, I sadly could only contribute a small amount to NetBeans 8. Following is the report, I received today. Get inspired to contribute too. Dear NetBeans User, In the past you have taken the time to report … Continue reading

Adam Bien - April 07, 2014 09:36 AM
1st Airhacks Q&A And The Questions Are:

  1. Jeff Picklyk: "How would you suggest convincing the ivory tower decision makers to leave plain old Tomcat + Spring in favour of JavaEE 6 or 7?"
  2. Andreas Haufler: "...and you should evaluate: Do I even need a JavaEE monster? Scalability can be achieved at a much lower price (in terms of learning curve and complexity)."
  3. My thoughts on Controversial 80 characters max withs.
  4. Tony Anecito: "JavaFX and ClassPath"
  5. Alberto Gori: "If this is true, I would say it's better to call em.clear() just after em.flush()."?
  6. Manfred Pauli: "You state you're never design your application by technical structures. Where would you pack exceptions to? Especially if they are used through the whole project. "
  7. Yasser: "I am trying to use your example, but my test fails at "facade.service = service". It looks like my test case doesn't have access to the @EJB Service in the ServiceFacade."
  8. Tim B. "If you have two applications communicate via REST and DTOs are forbidden, how do you share the model between those two?"
  9. Anonymous: "How one generates eg: REST client stubs in Delphi for java endpoints? There is still no widespread WSDL-like tools for REST"
  10. Conversation with Jeanne Boyarsky about @Ignore in unit test

I will at least answer the above questions today. If you have any other questions, just write a comment to this post. There are a few hours left...

You can also ask questions during the show using the built-in chat: or via twitter mentioning me: http://twitter.com/AdamBien (@AdamBien) or using the hashtag: #airhacks.

See you at Java EE Workshops at MUC Airport or on demand and in a location very near you: airhacks.io!


Real World Java EE Workshops [Airport Munich]>

NetBeans Zone - The social network for developers - April 07, 2014 06:38 AM
Tushar Joshi: My 5 Favorite NetBeans IDE Features!

Following on from Ciprian Turcu, Mark Stephens, Josh Preview Text:  Extensible architecture, active community, and other aspects of the NetBeans ecosystem are explained here by Tushar Joshi as his favorite NetBeans features. Legacy Sponsored:  unsponsored ...

Geertjan's Blog - April 06, 2014 07:00 AM
org.openide.awt.Actions.ButtonActionConnector

Handy, need to explore this further.

import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JMenuItem;
import org.openide.awt.Actions;
import org.openide.awt.Actions.ButtonActionConnector;
import org.openide.util.lookup.ServiceProvider;
@ServiceProvider(
        service = ButtonActionConnector.class, 
        position = 100)
public class MyButtonActionConnector implements ButtonActionConnector {
   @Override
   public boolean connect(AbstractButton button, Action action) {
      String text = (String)action.getValue("displayName");
      if (text != null) {
         button.setAction(action);
         button.setText(Actions.cutAmpersand(text));
         String desc = (String)action.getValue(Action.SHORT_DESCRIPTION);
         if (desc != null) {
            button.setToolTipText(desc);
         } else {
            button.setToolTipText((String)action.getValue(Action.NAME));
         }
         return true;
      }
      return false;
   }
   @Override
   public boolean connect(JMenuItem item, Action action, boolean popup) {
       return false; // use default implementation
   }
} 

Further reading:

http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/Actions.ButtonActionConnector.html

http://anchialas.wordpress.com/2012/04/16/toolbar-icons-with-label/#comments

http://praxisintermedia.wordpress.com/2012/04/10/branding-project-action-icons/

Geertjan's Blog - April 05, 2014 07:00 AM
Creating MultiViewElements on the Fly

Following from the above, here's how to add a new tab in the Java Editor, on the fly (as described here, possible from 8.0 onwards), i.e., when the "Design Custom Component" menu item (which is only available when you right-click a subclass of com.vaadin.ui.CustomComponent, as described yesterday) is clicked:

@Override
public void actionPerformed(ActionEvent ev) {
    dobj.getLookup().lookup(Openable.class).open();
    TopComponent activated = WindowManager.getDefault().getRegistry().getActivated();
    MultiViewHandler mvh = MultiViews.findMultiViewHandler(activated);
    mvh.addMultiViewDescription(new DesignerMVD(), 1);
}

In short, the above gets you this:


DesignerMVD, referenced above, is as follows:

import java.awt.Image;
import org.netbeans.core.spi.multiview.MultiViewDescription;
import org.netbeans.core.spi.multiview.MultiViewElement;
import org.openide.util.HelpCtx;
import org.openide.util.Utilities;
import org.openide.windows.TopComponent;

public class DesignerMVD implements MultiViewDescription {
    @Override
    public int getPersistenceType() {
        return TopComponent.PERSISTENCE_NEVER;
    }
    @Override
    public String getDisplayName() {
        return "Designer";
    }
    @Override
    public Image getIcon() {
        return null;
    }
    @Override
    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }
    @Override
    public String preferredID() {
        return "Designer";
    }
    @Override
    public MultiViewElement createElement() {
        return new DesignMVE(Utilities.actionsGlobalContext());
    }
}
 

And DesignerMVE is like this, i.e., a JPanel, which will later contain a Visual Library Scene that visualizes the content of the CustomComponent in some way, so that it can be graphically edited:

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import org.netbeans.core.spi.multiview.CloseOperationState;
import org.netbeans.core.spi.multiview.MultiViewElement;
import org.netbeans.core.spi.multiview.MultiViewElementCallback;
import org.openide.awt.UndoRedo;
import org.openide.loaders.DataObject;
import org.openide.util.Lookup;

public class DesignMVE extends JPanel implements MultiViewElement {
    private JToolBar toolbar = new JToolBar();
    private DataObject obj;
    public DesignMVE(Lookup lkp) {
        obj = lkp.lookup(DataObject.class);
        assert obj != null;
    }
    @Override
    public JComponent getVisualRepresentation() {
        return this;
    }
    @Override
    public JComponent getToolbarRepresentation() {
        toolbar.setFloatable(false);
        return toolbar;
    }
    @Override
    public Action[] getActions() {
        return new Action[0];
    }
    @Override
    public Lookup getLookup() {
        return obj.getLookup();
    }
    @Override public void componentOpened() {}
    @Override public void componentClosed() {}
    @Override public void componentShowing() {}
    @Override public void componentHidden() {}
    @Override public void componentActivated() {}
    @Override public void componentDeactivated() {}
    @Override
    public UndoRedo getUndoRedo() {
        return UndoRedo.NONE;
    }
    private transient MultiViewElementCallback callback;
    @Override
    public void setMultiViewCallback(MultiViewElementCallback mvec) {
        this.callback = mvec;
    }
    @Override
    public CloseOperationState canCloseElement() {
        return CloseOperationState.STATE_OK;
    }
}
 

Finally, the action for opening the DesignerMVD is slightly more complex because we don't want a new DesignerMVD whenever the Action is invoked. Specifically, we do not want a new DesignerMVD if the file is already open, since then a new DesignerMVD will already have been created. Hence (thanks to instructions here), we get this:

@Override
public void actionPerformed(ActionEvent ev) {
    //Need to make sure to add a designer
    //only if the file hasn't been opened yet,
    //otherwise we'll get a new designer
    //whenever the action is invoked:
    FileObject fileObject = dobj.getPrimaryFile();
    JavaSource javaSource = JavaSource.forFileObject(fileObject);
    if (javaSource != null) {
        try {
            javaSource.runUserActionTask(new Task<CompilationController>() {
                @Override
                public void run(CompilationController compilationController) throws Exception {
                    compilationController.toPhase(Phase.ELEMENTS_RESOLVED);
                    Document document = compilationController.getDocument();
                    if (document == null) {
                        dobj.getLookup().lookup(Openable.class).open();
                        TopComponent activated = WindowManager.getDefault().getRegistry().getActivated();
                        MultiViewHandler mvh = MultiViews.findMultiViewHandler(activated);
                        mvh.addMultiViewDescription(new DesignerMVD(), 1);
                    }
                }
            }, true);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
}
 

A different approach might be to disable the Action when the file has been opened, so that it cannot be invoked again while the file is open, which means the above code would not be needed anymore.

The next step is to work on the Visual Library Scene, which will be contained within the JPanel above, together with a Palette (as described here) that contains all the relevant Vaadin components.

And then we'll have a Visual Designer for Vaadin!

Geertjan's Blog - April 04, 2014 10:33 PM
Popup Action Based on Java Subclass

Climb up the hierarchy (thanks to this) to determine whether a class is a subclass of com.vaadin.ui.CustomComponent and, if so, enable and display a popup menu on it so that it can be opened in a visual designer of some kind.

@ActionID(
        category = "Tools",
        id = "org.tc.customizer.DesignCustomComponentAction")
@ActionRegistration(
        displayName = "#CTL_DesignCustomComponentAction",
        lazy = false)
@ActionReferences({
    @ActionReference(path = "Loaders/text/x-java/Actions", position = 150)
})
@Messages("CTL_DesignCustomComponentAction=Design Custom Component")
public final class DesignAbstractFormAction extends AbstractAction implements ContextAwareAction {
    private final DataObject dobj;
    private static Map args = new HashMap();
    public DesignAbstractFormAction() {
        this(Utilities.actionsGlobalContext());
    }
    public DesignAbstractFormAction(Lookup context) {
        super(Bundle.CTL_DesignCustomComponentAction());
        this.dobj = context.lookup(DataObject.class);
        JavaSource javaSource = JavaSource.forFileObject(dobj.getPrimaryFile());
        if (javaSource != null) {
            try {
                javaSource.runUserActionTask(new ScanForObjectTask(this), true);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
        //Hide the menu item if it isn't enabled:
        putValue(DynamicMenuContent.HIDE_WHEN_DISABLED, true);
    }
    @Override
    public void actionPerformed(ActionEvent ev) {
        //Starting point for designer:
        TopComponent tc = new TopComponent();
        tc.setDisplayName(dobj.getName());
        tc.open();
        tc.requestActive();
    }
    @Override
    public Action createContextAwareInstance(Lookup actionContext) {
        return new DesignAbstractFormAction(actionContext);
    }
    private static class ScanForObjectTask implements Task<CompilationController&g; {
        private final DesignAbstractFormAction action;
        private ScanForObjectTask(DesignAbstractFormAction action) {
            this.action = action;
        }
        @Override
        public void run(CompilationController compilationController) throws Exception {
            compilationController.toPhase(Phase.ELEMENTS_RESOLVED);
            new MemberVisitor(compilationController, action).scan(
                    compilationController.getCompilationUnit(), null);
        }
    }
    private static class MemberVisitor extends TreePathScanner<Void, Void&g; {
        private CompilationInfo info;
        private final AbstractAction action;
        public MemberVisitor(CompilationInfo info, AbstractAction action) {
            this.info = info;
            this.action = action;
        }
        @Override
        public Void visitClass(ClassTree t, Void v) {
            Element el = info.getTrees().getElement(getCurrentPath());
            if (el != null) {
                TypeElement element = (TypeElement) el;
                Types typeUtils = info.getTypes();
                while (element!=null&&!element.toString().equals("com.vaadin.ui.CustomComponent")) {
                    element = (TypeElement) typeUtils.asElement(element.getSuperclass());
                    if (element!=null&&element.toString().equals("com.vaadin.ui.CustomComponent")) {
                        action.setEnabled(true);
                    } else {
                        action.setEnabled(false);
                    }
                }
            }
            return null;
        }
    }
}

NetBeans Zone - The social network for developers - April 04, 2014 03:03 PM
David Salter: My 5 Favorite NetBeans IDE Features!

Following on from Ciprian Turcu, Mark Stephens, Josh Juneau, Preview Text:  Maven, Git, Java EE, and more... find out why David Salter likes NetBeans IDE! Legacy Sponsored:  unsponsored

Geertjan's Blog - April 03, 2014 02:26 PM
YouTube: Vaadin/NetBeans Webinar

The webinar is live on YouTube. Watch how Matti the Vaadin guy deletes almost my entire application and replaces it with Vaadin:

Or click here to get there: https://www.youtube.com/watch?v=3TompuzySD8

Here's a pic of the after party with Matti, my co-presenter:

And the after after party in a viking restaurant with Fredrik, Matti, and Sami:


Adam Bien - April 03, 2014 09:28 AM
GlassFish v4.0.1 Daily Build Supports Java 8 Lambda

GlassFish v4.0 does not support lambdas. If you attempt to deploy a Java EE 7 application with CDI and Lambdas you are going to get the following exception:


Severe:   Exception while visiting WEB-INF/classes/com/airhacks/lambda/test/BackendService.class of size 1825
java.lang.ArrayIndexOutOfBoundsException: 52264
	at org.objectweb.asm.ClassReader.readClass(ClassReader.java:2015)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:469)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:425)
	at org.glassfish.hk2.classmodel.reflect.Parser$5.on(Parser.java:362)
	at com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.handleEntry(ReadableArchiveScannerAdapter.java:165)
	at com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.onSelectedEntries(ReadableArchiveScannerAdapter.java:127)
	at org.glassfish.hk2.classmodel.reflect.Parser.doJob(Parser.java:347)
	at org.glassfish.hk2.classmodel.reflect.Parser.access$300(Parser.java:67)
	at org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:306)
	at org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:295)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:744)

The following test source was used:


@RequestScoped
public class BackendService {

    public double average() {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(42);
        numbers.add(21);
        numbers.add(7);
        return numbers.stream().mapToInt(i -> i).average().getAsDouble();

    }
}

However, GlassFish v4.0.1 nightly builds builds starting with March, 20th 2014 supports Java 8 and lambdas. You can deploy Java EE 7 applications running on Java 8 with lambdas.

See you at Java EE Workshops at MUC Airport!


Real World Java EE Workshops [Airport Munich]>

NetBeans Zone - The social network for developers - April 02, 2014 12:41 PM
Arthur Buliva: My 5 Favorite NetBeans IDE Features!

Following on from Ciprian Turcu, Mark Stephens, Preview Text:  Database support, GlassFish, Git, and more... read what Arthur Buliva from Kenya likes about NetBeans! Legacy Sponsored:  unsponsored

Geertjan's Blog - April 02, 2014 11:57 AM
Sign Up for Tomorrow's Vaadin/NetBeans Webinar!

Click the image above or click here to get to the sign up form!

Adam Bien - April 02, 2014 09:59 AM
Airhacks Q & A and How To Tackle Java EE (7)

Two free (no registration required) streaming, but interactive, events are waiting for you:

  1. Airhacks Questions and Answers: At the first Monday of each month at 6 P.M. CET. (next event is scheduled for: Monday, April, 7th, 6 P.M CET). I'm going to answer all remaining questions about Java (SE/EE/FX/Nashorn) from http://workshops.adam-bien.com, this blog, https://twitter.com/AdamBien and from "the streets" :-). The length of the event directly depends on the question's queue depth.
  2. Virtual Keynote: "How To Tackle Java EE 7" from http://2014.devcrowd.pl/. Abstract:
    You don't have to know the complete Java EE 7 API to create maintainable enterprise applications efficiently. The reverse is true: well designed Java EE applications comprise 95% business logic and only 5% plumbing. In this talk I would like to introduce a business driven approach to maintainable Java EE with lots of code and some slides
You can attend both events without any registration at: http://www.ustream.tv/channel/adambien. Questions can be asked during the event using the built-in chat or twitter with hashtag #airhacks.

See you at Java EE Workshops at MUC Airport or on demand and in a location very near you: airhacks.io!


Real World Java EE Workshops [Airport Munich]>

markiewb's blog - April 01, 2014 10:00 PM
NetBeans: Switching project groups from toolbar

Today I saw that a new version 1.7 of the “Cool Editor Actions” plugin has been uploaded by anchialos to the plugin portal [1]. It introduces switching of project groups and toolbar configurations right from the toolbar, which is very nice.

2014-04-01_23h38_24

 

BTW: A similar much older plugin named “Project Group Toolbar” from Aljoscha Rittner already exists, but  unfortunately it does not work in a stable way anymore – regarding to multiple comments at the plugin portal [2].

[1] http://plugins.netbeans.org/plugin/39634/cool-editor-actions
[2] http://plugins.netbeans.org/plugin/20677/project-group-toolbar


NetBeans Zone - The social network for developers - April 01, 2014 11:41 AM
Financial Management on NetBeans for Government of Eritrea

My name is Salhadin Yousuf Mahmoud. I graduated in 2011 from the department of Computer Engineering from the Eritrea Institute of Technology, in Eritrea. I continued studying Java at home in parallel to my basic Java college classes. Because I love Java, I continued studying it. Since that time, I have been working alone on Java and its related technologies in private projects. I have also worked...

Geertjan's Blog - April 01, 2014 08:38 AM
Dynamically Creating Menu Items (Part 2)

OK, following on from yesterday, here's the next part. What we want to do is click a button, such as shown below, and, when the button is clicked, cause a new menu item to be added to a predefined menu, in this case the "Shortcuts" menu.

The first step is to define the Shortcuts menu in a layer.xml file:

<folder name="Menu">
    <folder name="Shortcuts"/>
</folder>

Next, we want to populate that folder dynamically, whenever the user clicks the button above. To do that, we need to get hold of the Shortcuts folder within the Menu folder. Then we add in there a new file with ".instance" as the extension, assign our own Action to it, and (as described here, thanks Ernie and the vi/vim project), use the "instanceCreate" and "instanceClass" attributes.

public class SomeTopComponent extends TopComponent {
    private DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    public SomeTopComponent() {
        setDisplayName("Some");
        setLayout(new BorderLayout());
        add(new JButton(new AbstractAction("Add new menu item to shortcuts") {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        final String formatted = formatter.format(System.currentTimeMillis());
                        FileObject menuFolder = FileUtil.getConfigFile("Menu/Shortcuts");
                        try {
                            FileObject newMenu = menuFolder.createData(formatted, "instance");
                            AbstractAction action = new AbstractAction(
                                    "Added at: " + formatted) {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    JOptionPane.showMessageDialog(null, formatted);
                                }
                            };
                            newMenu.setAttribute("instanceCreate", action);
                            newMenu.setAttribute("instanceClass", action.getClass().getName());
                        } catch (IOException ex) {
                            Exceptions.printStackTrace(ex);
                        }
                    }
                });
            }
        }), BorderLayout.NORTH);
    }
}

OK. We now know how to dynamically add a new menu item within a top level menu. But can a top level menu be itself created dynamically too?

That's even simpler:

public class SomeTopComponent extends TopComponent {
    private DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    public SomeTopComponent() {
        setDisplayName("Some");
        setLayout(new BorderLayout());
        add(new JButton(new AbstractAction("Add new menu to main menubar") {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        final String formatted = formatter.format(System.currentTimeMillis());
                        FileObject menuFolder = FileUtil.getConfigFile("Menu");
                        try {
                            menuFolder.createFolder("Added at: " + formatted);
                        } catch (IOException ex) {
                            Exceptions.printStackTrace(ex);
                        }

                    }
                });
            }
        }), BorderLayout.NORTH);
    }
}

The result:


Geertjan's Blog - March 31, 2014 09:03 PM
Dynamically Creating Menu Items (Part 1)

Let's set up an infrastructure for dynamically creating menu items in a NetBeans Platform application. We start with this, i.e., a simple skeleton. We have an Action presented as a JMenu over which we have control via Presenter.Menu, together with a LookupListener that we're going to use for listening to the Lookup for objects of interest:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.actions.Presenter;
@ActionID(category = "Shortcuts", id = "org.bla.core.DynamicShortcutMenu")
@ActionReference(path = "Menu/Shortcuts")
public class DynamicShortcutMenu 
    implements ActionListener, Presenter.Menu, LookupListener {
    JMenu menu = new JMenu();
    @Override
    public JMenuItem getMenuPresenter() {
        return menu;
    }
    @Override
    public void resultChanged(LookupEvent le) {
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // not used
    }
}

Next, let's develop our LookupListener further so that we can listen for new objects of interest. What the "object of interest" is, is up to you. Let's create an interface named "Clickable" as the currency, i.e., the communication mechanism that will be used to communicate with the Action that we have created above, i.e., to tell it that new menu items are needed.

import javax.swing.AbstractAction;
public interface Clickable {
    AbstractAction getAbstractAction();
}

OK. We have an interface that is a wrapper around an AbstractAction. Later on, we'll publish implementations of this interface.

For the moment, let's focus on changing the earlier code so that we can consume the implementations, once those implementations are published.

@ActionID(category = "Shortcuts", id = "org.bla.core.DynamicShortcutMenu")
@ActionRegistration(displayName = "not-used", lazy = false)
@ActionReference(path = "Menu/Shortcuts")
public class DynamicShortcutMenu extends AbstractAction
        implements ContextAwareAction, Presenter.Menu, LookupListener {
    private final Lookup.Result<Clickable> clickables;
    private JMenu menu = new JMenu("Dynamic");
    public DynamicShortcutMenu() {
        this(Utilities.actionsGlobalContext());
    }
    public DynamicShortcutMenu(Lookup lkp) {
        clickables = lkp.lookupResult(Clickable.class);
        clickables.addLookupListener(
                WeakListeners.create(LookupListener.class, this, clickables));
    }
    @Override
    public JMenuItem getMenuPresenter() {
        return menu;
    }
    @Override
    public void resultChanged(LookupEvent le) {
        for (Clickable c : clickables.allInstances()){
            menu.add(c.getAbstractAction());
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // not used
    }
    @Override
    public Action createContextAwareInstance(Lookup lkp) {
        return new DynamicShortcutMenu(lkp);
    }
}

Great. We're now listening to the global lookup for Clickables and then adding their AbstractActions to the menu we created above.

Now that we know how to consume Clickables, let's learn how to publish a Clickable. Below you see a TopComponent that contains a JButton. When clicked, the JButton publishes a Clickable into the Lookup of the TopComponent. At that stage, the Action code above causes a new JMenuItem to be added. Note that at no point is a JMenuItem removed, i.e., when selection changes to a different TopComponent, the JMenuItem added via the code below will still be in the dynamic menu, which is probably how you want things to be anyway.

@TopComponent.Description(
        preferredID = "SomeTopComponent",
        persistenceType = TopComponent.PERSISTENCE_ALWAYS
)
@TopComponent.Registration(
        mode = "explorer",
        openAtStartup = true)
public class SomeTopComponent extends TopComponent {
    private DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    private InstanceContent ic = new InstanceContent();
    public SomeTopComponent() {
        setDisplayName("Some");
        setLayout(new BorderLayout());
        add(new JButton(new AbstractAction("Add new menu item to shortcuts") {
            @Override
            public void actionPerformed(ActionEvent e) {
                ic.set(Collections.singletonList(new SomeClickable()), null);
            }
        }), BorderLayout.NORTH);
        associateLookup(new AbstractLookup(ic));
    }
    private class SomeClickable implements Clickable {
        @Override
        public AbstractAction getAbstractAction() {
            final String formatted = formatter.format(System.currentTimeMillis());
            return new AbstractAction("Added at: " + formatted) {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(null, "hello from " + formatted);
                }
            };
        }
    }
}

Here's the result.

Of course, this throws up some new questions. Especially, how to achieve this result for a menu within the menubar, rather than a submenu within a menu within the menubar. I.e., as you can see above, this only solves the situation where a third-level menu needs to be dynamic. But what about if the menu "Dynamic" above needs to itself be dynamic? And, even more complexly, what if the "Shortcuts" menu should, itself, be dynamic? See part 2 for the solutions to these questions.

Geertjan's Blog - March 30, 2014 12:05 PM
"Cannot load even default layout, using internally predefined configuration"

When I created the FeedReader application in NetBeans IDE 8 and then ran it, this is what I saw:

The above tells you something is messed up in the System FileSystem.

The log shows among other things:

Caused: java.io.FileNotFoundException: [WinSys] Missing Window Manager configuration file
    at org.netbeans.core.windows.persistence.WindowManagerParser$PropertyHandler.readData(WindowManagerParser.java:911)
    at org.netbeans.core.windows.persistence.WindowManagerParser.readProperties(WindowManagerParser.java:365)
    at org.netbeans.core.windows.persistence.WindowManagerParser.load(WindowManagerParser.java:110)
    at org.netbeans.core.windows.persistence.PersistenceManager.loadWindowSystem(PersistenceManager.java:1156)
[catch] at org.netbeans.core.windows.PersistenceHandler.load(PersistenceHandler.java:130)
    at org.netbeans.core.windows.WindowSystemImpl.load(WindowSystemImpl.java:81)
    at org.netbeans.core.GuiRunLevel$InitWinSys.run(GuiRunLevel.java:229)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)

After quite a bit of searching, I discovered this file in the "branding" folder of the application. The "branding" folder can only be seen when you're in the Files window.

I deleted the "resources" folder above, together with the "layer.xml" file that you see there. It contained only "_hidden" elements, i.e., this is an older way of hiding menus and toolbars, that is now obsolete; now you do so within a module instead of in a file within the "branding" folder like the above. (Even better than deleting it is to move its content into one of the layer.xml files of your own modules, e.g., the Feed Reader module.)

Then I cleaned the application. And then I ran the application and everything was OK. Seems like an old file format of the layer.xml file, or maybe something changed in that module, I don't know what the reason is.

Geertjan's Blog - March 29, 2014 07:00 AM
Cause a Wizard to Appear Automatically

Sometimes you may want a wizard to automatically appear, as a result of logic, rather than a user action. Normally, the user goes to the New File dialog or the New Project dialog or clicks an Action, such as provided by a menu item or toolbar button, and then a wizard starts up.

However, here's something slightly different. The module depends on the Window System API and hence the @OnShowing annotation is available.

import java.io.File;
import org.openide.awt.Actions;
import org.openide.windows.OnShowing;
@OnShowing
public class Startable implements Runnable {
    @Override
    public void run() {
        if (!new File("/path/to/some/folder").exists()) {
            Actions.forID("File", "org.something.core.CreateFolderWizardAction").actionPerformed(null);
        }
    }   
}

In the "run" method, use "Actions.forID" and pass in the category and the ID of the Action that starts up the wizard. Since when you use the Wizard wizard to create a wizard skeleton, you also get an Action, you should have an Action somewhere in your module structure. Instead of registering the wizard in the Action such that it appears as a toolbar button or menu item, just remove those annotations. The only annotations your Action needs are @ActionID and @ActionRegistration, not @ActionReference.

And with that, the wizard starts up after the application is initialized, automatically.