Monday, 20 August 2012

JavaFX CSS Styling

I've been working on a light grey look and feel for JavaFX with square corners, inspired by the Swing Substance (Business Grey) Look and Feel.  Here are the results so far:




And just as a reminder as to the default JavaFX look and feel:



This is a work in progress and not all of the controls are styled.  This skin has now become the first entrant in the jfxtras-styles project hosted on github or click here if you just want to grab source.

The extra space is to show the drop shadows on the titled panes which I use quite a lot in my own application.

Update:
Just to show the different a little CSS styling can do, below is a recent screenshot of EstiMate, the JavaFX project I have been working on.  It's come a long way!  You can take a look at the CSS here.

Sunday, 1 July 2012

Creating JavaFX Controllers Using Guice

I really like Guice Dependency Injection so was pleased to hear that some work has been done to make this interact with JavaFX. The solution presented though, was less than ideal. It had some duplication of configuration where the class name of the controller needed to specified in the FXML as you would expect but also when loading it. After a brief fumble through FXMLLoader's methods I found #setControllerFactory. By passing this wafer thin adapter below as a parameter to #setControllerFactory, any controllers will be instantiated via Guice.

Monday, 4 June 2012

JScrollPane Repainting Problems

I was having some problems with the JScrollPane not repainting my custom component properly when scrolling.  The results were that the area that was now visible because of the scroll was painted unevenly and looked blurred.  This seems to happen when a component is doing some custom rendering inside a JScrollPane and using the clip to find out what area it should paint.  To fix this call the following methods on your JScrollPane:

scrollpane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);

In the modern swing implementation there is some 'clever' caching of the content view to improve performance which seems to be the problem.  Setting SIMPLE_SCROLL_MODE will force the scroll pane to repaint it's entire contents while scrolling.  Although this is less performant, it at least shows the correct results with minimum fuss.

Friday, 6 April 2012

Safely Removing an Element While Iterating a List

If you want to remove an element while you're iterating a Java ArrayList then you have some problems.  First off, if you use an iterator then the list will most likely throw a ConcurrentModificationException.  If you use a classic style for loop then when you remove an element the list will no longer be the same size or have it's other elements at the same position as when you started iterating which might cause an error, logical or otherwise.

The simplest way to do this is to iterate backwards over the list.  This means when you remove an element, the other elements will not get reordered.  The method below demonstrates:

    public void iterateBackwards()
    {
        List list = new ArrayList(Arrays.asList(1,2,3,4,5));
       
        for (int i = list.size() - 1; i >= 0; --i)
        {
            System.out.println(list.remove(i));
        }
    }

This prints....

  5
  4
  3
  2
  1

Thursday, 22 March 2012

Fastest Way to Delete a Directory In Windows

I had a load of large directories (several GBs) which I needed to delete so that I could meet the minimum free space requirement for Windows to run the defragmentation tool.  Unfortunately, Windows Explorer is unusably slow for this as it first scans the whole directory so that it can show the estimate and then copies everything into the recycle bin or not if the directory is too big.

Below is some batch script to delete a directory very fast.  The code is on stack overflow here where the commenter Hugo bench marked it at 3 times faster than rmdir which itself is a hell of a lot faster than deletion via Windows Explorer.

bestrmdir.bat

rem to use, drop in your c:/windows/system32 directory for this to be usable anywhere
rem in then command line type 'bestrmdir MyDirectory' to delete MyDirectory
del /f/s/q %1 > nul 
rmdir /s/q %1

Wednesday, 29 February 2012

Typed Integers

I really like the idea of typed integers. For example, if you a number representing the number of cats and a number representing a number of dogs it is possible to add these together.  In a typed integer world it would not be possible and throw an error upon compilation.  I think this would be a big improvement for API safety and also a method of documentation.  There is nothing worse than a method with a structure like #foo(int, int) which is difficult to understand without reading or documentation every time.

In general use this would be suicide in a managed language where the overhead of an object for every int could mean a huge jump in memory usage and GC wouldn't be worth the improvements.  The actual implementation in Java would also be extremely ugly, for example:

class EventID {
  private final int id;
  public EventID(int anID) {
    id = anID;
  }
}

The class doesn't even contain basic methods like a way to get the ID, compare or hash it which with an int you get for free and it is still a fair wedge of code.  Lombok's @Data annotation can really improve classes like this and make the language feel more declarative.

I have found the best language to implement this is c++, the following is my proof of concept implementation:

template
class TypedInt
{
public:
  const int value;

  TypedInt(int v) : value(v) {};

  TypedInt operator + (TypedInt num)
  {
    TypedInt result(value + num.value);

    return result;
  }

  TypedInt  operator = (const int other)
  {
    TypedInt result(other);

    return result;
  }
};

This allows the following usage:

struct eventid {};

typedef TypedInt EventId;
  
EventId i = 2, j = 3;

EventId result = i + j;

Overall this feels natural to use.  If I was actually using class then the other operators such as == could be implemented without problems. 

One of the benefits of c++ is that an object wrapping an int does not take more memory than an int would, during compilation this abstraction is apparently stripped away.

Sunday, 26 February 2012

Compatible Images

A couple of weeks ago I was tasked with improving the performance on a legacy java swing application that was really crawling.  It would repaint the whole screen on any event, which it could receive a lot of, and painting the whole screen was really slow.  By using compatible images instead of the default kind of image read by ImageIO, the painting code was sped up by a factor of 70 and the event frequency was a non-issue.  The whole change was about 10 lines of code, much less than that to make the software use the graphics clip.

If you are having an issue with graphics performance make sure you try compatible images before trying anything else since it is so easy to introduce.

Before deploying to site I was worried that the speed up I was seeing was in some way down to my dev machine working well with compatible images so I wrote the tool below to test if the improvement was the same which it was.  Some notes:
  1. The tool requires an image.  When I attempted to create an in-memory image there was no difference in run times.
  2. Results are printed on the command line so remember to use java.exe and not javaw.exe
  3. I went to some effort so that this program was a single class to make it easy for the support guys to run.  I don't usually like to implement Runnable on a class that isn't just a Runnable.