Saturday, 30 March 2013
If you have ever watched the show South Park then you will have probably read the disclaimer that is flashed at the start. Here is my software license tribute:
Remember that software development can often be much like an episode of South Park; constant swearing, youthful naivety and surprise endings.
Friday, 22 March 2013
One tool required a DSL for interacting with phones, it would read a list of phone numbers and a file containing commands and run them over each of the numbers. For example it would make a call to the phone and configure it using DTMF* tones. I had no idea at that time how a compiler could be properly implemented so the resulting code was a complete mess and the DSL was looked like assembly for telephones. Despite the hideous code, the program saved a lot of time. To do this manually would have taken days instead of a couple of hours and be impossibly error prone. One key missing feature was error handling, which is problematic in telecommunications. Inevitably one of the calls would go wrong and the program would crash, the operator would then have to delete the completed phones numbers from the list and run the program again. No problems!
Another project provided a UI for editing INI file configuration. The program was great, except that VB does not allow more than 256 controls on a single form. My 'ingenious' solution was to put each INI section in a tab pane which also had its own window. When the user clicked a new tab, it hid the current window and showed a new window for that tab.
VB6 also comes with it's own TCP control which you must drag onto the UI to instantiate. The problem is that it had almost the same API as a serial connection control, meaning it only dealt with 1 to 1 connections. This meant it was impossible to write a TCP server. That is, until I worked out that an array of TCP controls waiting for connections worked pretty much like a TCP server. This is OK except that an array has a finite capacity, I was again limited by the number of controls so the server could only ever handle a certain number of connections.
I remember the year, the work and the company fondly and hope that some of my work is still in use. Looking back, I don't know why I used VB6 for everything. It's just so easy to get started and then keep typing, I was young and naive, that's all I can say...
* DTMF tones are those strange sounds you hear when you press a number on a phone key pad. Pieces of hardware such as phones and switches can interpret a sequence of tones as commands.
Tuesday, 25 December 2012
- Task complexity, how complex it the task and how confident is the assignee with that technology.
- Quickly documenting what a task consists of and breaking it into smaller tasks
- Having a history of past estimates and how they worked out.
There are many many more factors which affect estimation but these are the things that I want to implement first.
So, what does it do? At the moment it has some characteristics of an ERP application. You are able to add some projects, tasks and people to implement them. Tasks can be estimated and the sum of estimates are calculated for a project.
Complexity is taken into account which I think is a huge factor in any task. Tasks can be assigned "skill requirements" such as Java, SQL or anything you think you need and then can be rated out of ten. People can assign skills to themselves and rate themselves. If a task has skill requirements greater than those possessed by the assigned person then the estimate for a task is increased. I plan to improve this calculation by allowing the estimate to be increased by a percentage set in the project, instead of by a fixed number. Other factors affecting the time that a task can take will also be added.
Tasks can also be "templated", this means that the information entered for this task can be recreated. This is great for reoccurring tasks like builds, deployments or coding tasks that are very similar. It will allow these tasks to look similar and have a consistent base for estimation but be flexible and allow changes as needed. I plan to improve this to capture best practices such as including sub-tasks for testing or bug fixing that are percentages of the task estimate or perhaps even complexity.
EstiMate uses JavaFX for the frontend GUI and neo4j for data storage. It allows the user to keep a local database, to use a shared neo4j server or a neo4j database hosted on the Heroku platform. It is pure java and shouldn't need any set-up once I create an installer. At the moment, you can download the code from bitbucket and run it from your favourite IDE or command line (there might be a Maven hack there right now so be warned!).
It is licensed under GPLv3. I have blogged about some of the code I have written for this project so assume any code in this blog is free for you to use in any way you see fit without recourse to Me if it doesn't work of course!
If you have an idea or opinion or would like to contribute that would be great, feel free to comment here or tweet me @andy_till.
Monday, 24 December 2012
Here is another handy JavaFX utility to allow you to drag the bottom edge of a JavaFX Region to resize it. Layout containers inherit from Region although controls do not even though they both have a minHeight property so Controls cannot be resized using this class :(
Sunday, 4 November 2012
Controllers allowed on arbitrary nodesLarge controls usually have many action methods, many controls injected with the @FXML annotation and typically other objects like DAOs which can get quite messy. Sometimes handling code for a single control such as a combo box can get quite large, creating an FXML for a small control seems like overkill.
To tackle this, it would be useful to allow the fx:controller attribute on any FXML element specifying a node that is loaded into the scene graph. This 'sub-controller' would have controls injected with @FXML annotations in the same way as root controller except that the it would not be able have it's parent controls injected. Only the element it is declared on or that element's children could be injected.
Allow effects to be created in Scene Builder and then injected into a controllerIt is much easier to create effects in Scene Builder than it is in Java code because I can get instant feedback and fine tune much easier. It would be great if I could create an effect in FXML and have it injected into the controller using an @FXML annotation.
Support 'Actions'One of the things that I miss from Swing is the javax.swing.Action interface. This was used to encapsulate action logic of a button in a single class instead of having many action listeners in one class. I could create a class implementing EventHandler
Specify some validations on TextField controlsFor Me, FXML is all about productivity so it makes sense that it could support common requirements such as validations on TextField controls. For example, a TextField might only allow numeric input up to a maximum number. If you google "javafx numeric textfield" there are already many varied implementations. It would be great to see this in Scene Builder, even better if it could be tested in preview mode.
Thursday, 4 October 2012
Testing JavaFX controllers is relatively easy although you do have to jump through a couple of hoops. Firstly, JavaFX must be initialised and secondly JavaFX controls must only be mutated on the JavaFX thread created internally during initialisation. The JUnit rule below will setup JavaFX once and run all tests on the FX thread. All you need to do is create it as a field in your test case class and annotate it with
@org.junit.Rule. You will need to be running JUnit 4.9 to use the rule API.
Tuesday, 4 September 2012
This code is now integrated into the fx-guice project where it will be maintained. I am not intending to modify the GitHub gists so this post now only serves to document the code as seen here.
It is very simple to inject controllers into an FXML control using Guice but once the UI starts to get bigger it is likely that we will need to split it out into smaller files. I wanted to do this with a list builder control simple to that in SceneBuilder used to build a list of CSS classes.
Here is a run down of my final solution although it is not altogether as simple as I would have liked it. This tutorial is much more complex than my previous FXML/Guice post, I had to look up my own tutorial on Guice scopes to work it out. Please let me know if anything is not clear
1. Add the Guice ModuleAdd the following Guice module to your Injector. This example also assumes that you are using the same Injector to inject controllers when loading FXML, this is detailed on my previous Guice/FXML post.
The module uses the following Guice scope to track all injected controllers.
2. Use a scope annotation on the controllerReusable controllers are annotated with the custom @FXMLLoadingScope.
3. Implement the IdentifiableController interface in the controllerReusable controllers must implement the IdentifiableController interface which has one method, #getId(). #getId() must return a non-null String containing the ID of the parent of the root pane of the control. If this ID is null then return the second parent-parent's ID. Keep going until a non-null ID is found.
4. Set an ID on the parentWhen importing one FXML file into a parent, set the container ID to the ID you want for the controller.
5. Retrieve the child controllerIn our parent controller (the one that that will tell the list builder what to do) we need to retrieve the list builders controller to populate options and so on. To do this, Inject an instance of ControllerLookup into the parent controller.
In the parent controller, make sure you implement the Initializable interface. In the initialise method of the parent controller call ControllerLookup#lookup(String) on the instance you have injected to retrieve the child controller. The ID that is passed in should be the ID that is returned by IdentifiableController#getId(). This could be hard coded but in this example it is using the FXML ID of the parent control, "factorsList" in this case. This allows several list builders to be used in the same parent control.
I am using this in my own JavaFX project and although the implementation was not simple I have found it quite easy to use.