The Source for Java Technology Collaboration
User: Password:



Evan Summers's Blog

June 2007 Archives


Entity Equals

Posted by evanx on June 28, 2007 at 08:01 AM | Permalink | Comments (0)

Let's look at neatening up those messy equals() and hashCode() methods in our entities.


Code Snippet

public class Feed {
    private int id;
    private String uri;
    ...
    private Comparable[] values() {
        return new Comparable[] {id, uri};
    }
    
    public boolean equals(Object object)  {
        if (object instanceof Feed) {
            Feed feed = (Feed) object;
            return typeHelper.equals(values(), feed.values());
        }
        return false;
    }
    
    public int hashCode() {
        return typeHelper.hashCode(values());
    }
}    

where we implement a values() method to return an array of our IDs et al for hashCode() and equals(), and utilise a helper class.




Chronicles of the Trove: Fixing by Deprefixing

Posted by evanx on June 17, 2007 at 07:42 AM | Permalink | Comments (1)

I have one very simple rule for design, namely to create as many classes as possible! Let's name this "Evan's Rule of Simplicity by Multiplicity."

So I just noticed a simple cue to refactor out a class. Consider the following GUI construction.

public class MainView {
    JTabbedPane mainTabbedPane = new JTabbedPane();
    ...
    DefaultMutableTreeNode categoryRootTreeNode = new DefaultMutableTreeNode(new CheckBoxModel("All", false));
    DefaultTreeModel categoryTreeModel = new DefaultTreeModel(categoryRootTreeNode);
    JTree categoryTree  = new JTree(categoryTreeModel);    
    ...    
    public MainView() {
        categoryTree.setEditable(true);    
        ...
    }
    ...
}    

You see we have a few related components categoryTree, categoryTreeModel and categoryRootTreeNode. They all start with the same prefix ie. category, so as to distinguish them from other trees.

So the clue is when seeing such prefixes, refactor them out to a class so as to "de-prefix" them, as follows.

public class CategoryTreeView {    
    DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode(new CheckBoxModel("All", false));
    DefaultTreeModel treeModel = new DefaultTreeModel(rootTreeNode);
    JTree tree  = new JTree(treeModel);
    
    Map<Category, DefaultMutableTreeNode> treeNodeMap = new HashMap();
    Map<Feed, DefaultMutableTreeNode> feedTreeNodeMap = new HashMap();
    
    TreeCellRenderer renderer = new CheckBoxTreeCellRenderer();
    CheckBoxTreeCellEditor editor = new CheckBoxTreeCellEditor();
    ...
    public CategoryTreeView() {
        tree.setEditable(true);
        ...
    }        
    ...
}    

So let's name this "Evan's Rule of Fixing by Deprefixing."

A further step might be refactoring this to extend something eg. JTree or DefaultTreeModel, rather than being a composition.

We hook up that class, to a now simpler MainView.

public class MainView {    
    JTabbedPane mainTabbedPane = new JTabbedPane();
    ...
    CategoryTreeView categoryTreeView = new CategoryTreeView();
    ...        
    public MainView() {
        ...
    }
    ...
}    

So our increasingly complex system progressively devolves to a collection of increasingly simple classes. It's nice!

PS. Here is (another) sneak preview of this feed reader toy that's been distracting me of late, and the actual reason i wrote this blog entry, ie. as an excuse for this postscript, as will be the case with all entries in this series - I know, gutting.

PPS. That's from The Office when David Brent says, "Well, there's good news and bad news. The bad news is that Neil will be taking over both branches, and some of you will lose your jobs. Those of you who are kept on will have to relocate to Swindon, if you wanna stay. I know, gutting. On a more positive note, the good news is, I've been promoted, so... every cloud... You're still thinking about the bad news aren't you?"

Launch   (FeedTrove, 1M/350k, unsandboxed, Java6)

There seems to be the odd GUI feeze-up but i don't know why!? I'm doing every GUI-ish thing on the EDT as far as i can see. Personally i suspect JEditorPane! ;) Anyway, one can dispose the frame into the system tray, and pop it up again.




Chronicles of the Trough: Sneak Preview

Posted by evanx on June 07, 2007 at 01:18 AM | Permalink | Comments (4)

Here is a sneak preview of a trivial feed reader app using the Java6 SystemTray. It checks a few preconfigured (Java) feeds every 10 minutes, popping up a message when a new article is spotted.

Launch   (FeedTray, 1M/250k, unsandboxed, Java6)

The feedtray app itself is small (18k using pack200), but depends on ROME and AppFramework and their dependencies ie. jDOM and SwingWorker, so the total packed size is around 250k, and unpacked, well... much more!

Note that when you minimise or close the window, the frame is disposed, but the app still runs in the SystemTray. You have to right-click on the TrayIcon and choose "Exit" to exit the app and dispose its JVM instance.


Resources

You can browse the code for this exercise at feedtray.dev.java.net.
See the classes FeedTrayApplication (and it's resource file), FeedSystemTray, FeedManager, FeedReader.

FeedTray requires rome.dev.java.net (which requires jdom.org),
and AppFramework.dev.java.net (which requires swing-worker ie. org.jdesktop.SwingWorker).

Also see "New System Tray Functionality in Java SE 6," on the Sun Developer Network,
and "Displaying messages in the system tray," by Michael Nascimento Santos.






Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds