Why being a Rebel is hot and spicy?

I usually write technical articles about what is hot and spicy in software development, or at least what I think is hot and spicy. Well, I will make a little exception this time and write about why it is also hot and spicy being a RebelLabs author. If you’re reading this, you probably know what RebelLabs is: a house of geeky ninjas that like to write technical content about hot topics in our geeky development world. According Oliver White, head of RebelLabs:

Developers enjoy the additional “spice” of RebelLabs–we’ve managed to create a reliable content machine producing challenging, opinionated and humorous technical content for all software engineers to enjoy. Recently I saw this quote about RebelLabs by Rafael Winterhalter, in a recent Developer of the Week interview by DZone, and I think it sums things up very nicely: “I like RebelLabs a lot, especially since they manage to be both competent and humorous which is a rather rare combination.” –

Finding passion in the geeky world of development

As a geek, I’m passionate about software development, especially about Java and more recently, JavaFX. This passion leads me to go to people and say “Hey look, I discovered some pretty awesome new stuff”. But you can’t do this with your wife or your grandma, right? You won’t be understood … So frustrating …

But as passionate geek, I still need to tell somebody what I have discovered, tested and developed because I’m proud of it. Yeah you read right, proud of it. It is like being a kid having the latest trendy toy who shows everybody he has it. It is the same for me with software development. RebelLabs brings me the possibility of doing it, with a lot of fun.

I don’t need to write about old tools, APIs, languages and so on. I need to find a subject, find a way of making it attractive and interesting, and write. And when it’s published it’s like telling the world how proud you are. It is like your work being concrete and not only stored on your computer, right? Haven’t you ever felt that feeling of pride when you’ve developed the next most awesome API and nobody is using it?

The open source writer

We all know open source projects, developed by passionate ninjas to help other ninjas (or not) do their jobs better and make them easier by bringing them tools, APIs and other shiny stuff. I know a couple of those. One of them, Guillaume Scheibel (@g_scheibel and Hibernate OGM contributor) told me some time ago, that in the beginning it was not that easy to code in open source projects because you show the way you code to everyone and you have to accept remarks from others giving you advices of how doing things better. You have to accept remarks and sometimes it is not that easy. Writing is almost the same because you show the world what you’ve done and how you write. Double pressure.

I accept both because what you learn is much greater than this. Why is it? Because I work with guys that are as passionate as me and who like to teach you things about writing, tools and more. They don’t want to take you down in what you’re writing, but raising you up. And remarks are always constructive. It helps you do things better.

I also think this needs a little bit of courage. You, and I, have to be brave before publishing your first article. I needed some to accept the opinions of others, I needed some to accept the remarks and comments about my opinion, way of writing and way of thinking. I needed some to accept that other ninjas will take a look and possibly prove me wrong. But at the end the discussion will bring you a lot of point of view, a lot of ideas and you will always have the chance to be better next time.

Being visible

There is a really nice side effect of writing for RebelLabs: you are visible and you’re getting more and more known. People are reading your articles, looking at your Twitter profile, reading your blog and so on. It is a nice recognition to have people with more experience than you reading your articles, commenting on them and sometimes offering you their point of view.

You start to grow much more, and very quickly. And people can see that you are passionate, up to date, open minded and full of resources. It is a very positive image you’re giving of yourself.

You also benefit of the RebelLabs’ image, so you are more considered as experimented because if you’re not, you’re going to know it very quickly. So it is good for RebelLabs and it is good for you as well.

Hot and spicy instead of glory

To conclude, I write for fun. I write because I like to share my knowledge. I write because I’m passionate. I write because I like to write. I don’t write for any glory. I’m humble enough to admit there are plenty of ninjas out there that are thousands times better than me. But I am always looking for new challenges and I like to share them because maybe it could help other ninjas like you.

It’s a great opportunity to write for RebelLabs, and I like it very much. I can only encourage you to think about it, because being a Rebel is freakin’ awesome, and it’s hot and spicy!

Partial HTML generation from textile using eclipse Mylyn standalone

