Archives for January 2008

WWIG - Pastebin

Through random surfing, I came across the site 7days7apps.com. It’s an effort to create seven applications using the Python Django framework. I decided to implement the paste bin example for the second edition of WWIG. It’s very simple but I think it would be useful to beginners since it’s a fully functional Grails application with only one domain class, one controller, one plugin, and ...you guessed it, one taglib(pretty date taglib from GroovyBlogs).

In addition to the basic CRUD operations1, posts expire after their interval has passed and thanks to google-code-prettify, most languages have syntax highlighting.

Post expiration

 class DeleteSnippetJob {
    def timeout = 60000l     // execute job once in 60 seconds

    def execute() {
    // execute task
    def oneHourAgo = new Date()
    oneHourAgo.minutes = oneHourAgo.hours - 1;
    def snippets = Snippet.executeQuery("from Snippet s where s.dateCreated < ?", [oneHourAgo])
    for (snippet in snippets) {
        def date = snippet.dateCreated.clone()
        date.hours += Integer.parseInt(snippet.durationHours)
        if (date.before(new Date())) {
            def id = snippet.id
            snippet.delete()
            log.info "deleting snippet ${id}"
        }
    }
    }
}


In the above code, we first find the posts that are at least one hour old (the short snippet duration). After getting that list, we iterate through it and remove the snippets that have expired.


Given that it’s a paste bin app, don’t expect high design, it is what it is. A simple quick and dirty application. Just in case folks were wondering, the title logo was made in Blender.

 


Download the source code here. Or demo the application:http://jameswilliams.be/pastebin.

It’ll be up for at least a week or so2.



1well actually CR since deletion and updates have been disabled

2provided it doesn’t use up all my VPS memory

So that is a rich application?

I visited java.net today and saw the headline "Create rich applications with JavaFX Script." Though I’m not what you would call adherent of the JavaFX dogma per se, I do like to keep abreast of what’s going on. I’ve been watching it since it was F3.

So I clicked the link and to my utter dismay, the "rich application" was a calculator. A run of the mill, generic, basic four function calculator. WTF? What’s with the wacky 7,4,1, and 0 buttons?

My definition of a rich application is something that is impeccably designed, clean and succinct, yet complex enough to give the everyday user something to aspire to. If it does look like a simple app, it must innovate on terseness of code or some other technical area. This "rich application" does neither. In this case a reimplementation would have been more palatable. Like this for example. A reimplementation can leverage the familiarity of the original in an attempt to understand the copy.

Now this is a rich calculator(from when JFX was F3): http://blogs.sun.com/chrisoliver/entry/macos_dashboard_widgets

I liked the demos coming out of JFX back when it was F3. What’s the deal now?

*I still think it looks like an intepretation of a Groovy builder but that’s already been discussed ad nauseam so I’m gonna leave it be.

Where is the groovy tag on DZone?

If you search DZone for Groovy, currently it says there are about 526 stories. I think that’s more than enough to warrant its own tag. Here’s how some other languages stack up:

Perl:         506
Python:        1398
C-and-cpp:    1233

Granted Groovy is not the most popular language on DZone but it’s more popular than Perl and doing pretty well for one of the younger kids on the block. The only downside to this is that it makes it easier for the haters to find stories to vote down.

Motivation comes when you least expect it - Google Chart Plugin

Zig Ziglar once said:
People often say that motivation doesn’t last. Well, neither does bathing - that’s why we recommend it daily.”

My daily dose was Graeme’s nod on his blog yesterday. In wrapping up the last few remaining issues, I am happy to announce that the Grails Google Chart plugin now fully implements Google’s spec. New in this release is:

  • line styles
  • grid lines
  • shape markers, and
  • range fill

The one breaking change is that the attribute "shapes" has changed to shapeRangeFill because those features use the same attribute key on Google’s side.

It has come across my mind more than once to abstract a chart into a domain object so that it can be stored. For the needs of most Google’s 50K threshold is perfectly fine. The one area that might cause issues is if there are many charts using the extended dataset being parsed at the same time. If the data changes infrequently, it’s better to store the data string than regenerate. Additionally, a domain object could allow the user to use nicer color names.

Thoughts? Objections? Concerns?

Groovy package ideas

So I’ve been poking around a bit learning Debian policy and how to build from source, which, by the way is much more difficult that building a regular binary package but anyways... Usually in Debian-land, applications live in usr/share and libraries live in usr/lib.

When you want to add, for example groovy-xmlrpc, you generally either add the jar or a link to the jar in the GROOVY_HOME/lib directory. This becomes a little bit problematic when you upgrade versions. Putting the jars directly in lib/ makes it where the groovy package would have to enumerate every core lib and preserve jars not on the list. Not really fun and prone to errors if a dependency changes, etc, etc. On the other hand, installing libraries in /usr/lib/xxx seems like a bit much for a one-off jar. But they do need to go somewhere.

In one of my random chats with Andres, I kinda tossed around the idea of adding a GROOVY_HOME/extra-libs directory and a small bash script(in GROOVY_HOME/bin) to recurse the list in extra-libs and create symbolic links after an upgrade to handle optional libraries more gracefully.

