ojob
Related Articles
JBoss at Work in print
The JBoss book market has taken a very positive turn this year, with several quality JBoss titles being released. This month, we another great O'Reilly title: JBoss at Work. I had a chance to review early drafts of the book, and I think Tom and Scott have done a good job with it. It's a great introduction to J2EE development on JBoss, and I definitely recommend taking a look at it if you are planning to start a new JBoss project or are looking to migrate an existing J2EE project from another application server.
Several people have asked how JBoss at Work compares to JBoss; A Developer's Notebook. The books are quite complimentary. With the notebook, you get a fast paced, bare bones "how can I make my app work on JBoss" book. JBoss at Work, on the other hand, is a bit more comprehensive and tries to explain more of the big picture of application development in JBoss. If you found the JBoss notebook a little too fast or need a bit more guidance on how to architect an application in JBoss, you'll enjoy JBoss at Work.
If you have any doubts, JBoss at Work should be on the shelves of your local bookstore by now. Go check it out.
JSF passes Swing as the number one Java GUI component model for job demand
Kito suggested I change the search from JSF and java to (jsf or "JavaServer Faces" or "Java Server Faces") and java.JSF passed Swing as the number one GUI component model for Java.
JSF did well in 2007. Let's put it this way: If job demand for the Struts framework and JSF were a stocks and you invested in it in April of 2005 by July of 2007 you would barely break even with Struts but with JSF your investment would have grown 700% as of July 2007. (According to indeed.com.)
Wayne Beaton: DeferredContentProvider: My new favourite thing
I’ve built two tables over the past two days and both of them are pretty expensive to populate. Leaving the user waiting while you run off and fetch all the data before you can display the table is bad form. To keep in your users’ good graces, consider using the DeferredContentProvider.
DeferredContentProvideris part of JFace, and works well with the JFace TableViewer(I assume that it can also work with a TreeViewer, but haven’t tried it yet). Rather than try and do a bad job at explaining how it works, here’s an example of an Eclipse view that employs one:
...
public class SampleView extends ViewPart {
private TableViewer viewer;
private SetModel files = new SetModel();
private Job findFilesJob;
...
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.VIRTUAL | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new DeferredContentProvider(new Comparator() {
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
}));
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setInput(files);
startFindFilesJob();
}
...
} This view lists—in a table—all the files in your file system. As you might expect, this can take a while. Starting from the top of the createPartControlmethod, you’ll notice that I’ve created the TableViewerusing the SWT.VIRTUALstyle: this is a requirement of use for the DeferredContentProvider(it configures the table to ask for the bits it needs to display as it needs them, rather than getting them all up front; more information here).
The content provider for the TableVieweris set to a new instance of DeferredContentProvider. The solitary constructor requires that a Comparatorbe provided: this Comparator, which must be provided, tells the content provider how to sort the items in the table. If you want to change how items are sorted, you need to tell the content provider, not the TableViewer.
The next bit is the input. The input tells the table what to display. The input has to be something that implements IConcurrentModel. For our purposes, an instance of the SetModelclass (which has been created in the field named “files”) does what we need.
The last thing the method does is start a Jobto populate the table via the startFindFilesJobmethod:
private void startFindFilesJob() {
findFilesJob = new Job("Find Files") {
@Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("Find files", IProgressMonitor.UNKNOWN);
for (File root : File.listRoots()) {
findFiles(monitor, root);
}
if (monitor.isCanceled()) return Status.CANCEL_STATUS;
return Status.OK_STATUS;
}
};
findFilesJob.setPriority(Job.DECORATE);
findFilesJob.schedule();
} Note that this very simple example starts populating itself when it is opened, and I haven’t provided any means of restarting the population process other than to close and reopen the window.
Creating the job is pretty straightforward. I’ve decided to set the priority of the job to the lowest setting (Job.DECORATE) because experience has shown that it takes a very long time and I want the rest of the workbench to be as responsive as possible. The job, as defined above, will appear in the Progress view where is can easily be canceled. There’s more information about the Jobs API here.
The findFilesmethod recursively discovers the files and adds them to the SetModel(highlighted):
void findFiles(IProgressMonitor monitor, File root) {
if (monitor.isCanceled()) return;
File[] children = root.listFiles();
if (children == null) return; files.addAll(children);for (File file : children) {
findFiles(monitor, file);
}
} When the addAllmethod is called, the magic happens and the table is updated. It’s pretty neat to watch. Hypnotic even.
For completeness, the disposemethod stops the job (no need to keep doing the work if the user closes the view):
@Override
public void dispose() {
findFilesJob.cancel();
} For what I’m doing, the SetModelseems to work well. I believe that this is true only because I’m updating it in a single thread. A quick browse through the code leads me to believe that it would break if multiple threads tried updating it at the same time. So keep that in mind.
I’m using the DeferredContentProvideron a plug-in that scans an IFileStorefor image files and displays them (right now, I have it scanning eclipse.org’s CVS server). The deferred loading of the images is darned cool to watch. Once this reaches a reasonable level of maturity, I’ll let you know.