The title is pretty much explicit. For SlideshowFX, I needed to generate HTML content from textile, in order to define slide’s content. Looking for a lib, I found eclipse Mylyn that can be used in a standalone way. The library is pretty powerful but I have to look a lot at the sources in order to get the things done how I wanted to (#LukeAtTheSource power). Generally to convert a markup string into a HTML one, you create a MarkupLanguage as well as a MarkupParser and do the following:

final MarkupLanguage language = new TextileLanguage();
final MarkupParser parser = new MarkupParser(language);
parser.parseToHTML("h1. My little String");

The thing is that this code will create a whole HTML document (with html, head, body and so on tags). Me needs were to just get the HTML code corresponding to my string, e.g.

<h1>My little String</h1>

So the code should be changed to use a DocumentBuilder, like the following one:

final StringWriter writer = new StringWriter();
final DocumentBuilder builder = new HtmlDocumentBuilder(writer);
final MarkupLanguage language = new TextileLanguage();
final MarkupParser parser = new MarkupParser(language, builder);

// false indicates to not produce a whole HTML document
parser.parse("h1. My little String", false);

writer.flush();
writer.close();

String htmlContent = writer.toString();

This is almost done except that Mylyn generates IDs (which is kind of normal right?) by using the content of the markup. In short, I wanted to avoid IDs’ generation but I could’t find a right and efficient way to do it. So I decided to ensure uniqueness of IDs by always getting the current timestamp. Maybe it’s not a wonderful solution, but for the purpose of this little tutorial it will be perfect. The main idea is to change the ID generation and for doing this, you have to override some classes, because the default ID generation strategy is stored as a static and final variable, and no setters are available. The following example demonstrates how to do it:

final StringWriter writer = new StringWriter();

// The generation strategy generates IDs using the current timestamp
final IdGenerationStrategy idGenerationStrategy = new IdGenerationStrategy() {
  @Override
  public String generateId(String s) {
    return System.currentTimeMillis() + "";
  }
};

final IdGenerator idGenerator = new IdGenerator();
idGenerator.setGenerationStrategy(idGenerationStrategy);

final TextileContentState contentState = new TextileContentState() {
  @Override
  public IdGenerator getIdGenerator() {
    return idGenerator;
  }
};

// Override the language to return the created contentState used for the ID generation
final MarkupLanguage language = new TextileLanguage() {
  @Override
  protected ContentState createState() {
    return contentState;
  }
};

final DocumentBuilder builder = new HtmlDocumentBuilder(writer);

final MarkupParser parser = new MarkupParser(language, builder);

parser.parse(markupString, false);

writer.flush();
writer.close();

final String htmlContent = writer.toString();

This is it. Enjoy.

Update your Scene in JavaFX

Usually it is very simple to update your scene in JavaFX. For example if you want to update the X and Y position of your nodes, you can often simply do some stuff like:

node.setLayoutX(100d);
node.setLayoutY(150d);

But this isn’t a good way of doing it. In JavaFX you have to be sure you are in the JavaFX application thread. But how can you know this?

Platform.isApplicationFxThread();

But what if you’re not in that thread?

Platform.runLater(Runnable r);

So each time you would like to update your scene manually, you should check if you’re or not in the FX application thread. So let’s make a really simple helper class:

/**
 * @author Thierry Wasylczenko
 */
public class PlatformHelper {

    public static void run(Runnable treatment) {
        if(treatment == null) throw new IllegalArgumentException("The treatment to perform can not be null");

        if(Platform.isFxApplicationThread()) treatment.run();
        else Platform.runLater(treatment);
    }
}

The method run does the check for you. Finally you can use a lambda expression to execute that code:

final Node node = ... ;
PlatformHelper.run(() -> {
  node.setLayoutX(100d);
  node.setLayoutY(150d);
});

That’s it.

PathTextField: quick example of property usage in JavaFX

Context

Properties and binding in JavaFX is a really interesting feature that sometimes is hard to illustrate. Recently I just faced a problem in CompilerFX: file paths entered by the user could be problematic. Indeed on some platforms path separator is \ and on others it is /. In Java you can often use / as path separator.

Practice

So in our example, you can choose many solutions like for example:

  • When the user submit the path in a text field, replace all \ by /;
  • When the user enter a \, use a key event to replace it;
  • Choose a more JavaFX way.

Let’s deal with the third solution. Have this ones in mind:

  • In JavaFX you have the properties, allowing you to listen for a change using a ChangeListener;
  • The text of a TextField is store in the text property.

You could implement the second solution listen previously but let’s work with a custom text field that will replace replace all \ by /.

public class PathTextField extends TextField {

  {
    textProperty().addListener(new ChangeListener<String>() {
      @Override
      public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
        if(!textProperty().isBound() && s2 != null) {
          textProperty().set(s2.replaceAll("\\\\", "/"));
        }
      }
    });
  }
}

In this component, we place a ChangeListener on the text property in order to replace all \ by /. Then you can use it in your FXML files for example.

TableView and ListValueFactory in JavaFX

The TableView control is pretty complete to use and very convenient. But the classical use of it specify that a line is represented by an instance of an Object, usually a property bean. But in some cases it would be very useful to have a line composed by multiple instances of a specific class, i.e. having an instance per column, and each column should display a particular property of your instance. A concrete example would be the management interface of translations in NetBeans. Indeed, this screen display all properties files of a particular resource bundle, having a column for the translations keys and as many columns as needed to display the translations for each keys.

netbeans_i18n_editor

As said above, we could need an instance of object per column, meaning multiple instances per line. So a line of the TableView should be a List<? extends Object>. The problem is to know which data to display in a particular column.

ListValueFactory

As you may know, you can set CellValueFactory on a TableColumn, which will display the value in the cell. For example, you can set a PropertyValueFactory that will look for a property of a bean, and will display it. But that works if you have a single Object per line, not a collection. So we will create our own implementation that will check a property of a bean inside a list.

public class ListValueFactory<T, V> implements Callback<TableColumn.CellDataFeatures<List<T>, V>, ObservableValue<V>> {
  
  private String propertyName;

  public ListValueFactory(String propertyName) {
    this.propertyName = propertyName;
  }
    
  @Override
  public ObservableValue<V> call(TableColumn.CellDataFeatures<List<T> , V> p) {
        
    int index = 0;
        
    ListIterator<TableColumn<List<T>, ?>> iterator = 
       p.getTableView().getColumns().listIterator();
        
    TableColumn tmpColumn;
    while(iterator.hasNext()) {
      tmpColumn = iterator.next();

      if(tmpColumn == p.getTableColumn())
        break;
      else
        index++;
    }

    T object = p.getValue().get(index);

    try {
      Method method = object.getClass().getMethod(propertyName.concat("Property"));
      return (Property<V>) method.invoke(object);
    } catch (Exception ex) {
      Logger.getLogger(ListValueFactory.class.getName()).log(Level.SEVERE, null, ex);
      return null;
    }
  }
}

As you can see, the implementation is totally generic. First, we try to know the index of the column and we suppose that this index is the same index of the data in the list of data. WARNING: this is totally wrong if, in your UI, you move columns ; so take this into consideration because the implementation is not shown here. Once we have the index, we look for the data in the list, and finally, using so introspection, we look for the getter of the property in order to get the value. And that’s it.

Usage

To use this implementation in your code, you juste have to do the following:

TableView<List<Person>> tableView = new TableView<>();
TableColumn<String> columnOne = new TableColumn<>("First name one");
columnOne.setCellValueFactory(new ListValueFactory<List<Person>, String>("firstName"));
TableColumn<String> columnTwo = new TableColumn<>("First name two");
columnTwo.setCellValueFactory(new ListValueFactory<List<Person>, String>("firstName"));
tableView.getColumns().addAll(columnOne, columnTwo);

“Bind” components’ size to a MediaView’s size in JavaFX

The MediaView is a control allowing you to add videos and sounds to your JavaFX application. If you are playing a video, maybe you would like another control to have the same size. For example, you can have a video played next to an image that you would like to have the same height. The easy thing would like to do some property binding like this:

final MediaView mediaView = new MediaView(aPlayerInstance);
mediaView.setFitWidth(200);

final ImageView imageView = new ImageView(anImageInstance);
imageView.fitHeightProperty().bind(mediaView.heightProperty());

But this code is wrong because the MediaView doesn’t have a height property. So in order to succeed in our goal, the MediaView has a boundsInLocalProperty which can be used to change the size of the ImageView in our case. Look at this code example:

final MediaView mediaView = new MediaView(aPlayerInstance);
mediaView.setFitWidth(200);

final ImageView imageView = new ImageView(anImageInstance);

mediaView.boundsInLocalProperty().addListener(new ChangeListener<Bounds>() {
  @Override
  public void changed(ObservableValue<? extends Bounds> observableValue, Bounds bounds, Bounds bounds2) {
    imageView.setFitHeight(bounds2.getHeight());
  }
});

Of course you have to do some nullity checks to make your code more robust.

Working with NetBeans 7.3 and JavaFX 8

Maybe you want to work with the latest version of NetBeans, currently 7.3. But also with the early access of JDK 8 in order to play with the latest features of JavaFX. The thing is that NetBeans will not launch your JavaFX application, even if you are using JDK 7. Indeed you will get an exception dealing with Nashorn.

java.lang.VerifyError: Code generation bug in "runScript": likely stack misaligned: java.lang.ArrayIndexOutOfBoundsException: 0 <eval>
	at jdk.nashorn.internal.codegen.CodeGenerator.leave(CodeGenerator.java:1003)
	at jdk.nashorn.internal.ir.FunctionNode.accept(FunctionNode.java:339)
	at jdk.nashorn.internal.codegen.CompilationPhase$7.transform(CompilationPhase.java:239)
	at jdk.nashorn.internal.codegen.CompilationPhase.apply(CompilationPhase.java:372)
	at jdk.nashorn.internal.codegen.Compiler.compile(Compiler.java:263)
	at jdk.nashorn.internal.runtime.Context.compile(Context.java:758)
	at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:720)
	at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:358)
	at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:463)
	at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:451)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:379)
	at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:134)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.util.ReflectUtil.invoke(ReflectUtil.java:108)
	at org.apache.tools.ant.util.ReflectWrapper.invoke(ReflectWrapper.java:81)
	at org.apache.tools.ant.util.optional.JavaxScriptRunner.evaluateScript(JavaxScriptRunner.java:103)
	at org.apache.tools.ant.util.optional.JavaxScriptRunner.executeScript(JavaxScriptRunner.java:67)
	at org.apache.tools.ant.taskdefs.optional.Script.execute(Script.java:52)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:398)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.Target.execute(Target.java:392)
	at org.apache.tools.ant.Target.performTasks(Target.java:413)
	at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
	at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
	at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
	at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
	at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:283)
	at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:541)
	at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
	at jdk.internal.org.objectweb.asm.Frame.merge(Frame.java:1408)
	at jdk.internal.org.objectweb.asm.Frame.merge(Frame.java:1364)
	at jdk.internal.org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1382)
	at jdk.nashorn.internal.codegen.MethodEmitter.end(MethodEmitter.java:198)
	at jdk.nashorn.internal.codegen.CodeGenerator.leave(CodeGenerator.java:1000)
	... 50 more

The problem is that NetBeans uses the most recent JDK installed on your machine to run itself. And if you look in the About NetBeans menu entry, you will see that it uses the JDK 8 if it is installed, even if your JAVA_HOME points to your JDK 7 installation.

NB_JDK7

But there is a little workaround to get things working again: you can specify, in a configuration file of NetBeans, which JDK it should use. On OSX, show the package content of NetBeans 7.3.app and go to Content > Resources > NetBeans &gt etc and open the file netbeans.cnf. In this file, locate the line containing netbeans_jdkhome and uncomment it and specify the JDK home you want NetBeans to use. For example:

netbeans_jdkhome="/Library/Java/JavaVirtualMachines/Current/Contents/Home"

Then just restart NetBeans and go the About NetBeans menu entry. You should see that your JDK 7 installation instead of JDK 8.

NB_JDK8

Now if you try to launch your JavaFX application, everything is working again.

Follow

Get every new post delivered to your Inbox.