I was thinking something like this:
GROOVY_HOME/extra-libs/
GROOVY_HOME/extra-libs/swingxbuilder
GROOVY_HOME/extra-libs/swingxbuilder/0.1.5
GROOVY_HOME/extra-libs/swingxbuilder/0.1.5/swingxbuilder.jar

Under such a scheme, you could have everything in one place and organized with access to multiple versions of a library. It would symlink the latest version but the user can arbritrarily add an older version to the classpath of an application if needed . AFAIK Windows has limited symlink capabilities, so this would be a UNIX/BSD only thing. But as a packager, it makes my job a whole lot easier.

What do y’all think?

Haiku Java Team formed

Haiku is a reimplementation of the former BeOS system. BeOS was an operating system in the late 90s that started as an alternate OS for PowerPC computers(mostly Apple) before being ported to the Intel architeture to gain market share. It never quite caught on and was later acquired by Palm. One of distinguishing "features" of the system was that it has a consistent user interface theme for any applications that run and it can’t really be modified.

I’ve never used Haiku or BeOS but can appreciate the simplicity of its design. I think it will be interesting to see how they implement Swing and AWT given the way that the core operating system runs. It may have took a year to pick up speed but OpenJDK has legs now. First SoyLatte and now this one. Very cool...Come on guys, you gotta pick a cool name for Haiku’s port of Java. I suggest  chanoyu, the Japanese tea ceremony.

Read the full blog post here.

 

WWIG - JFlubber

Let me first state that it is very possible that any of the applications in this series, if reimplemented today in the original implementation language, might see a reduction in code size/simplification due to libraries, methods, or techniques that weren’t available the first time around. That is probably the case with this first example as I am pretty sure that some of the implementation code eventually made its way into the SwingX components.


jFlubber, in its orginal version, was created by Dick Wall (of Java Posse fame) as a tool to mark flub spots during the recording of the podcast and as a way to learn Matisse. In its second iteration, Romain[Guy] injected some bling. That’s the version I’ve recreated in Groovy.

Dick’s Original Version Romain’s version

 

Creating the buttons

Instead of creating each button with a half a dozen method calls as Matisse did, I was able to refactor it into a single function that takes a string and a closure for the ActionListener. 

 

 def createButton(buttonString, action) {
  return swing.button(borderPainted: false, contentAreaFilled: false, focusPainted: false,
    icon: swing.imageIcon(getClass().getResource(baseIconString + buttonString + ’-button.png’)),
    pressedIcon: swing.imageIcon(getClass().getResource(baseIconString + buttonString + ’-button-pressed.png’)),
    actionPerformed: action)
     } 

 

TimeLabel and WoodenContentPane

Because Groovy doesn’t allow inner classes, these had to be broken out of the main form class file. For the time label, thanks to the existence of Painters, I was able to construct a component duplicating the effect using a CompoundPainter :

 

private TimeLabel() {
  compoundPainter = swing.compoundPainter() {
     imagePainter(image: ImageIO.read(getClass().getResource("images/metal.png")),scaleToFit: true)
                 textPainter(id: ’txtPainter’, font: new Font("Arial", Font.PLAIN, 36), fillPaint: Color.white) {
                         shadowPathEffect()
                 }
          }
           setBackgroundPainter(compoundPainter)
} 

 

Only cosmetic changes were made to the WoodenContentPane class file. registerBeanFactory registers the class with the builder so that we can reference it like any other built-in component.

 

swing = new SwingXBuilder()
swing.lookAndFeel(new org.jdesktop.swingx.plaf.nimbus.NimbusLookAndFeel())
swing.registerBeanFactory("woodenPane", WoodenContentPane)
swing.registerBeanFactory("timeLabel", TimeLabel)
... 
timeLabel = swing.timeLabel(text: ’0:00’) 

 

And now for the pièce de résistance, the code to build and layout the GUI. Warning: ymmv if your resolution is less than 1024x768. I’ve not yet found a reliable way to duplicate the efficient resizing from GroupLayout in MigLayout. The spacing is a little bit baked in. A sacrifice made for speed’s sake.

def pane = swing.woodenPane(layout: new MigLayout()) {
  def x = centerObject(261)
  widget(timeLabel, constraints: "id timeLabel, w 261!, h 81!, x " + x)
  widget(startButton, constraints: ’id startButton,x timeLabel.x-5, y timeLabel.y2+10’)
  widget(stopButton, constraints: ’id stopButton, x startButton.x2+45, y startButton.y, x2 timeLabel.x2’)
  flubX = centerObject(flubButton.getSize().getWidth())

  widget(flubButton, constraints: ’id flubButton, x 75, y 150,wrap’)
  scrollPane(constraints: ’id scrollPane,x timeLabel.x+10, x2 timeLabel.x2, y flubButton.y2+10’,                     horizontalScrollBarPolicy:    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) {
     widget(flubPointsTextArea)
  }
  widget(saveButton, constraints: ’x startButton.x, y scrollPane.y2+20’)
  widget(clearButton, constraints: ’x stopButton.x, y scrollPane.y2+20, x2 timeLabel.x2’)

}

 

And here’s how the Groovy version looks. Download the tar’d project archive here.