1 2 Previous Next


17 posts

SwingX 1.6.5-1 Released Blog

Posted by kschaefe Feb 27, 2013
Due to a painting regression in JXPanel for Synth-based Look and Feels, we are releasing a regression fix.  The new files should appear in Maven Central soon.

SwingX 1.6.5 Released Blog

Posted by kschaefe Jan 28, 2013

SwingX 1.6.4 Released Blog

Posted by kschaefe Jul 22, 2012
I am pleased to announce the release of SwingX 1.6.4.  This release is small, fixing a few critical items and following the standard process of removing deprecated code.  The main cause for this release was that SwingX 1.6.3 failed to correctly build the swingx-all sources and javadoc jars. Please let us know if you have any issues or concerns with this release. Karl

SwingX 1.6.3 Released Blog

Posted by kschaefe Feb 1, 2012

I am very pleased to announce the release of SwingX 1.6.3.  While the release notes contain many fixes, I wanted to take a minute to highlight some of the major changes.

First and foremost, we have more fully adopted Maven.  The project is now a collection of smaller modules. This will make it easier for clients to use only the pieces of SwingX that they need or want.  To enable us to break SwingX into smaller modules, some classes have been moved or reorganized.  Don't worry, we've left a deprecated copy in the original location in all instance but one (I'm looking at you JXBusyLabel.Direction).

Secondly for Maven, we needed to rename our groupId.  Per discussions with the maven.java.net folks, we are now using org.swinglabs.swingx as the groupId.  This is a change from org.swinglabs.  Doing so allows us to use the maven.java.net facitilities for automatically updating Maven Central with our releases.  Future releases should be a lot easier for us in that regard.

The third Maven-related change is that swingx-core no longer contains a copy or dependency on all SwingX classes.  The swingx-graphics package is not used by any of our components.  To suppliment the need to have an all-in-one jar, we have created the swingx-all module which provides all SwingX content as a single JAR file.

To highlight some non-Maven changes, we have:

  • Improved our serialization support.
  • Improved our beaninfo support.
  • Rearchitected our plaf support to allow third party L&F support in the future.
  • Fixed a ton of bugs.
  • Improved our testing style and code coverage.

If anyone is experiencing any issues with out latest release, please let us know over in the forums.  Any feedback, especially about how we divided the code into modules, is always welcomed.

Thanks and enjoy!

The first rule of Swing programming is to always interact with Swing components in the Event Dispatch Thread (EDT, for short).  Swing is single-threaded (as a lot of UI toolkits are) and as such it can only makes guarantees about the state of Swing components when interacted with properly on the EDT.  Some Swing methods are thread-safe, such as JComponent.repaint.  Recently, I discovered that RepaintManager, the class that handles Swing painting (used by JComponent.repaint), can access a JComponent's state off of the EDT.

The Problem

Here's what happened. My company, to ensure that we do not violate the Swing "prime directive," uses an aspect to interleave EDT checking code in our internal builds.  During one of our latest builds, we started seeing threading violations reported.  At first, we thought it was the new look and feel we were using doing something untoward, but it was simply calling JComponent.repaint() from an animation thread.  Digging into the internals of the RepaintManager, I found the following:

  1. JComponent.repaint calls RepaintManager.addDirtyRegion.
  3. RepaintManager.addDirtyRegion calls into the private implementation RepaintManager.addDirtyRegion0.
  5. RepaintManager.addDirtyRegion0 calls JComponent methods without ensuring the calls happen on the EDT.    
    1. getWidth()
    3. getHeight()
    5. getParent()
    7. isVisible()

The following class demonstrates the "problem:" 

import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.*;

import javax.swing.*;

public class RepaintThreadViolations {
    private static class TestingComponent extends JLabel {
        public int getWidth() {
            assert SwingUtilities.isEventDispatchThread();
            return super.getWidth();
        public int getHeight() {
            assert SwingUtilities.isEventDispatchThread();
            return super.getHeight();
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                final JLabel label = new TestingComponent();
                label.setText("Hello world!");
                frame.add(new JButton(getAction(label)), BorderLayout.SOUTH);
    private static Action getAction(final JComponent comp) {
        return new AbstractAction("Repaint") {
            public void actionPerformed(ActionEvent e) {
                SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
                    protected Void doInBackground() throws Exception {
                        return null;
                    protected void done() {
                        try {
                        } catch (InterruptedException e) {
                        } catch (ExecutionException e) {

The embedded SwingWorker is calling the repaint on a background thread.  This will trip the assertions in TestingComponent.getWidth and TestingComponent.getHeight because RepaintManager is not calling the methods from the EDT.

Is it thread-safe?

Technically speaking, RepaintManager is not thread-safe.  Each call to addDirtyRegion0 makes several calls to Swing methods that are known to be not thread-safe.  As such, it is possible that RepaintManager may obtain stale data from a dirty read.  The following steps illustrate that possibility:

Stale Data Example for RepaintManager.addDirtyRegion0
Thread 1 (EDT)Thread 2
Existing Swing component has a size of 0x0. 
 Swing component is repainted with repaint().

RepaintManager.addDirtyRegion0 calls getWidth().

 Component receives a new size of 100x100.            



RepaintManager believes that the component's size is 0x0.

 Component fields are updated with the new values.            



Even though the component's size is in the process of updating to 100x100, the RepaintManager obtains 0x0.  Furthermore, if the a component returns a height or a width of 0, RepaintManager will not even queue it for painting!

How does it work?

RepaintManager is trading accuracy for speed.  Most of the time the value will not be stale and it is a lot faster to read (a possibly stale) value, than to synchronize (or to serialize the calls on the EDT).  So, how can RepaintManager get away with this?  The reason is simple: anything that would change the size of a component or its visibility actually occurs on the Event Dispatch Thread and those changes always cause a repaint to occur.  This means that in our example above once the component's size is set to 100x100, a new event will cause the RepaintManager to repaint the component.  That event will be on the EDT and the RepaintManager will have accurate information.  So even if the RepaintManager fails to repaint because of stale data an EDT-based event will cause another repaint to happen that all is well.  Furthermore, the actual painting occurs on the EDT, this gives the RepaintManager another bite at the apple where it can ensure that the data it has is accurate.

This does not mean that getHeight, getWidth, or isVisible are thread-safe; this is an advanced optimization based on a deep understanding of Swing and how it propagates events.  I would not recommend anyone to build Swing code in this way, but this overview gives a good understanding of how it is possible to break the Swing threading model and still come out on top.

I would like to thank my friend Alex for reviewing this blog.

Last week, I updated my local copy of the SwingX source code, modifying SwingXUtilities to inlcude an invokeLater and an invokeAndWait that support return values.  I plan on checking in that code sometime today.  In one of those strange coincidences, Swing links of the week pointed me to Jan Kotek's post: SwingUtilities.invokeAndWait with return value.  It's a good article, but my solution was different.

To obtain a value, we will use a Callable (basically a Runnable that supports return values).  I use FutureTask to wrap my Callable.  A FutureTask is a Runnable, so it may be directly submitted to either of the core SwingUtilities invoke methods.  The get method in FutureTask is the method that actually returns the value (it is blocking).  So, we begin by creating a new invokeLater method to wrap SwingUtilities.invokeLater.

public static <T> FutureTask<T> invokeLater(Callable<T> callable) {
    FutureTask<T> task = new FutureTask<T>(callable);
    return task;

This method will not block the calling thread and now you have access to the FutureTask, enabling you to get the value (at some future point).  Building on that, we can create a method that blocks, just as SwingUtilities.invokeAndWait does.

public static <T> T invokeAndWait(Callable<T> callable) throws InterruptedException,
        InvocationTargetException {
    try {
        //blocks until future returns
        return invokeLater(callable).get();
    } catch (ExecutionException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else if (t instanceof InvocationTargetException) {
            throw (InvocationTargetException) t;
        } else {
            throw new InvocationTargetException(t);

By using FutureTask.get, we can create a blocking method that waits for the return value by calling get.  Since it returns wrapped exceptions, we unwrap them and pass them on as appropriate.


SwingX: JXScrollMap Blog

Posted by kschaefe Sep 22, 2010

I mentioned during my BOF at JavaOne a new component that is close to ready for moving into SwingX: JXScrollMap.

Part of the way that SwingX works is that members first join the incubator project. Members contribute ideas to the incubator, flesh them out, and eventually bring them into SwingX. The incubator contains lots of stuff from really mature ideas to things that aren't. Some of the ideas have moved into SwingX, but a number of good ideas still reside there.

As SwingX was preparing for version 1.0, we placed a ban on any component additions, as we needed to concentrate on the issues at hand. The first goal post-1.0 was to remove SwingX sorting and filtering migrating JXTable and JXList to core sorting and filtering. During this time we also identified a few components that we thought might make good additions to SwingX proper. One such component was the ScrollPaneSelector.

ScrollPaneSelector is a popup that displays a mini-map of the viewport contents. Users move the viewport rectangle on the mini-map to place the viewport rectangle in the scroll pane. ScrollPaneSelector was definitely an idea that we liked. Recently, I took the ScrollPaneSelector code and made a clean up pass. I separated the control logic into the UI delegate, fine-tuned the API, and renamed it. Without further ado, I'd like to present JXScrollMap. Neither the name nor the API are finalized, as the component is still in the incubator, so any feedback is welcomed. As a side note, my second choice for naming it was JXScrollView, but I thought people might confuse it with the viewport.

JXScollMap embarks on some new territory for SwingX. Part of the original design that I liked so much was the use of Robot to automove the user's mouse to the location of the current viewport when the mini-map is displayed. Since Robot is secure, this presents an additional challenge. SwingX should run without breaking sandbox containment; no signing should be necessary. So, we need to decide how JXScrollMap is going to run without Robot. I expect that we will simply do nothing in insecure environments, meaning the current highlight will be placed, but the mouse will remain unchanged. That question is still up in the air and is one reason the component still resides in the incubator. JXScrollMap now has a property is/setSynchronizedScrolling, which determines whether the viewport location updates when the mini-map rectangle changes. It is recommended to turn this off when running in a secure environment where Robot does not work, since the user's first movement may be to place the mouse into the popup.

So, without further ado, JXScrollMap (signed) to show full functionality:

The SwingLabs BOF had a good number of attendees (more than last year I believe).  Jan and I focused the update on SwingX, but did speak about JXLayer some. We also announced the release of version 1.6.2.  As promised, I have uploaded the presentation.

All in all, I think it has been a very positive convention for SwingX (so far).  I spoke about SwingLabs/SwingX at the end of the "Meet the Abstract Window Toolkit, Swing, Java 2D, and il8n" BOF and it was mentioned in some other talks I've attended. Given the announcement of JavaFX 2.0, I think SwingX will need to play a more important role in the future of Swing development.

As always, the best place to give feedback and comments on SwingLabs is on our forum.


Ostriches Blog

Posted by kschaefe Sep 20, 2010

I attended "Swing Tips and Tricks: A Best Practices Approach to Swing Applications" talk today.  While the talk covered well-known ground (or what I hope should be well-known ground) for Swing developers, what struck me most was that we (developers) are too often ostriches.  Putting our heads in the sand, we move forward tackling problems as they come, forgetting that more often than not, these problems are not new.  And forgetting more often then not someone else has already solved it.

This is not a critism of the presentation, but the two example problems for JTables are as I see it rather common: highlighting particular table cell with predicates and displaying the rollover row in a different color.  It must be said that some companies do not use FOSS and other only allow specific OSS licenses.  So, it is necessary to give developers the tools to solve the problems as they may be constrained by outside factors.  However, assuming that no outside factors exist, why not look for the existing solution.  For my part, I know that SwingX solves all of those issues out-of-the-box.  It is my goto tool for solving these common Swing problems.

So back to my ostrich comment: how do we do better?  Both specifically in SwingX to help users with problems that we've already tackled, but also (and perhaps more importantly) generally handle these issues?  Why is it that we developers are constantly reinventing the wheel instead of reusing someone else's?  How do we change that pattern?


The Legacy of JavaFX Blog

Posted by kschaefe Sep 20, 2010

My first session this moring at JavaOne was Deploying Java Applications on the Web.  It was quite good as it covered some of the newer techniques that have been added to the latest 1.6_x updates.  As with any good session, I walked away with some knowledge that I hadn't entered with, but what struck me the most was the legacy of JavaFX.  While JavaFX was mentioned (in passing once or twice by presenter Thomas Ng) and it appeared in some of the JNLP examples (as references to the JavaFX jar), it made little impact on the talk.  It was clear to me, however, that JavaFX (directly or indirectly) forced the updates that Thomas was speaking about.  The improvements in the deployment technology allowing applets to use JNLP.  The improvements to LiveConnet for better Web page integration. The improvements to caching and download times.  The improvements from click to interaction.

Whether you are pro-JavaFX or not, it seems clear that it has done something useful for the rest of the desktop development community: it has mde our lives easier when trying to push our technologies out via the Web.

With the release of SwingX 1.6.1, we now have a milestone release that contains the PromptSupport code.  So, what are prompts?  They are decorations to empty text components that usually provide a clue on how to use the component.  Search fields containing a "Search" prompt, etc.  Here, I provide a couple of examples on how to use the new SwingX code as well as a runnable application below.

PromptSupport has a rather small API of only 13 methods; most of which are not needed on a daily basis.  There are two entry points for PromptSupport: setPrompt and setBackgroudPainter.  Unless one of these is called no prompt painting will be performed.  Let's discuss each of the configurable prompts options and their defaults.

Focus Behavior
This is how the prompt reacts when the prompted component gains and looses focus.
HIDE,which hides the prompt when the component gains focus. This is the default behavior.
SHOW,which shows the prompt until the user types something.
HIGHLIGHT,which highlights the prompt text as though it were auto-selected.
Font Style
Alters the font by making it bold, Italic, or bold Italic. The default is to show the font unchanged.
Foreground Color
This is the color of the text prompt. The default is to use JTextComponent.getDisabledTextColor().
Background Color
This is the background color of the text prompt. By default this is the same color the text component normally uses.
This is the text displayed for the prompt. This or a background painter is required.
Background Painter
A painter that overlays the background, but lies beneath the prompt text. The painter allows non-text prompts, gradient backgrounds, or whatever you can imagine. This or prompt is required.

A simple example, using just the defaults:
JTextField tf = new JTextField(5);
PromptSupport.setPrompt("A Prompt", tf);

Specifying a prompt with foreground and background colors:
JTextField tf = new JTextField(5);
PromptSupport.init("Custom Prompt Colors", Color.GREEN, Color.BLACK, tf);

More examples are available in the Webstart demo.  The source is available here.  As always, please provide comments and feedback on our forums and any issues to our tracker.


SwingX 1.6.1 Released Blog

Posted by kschaefe Jul 7, 2010

I am please to announce that SwingX has released version 1.6.1.  We hope to have the release uploaded Maven central soon.

Just a quick overview of some of the issues:

  • Added prompt support.
  • Added new Highlighters and HighlighterPredicates and improved the rendering API.
  • Lots of JXDatePicker and JXMonthView improvements.
  • More Mustang sorting improvements.
  • AutoComplete improvements.

As always you can provide feedback on the forums and submit any bug or enchancements on our issue tracker.

Since I was unable to quickly google the solution for my Maven DLL problem, I thought I'd post a quick blog about it.  Here's the situation, I have tests that rely on artifacts that are DLLs (in my case these were the Java3D DLLs).  So, I needed to be able to have the DLLs in a known location so that the tests could run, but did not want to check those items into the SCM repository, nor install them locally on the Hudson server.  I made two changes to the POM file.

First I used the dependency plugin to find and output all the DLLs.



Then, I modified the surefire plugin to use the output directory as part of the java.library.path.



Hopefully, this will make it easier for the next guy trying to solve the same problem.  If anyone has a better way of doing it, please let me know.

The other day I posted some initial thoughts from my recent job search.  Today, I wanted to talk a bit about technical questions.  The questions I faced during my interviews (or before in timed tests) ranged from the obscure and puzzle-oriented to the practical and useful (albeit short).  So, I've picked two questions to review to talk about what I liked and what I didn't, hoping to find out: what makes a good technical question?  Question 1: In the language of your choice (or pseudocode), write an algorithm to efficiently reverse a string.  Let me begin by saying that I think this is a horrible question.  There are only three categories of answers: no answer (you can't solve the problem), the typical answer (n iterations), and the optimal answer (n/2 iterations).  What is the question actually attempting to test?  Strings?  Arrays?  Loops?  Computational complexity? Or my memory?  My issues with this question stem from the fact that it is completely contrived.  When is the last time anyone ever needed to implement such an algorithm (outside of CSC 101)?  It is also completely googleable; I was able to find the optimal solution in less than 60 seconds on Google.  Most importantly, how does this question differentiate the respondants?  Is the developer that gives the optimal answer really better than the the developer that gives the typical answer?  My favorite answer to this question (in Java) is: new StringBuilder(string).reverse().toString()  Question 2: Create an ER (or other) diagram to model the following [business specific problem].  This was a paragraph-long word problem, describing a small world (that was relavent to the business in question).  I absolutely love this question.  What is this question attempting to test?  Obviously, you're ability to create an ER diagram, but also whether you can model a problem accurately.  What types of assumptions do you make about the problem in your attempt to solve it?  How do you tackle it?  Entities first or build as you go?  What I like most about this question is that you cannot google the answer.  It is possible to google ER diagramming, but are not going to be able to find the actual solution.  Most importantly, it tests how you think and whether you really grok the ER modeling process.  If you've read my previous post, or perhaps just from this one, you'll notice that I place a premium on thinkers and problem-solvers.  Perhaps, my bias comes from working in small companies where you need to solve a problem today with a technology that you didn't know about yesterday.  So, what are some questions that you've encountered?  What do you think makes a good question?  What makes a bad one?

Now that I have officially given notice at work, I wanted to take a minute to share some details of my recent job hunting experience and raise some questions that have been bothering me.  A small bit of background, I have been working in software development for 13 years, during that time, I've done Web-based, desktop, and database stuff.  My recent work has been focused on thick desktop clients connecting to remote databases.  When I decided that I wanted to start looking for a new job, I read hundreds of posts to determine what I felt the trends were.  As with any good marketing campaign, I needed to taylor my strengths to what was in the marketplace.  One of the most common types of posts were JEE-related (which is good for the state of the Java platform, I guess).  They were, however, carbon copies of one another and they all came down to three things: Spring, Struts, and Hibernate.  Only having, Hibernate on my resume, I received hardly any interest from these job posters.  Why is that?  Since when did we become tool-focused?  That might matter more for newer hires, but when you're recruiting senior people shouldn't you expect them to pick up a new toolkit or API?  Isn't Spring just another API?  Isn't Struts?  Is it the recruiters or the job posters that have forgotten that at one point, none of us new Java, let alone JEE?  Since a few of my friends and colleagues have also said similar things to me recently, I can't imagine I'm alone in thinking this.  So, how do we reverse this trend?  Can we even reverse it?  I always thought that we, software engineers, were problem solvers.  Our goals is to build a system to solve a problem.  Since when has every problem had the same answer (and how long has that answer been Sprint, Struts, and Hibernate)?

Filter Blog

By date: