alexfromsun's Blog
Swing in a better world: Static fields vs AppContext
The problems that are related to the application context might be invisible from the outside of the Swing core libraries, but it has been a big deal for the Swing toolkit developers. Every time when you create a mutable static field in a Swing class you potentially introduce a security whole. It is quite surprising that an ordinary pattern of the Java language becomes a problem. To understand what is going there let's look at what is the application context is.
A Swing application is not necessarily run by its own Java Virtual Machine. Applets or webstart applicatoins placed on the same html page may share one JVM, which leads to the common static data. A static field changed by one application may unexpectedly affect another application.
If we stored the instance of the current LookAndFeel in a static field, setting it in one application would result in changing the LookAndFeel for all the applications within one JVM.
To isolate a Swing application from the other applications within the one JVM we create the Applicatoin Context class which is mostly used as a mutable static map.
Since the usual getter/setter pattern is not valid for the static data in core Swing classes, here is the code snippet from the PopupFactory class, which illustrates the usage of the application context:
public final class SwingStaticProperty<V> {
private final Map<ThreadGroup, V> valueMap = new WeakHashMap<ThreadGroup, V>();
public SwingStaticProperty() {
}
public SwingStaticProperty(V value) {
set(value);
}
public synchronized void set(V value) {
valueMap.put(Thread.currentThread().getThreadGroup(), value);
}
public synchronized V get() {
return valueMap.get(Thread.currentThread().getThreadGroup());
}
This pattern is widely used across the Swing classes, for example you can also find it in the UIManager or RepaintManager classes.
AppContext implementation
Internally the application contexts are identified by the thread group of the calling thread. All the system threads belongs to the main thread group, so if you put a value with AppContext.getAppContext().put(); on a main thread you can read it with AppContext.getAppContext().get() on the Event Dispatching Thread.
It is easy to write your own implementation of a static value which safely separates it across different "applicatoin contexts" (unless you use it on a custom threads with a specific thread group)
public final class SwingStaticProperty<V> {
private final Map<ThreadGroup, V> valueMap = new WeakHashMap<ThreadGroup, V>();
public SwingStaticProperty() {
}
public SwingStaticProperty(V value) {
set(value);
}
public synchronized void set(V value) {
valueMap.put(Thread.currentThread().getThreadGroup(), value);
}
public synchronized V get() {
return valueMap.get(Thread.currentThread().getThreadGroup());
}
Existing drawbacks
- The AppContext class belongs to the sun.awt package which means that it is not a part of the open API.
- AppContext implementation is based on the undocumented features
- Local suppression of a widely known pattern leads to multiple bugs of the same kind
Eventually we have fixed all known bugs which are related to the described problem.
Anyway it was interesting to remember some details about it.
This was an entry from the Swing in a better world series
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 2504 reads
Swing in a better world: Compound components
Swing makes it very easy to control and modify simple components like JLabel or JButton. It gets trickier when you customize a compound component like JTree or JTable. Unlike a simple component, JTable consists of multiple subcomponents like table header, renderer and editor, so actually JTable is not a single component but a container with several descendants.
Imagine that you want to customize a JLabel to change its border when you move the mouse cursor over it. You just add a mouse listener and switch the border there back and forth. Now let's make the task a bit more challenging - you want make the same trick with a JPanel which contains a JButton inside.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JPanelTest extends JFrame {
public JPanelTest() {
super("JPanel test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel();
add(panel);
panel.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
panel.setBorder(
BorderFactory.createLineBorder(Color.GREEN, 5));
}
public void mouseExited(MouseEvent e) {
panel.setBorder(null);
}
});
panel.setLayout(new GridLayout(0, 2));
panel.add(new JButton("JButton"));
setSize(300, 300);
setLocationRelativeTo(null);
}
public static void main(String... args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JPanelTest().setVisible(true);
}
});
}
}
Running this test you will see that when the mouse cursor enters the child button the parent panel receives the mouseExited event and the border is gone.

To fix it you should add the same listener to the button and to all of the possible panel's children recursively.
It may sound as a minor problem, but it gets complicated if the hierarachy is changing. In this case you should add this listener to the newly added component and remove it accordingly.
By the way, adding a mouseListener may considerably change the component's behaviour as I illustrated in my very first entry. So implementing a simple animation for a compound component is quite a challenging task in Swing.
Missing API
Compound components is a key part of any GUI toolkit so it is important to support them in a better way. In Swing I am missing a simple solution which would give me a chance to listen for the input events not for a single component but for a component and all its subcomponents. JLayer component added in JDK 7, can catch all the events from its children, but this is a topic for another entry.
This was an entry from the Swing in a better world series
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 5134 reads
Swing in a better world: Listeners
In the list of the things that needs improving in Swing, the implementation of listeners takes the first place. The problem is the fact that the order in which listeners are notified is not specified and it is not even guaranteed that your listeners will be notified after the Swing system listeners. Actually all listeners can be mixed together with any possible combination and it leads to two main problems:
- Listeners' order is messed up after updateUI() is called. See 4871932 and 6508168
- User's listeners are notified before the UI listeners See 4178930, 6294075, 4675786, 4688560, 5032759, 4816818 and 4730055
Examining the problem
Let's write some code and check if a JButton is in the pressed state when MouseListener.mousePressed() is notified:
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ListenersOrder extends JFrame {
public ListenersOrder() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
final JButton button = new JButton("JButton");
button.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.out.println("button.getModel().isPressed() = "
+ button.getModel().isPressed());
}
});
add(button);
pack();
}
public static void main(String... args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ListenersOrder().setVisible(true);
}
});
}
}
When you press the button you can see that it is in the pressed state, as we may expect.
button.getModel().isPressed() = true
Let's add some more code and change the system Look and Feel after the button is created:
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ListenersOrder extends JFrame {
public ListenersOrder() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
final JButton button = new JButton("JButton");
button.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.out.println("button.getModel().isPressed() = "
+ button.getModel().isPressed());
}
});
add(button);
pack();
changeLaF();
}
private void changeLaF() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
// we don't forget to update all the components
SwingUtilities.updateComponentTreeUI(this);
}
public static void main(String... args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ListenersOrder().setVisible(true);
}
});
}
}
This simple update changes the mouse listener's order and now, surprisingly, when you press the button you'll see:
button.getModel().isPressed() = false
How to explain it?
Let's examine the mouse listeners' added to the button, corresponding to every relevant line:
| Line of code | MouseListener added to the button |
| JButton button = new JButton("JButton"); | Listener from MetalLaF |
| button.addMouseListener(new MouseAdapter() {}); | user's listener |
| changeLaF(); | |
| changeLaF(); | Listener from NimbusLaF |
It means that the actual state of the button seeing from a user's mouseListener is unspecified and you shouldn't rely on any particular order.
Modal dialogs
Showing a modal dialog from a listener is the best way to observe your component in a transition state. If you run the following test and click an unselected list's item the modal dialog will come up and you'll be able to see the two selected items for a list with the SINGLE_SELECTION mode.
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.FlowLayout;
public class ModalityTest extends JFrame {
public ModalityTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
String[] data = {"One", "Two", "Three", "Four"};
JList list = new JList(data);
list.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
// Showing a modal dialog blocks the listener's notification
JOptionPane.showConfirmDialog(null,
"Do you see two selected lines ?");
}
});
add(list);
setSize(200, 300);
}
public static void main(String... args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ModalityTest().setVisible(true);
}
});
}
}

list.addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Showing a modal dialog with invokeLater
// doesn't leave the GUI in a transition state
JOptionPane.showConfirmDialog(null,
"Do you see two selected lines ?");
}
});
}
});
How should it have been implemented?
We seriously thought about improving the listeners notification several years ago but after heated disputes we didn't come up to one proposal. I offered to mark the Swing UI listeners with the existing UIResource interface and gurantee their notification before the user's listeners. The other propsal was to add a conception of listeners "weight" which will control the order in which a listener will be notified. So you would use the new add*Listener() methods with the second parameter - button.addMouseListener(listener, weight);
As a matter of fact the multiple listeners approach brings more problems than solutions. It would have been better to make the users override methods like processMouseEvent and automatically notify the same kind of method in the ComponentUI.
This was an entry from the Swing in a better world series
Thanks alexp
- Printer-friendly version
- alexfromsun's blog
- 2093 reads
Swing in a better world: Generics and arrays
Generics doesn't work well with arrays. Everybody knows that you can't create a generified array,
but not many people really know what it was done this way.
A nice article from Brian Goetz helped me to understand the problem
when I studied the new features of JDK 5.
String stringArray[] = new String[1];
// compiles ok
Object objectArray[] = stringArray;
// throws ArrayStoreException
objectArray[0] = new Object();
ArrayList<String> stringList = new ArrayList<String>();
// doesn't compile - incompatible types
ArrayList<Object> objectList = stringList;
If a generfied program is compiled without a warning you can safely add an Object to your ArrayList of Objects.However when there is an array of Objects passed to your method as a parameter, there is no way to understand an object of what type you can put there
(I am not sure if you can find it out via reflection).
So it is known that arrays and generics don't do well together. It means that it is not recommended to use two features of JDK 5 together,
I am talking about generics and varargs. This reminds me one old bug found by Rémi Forax,
which was fixed by changing
protected void process(V... chunks) {
}
to
protected void process(List<V> chunks) {
}
in the SwingWorker class, which did look awkward at the first glance.
An alternative implementation
I would be happy if I could create and safely use generified arrays in java, at the same time I can hardly remember if I ever saw a snippet of code that really benefited from the fact that arrays are covariant.
This feature of java arrays doesn't look attractive to me and I don't mind "deprecating" it, I don't feel it is correct that I can't create a generifed array when I never cast an array of one particular type to an array of its supertype.
Certainly all java code must be backward compatible with any new version of JDK,
I am thinking about a new warning produced by the compiler when covariant arrays are in use.
If there is no such a warning in your code it should be pretty acceptable to create a generified array, otherwise you are warned just like when you use a raw type of a generifed class. Something to discuss for the next JDKs?
This was an entry from the Swing in a better world series
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 1401 reads
Comments
<p> to create a generic array you must ...
by hute37 - 2011-05-06 08:27
to create a generic array you must "reify" yourself the type with a Class<T> parameter to a genetic utility static method, that force a cast of the result of
<a href="http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Array.html#newInstance(java.lang.Class, int)">java.lang.reflect.Array.newInstance()</a>
something like
public class ArrayUtils {
@SuppressWarnings("unchecked")
public static <t> T[] makeArray(Class<t> clazz, int length) { return (T[]) java.lang.reflect.Array.newInstance(clazz, length); } @SuppressWarnings("unchecked") public static <t> T[] makeArray(Class<t> clazz, int... lengths) { return (T[]) java.lang.reflect.Array.newInstance(clazz, lengths); } } </t></t></t></t>usage:
@Test
public void testMakeSimple() {
String[] exp = new String[] { "one", "two", "three" };
String[] act = ArrayUtils.makeArray(String.class, exp.length);
// explicit type "String.class": exp.getClass().getComponentType() not works here ...
assertEquals(String.class, act.getClass().getComponentType());
for (int i = 0; i < act.length; i++) {
act[i] = exp[i];
}
for (int i = 0; i < act.length; i++) {
assertSame(exp[i], act[i]);
}
}
<p>Hi hut37,<br /> as Alex said, generics and reflection ...
by forax - 2011-05-09 12:23
Hi hut37,
as Alex said, generics and reflection doesn't play well together.
try:
Object[] array = makeArray(int.class, 3);
Rémi
Hello <br/><br/> The problem is not how to find a trick ...
by alexfromsun - 2011-05-07 03:38
Hello
The problem is not how to find a trick and create a generified array, but the fact that it can't be used after that in a type-safe manner
Thanks
alexp
<p>Hi Alex,</p> <p>> I can hardly remember if I ever saw ...
by forax - 2011-05-06 02:48
Hi Alex,
> I can hardly remember if I ever saw a snippet of code that really benefited from the fact that arrays are covariant
I don't agree. It's easy to find such snippet.Arrays.asList() is often used with an array of something which is not an Object. Also it's not that hard to find an example of array covariance in Swing.I remember trying to generify java.swing.tree and have some trouble with bad interactions between TreePath and DefaultTreeModel, so by example in DefaultTreeModel.nodeChanged, fireTreeNodeChanged is called with an array of TreeNode but takes an array of Object as parameter.
Anyway, you're fundamentally right that the bad interactions between generics and array is a part of the Java technical debt. I really hope that Java 9 will reified generics to reduce that debt to something moderate. Currently, this debt makes all attempts to move forward less easier than it should be. The actual discussions about lambda implementations is all about that.
Note that one way to reduce the debt is also to cut spending, what about deprecating wildcards ?
Rémi
<pr/> > It's easy to find such snippet.Arrays.asList() is ...
by alexfromsun - 2011-05-06 08:10
I was talking about the situation when an array of a particular type is casted to an array of its supertype
> and DefaultTreeModel, so by example in DefaultTreeModel.nodeChanged, fireTreeNodeChanged is called with an array of TreeNode but takes an array of Object as parameter.
Yep, it is possible to find this kind of code in Swing, but it looks more like just an accident
that example with array of Objects instead of TreeNodes is just an API misdesign
alexp
Swing in a better world: Checked exceptions
Checked exceptions are painful. I could write a long article about it,
but there are more than enough good blogs describing this problem.
My favorite article is written by Rod Waldhoff.
From my point of view the existence of the InvocationTargetException clearly shows the problem.
Imagine you call a method which throws an exception, you properly catches it
and then you decide to rewrite the code and call the same method via refection.
After that you have to catch the same exception in quite a different manner:
public class Test {
public static void main(String[] args) {
PrinterJob job = PrinterJob.getPrinterJob();
// Call it in the usual way
try {
// this throws checked PrinterException
job.print();
} catch (PrinterException e) {
// handle the printer exception
}
// Call the same method via reflection
try {
// this throws InvocationTargetException instead
getPrintMethod().invoke(job);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
if(e.getCause() instanceof PrinterException) {
// handle the printer exception;
// a little bit more complicated than it used to be
}
}
}
static Method getPrintMethod() {
try {
return Class.forName("PrinterJob").getDeclaredMethod("print");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
I would love it if Java doesn't require me to catch the InvocationTargetException
and let me work with the PrinterException the same way.
Let me give you some examples that illustrate what kind of mess it brings to the Swing code base.
Fortunately there are not many checked exceptions used in Swing code,
but when you implement printing you can't avoid PrinterException
and PrinterAbortException.
Since printing must be done in the background to not block the GUI,
we have to properly re-throw the exceptions back to the Event Dispatching Thread thread.
So in the implementation of the JTable.print() method you can find the following construction:
// this runnable will be used to do the printing
// (and save any throwables) on another thread
Runnable runnable = new Runnable() {
public void run() {
try {
// do the printing
job.print(copyAttr);
} catch (Throwable t) {
// save any Throwable to be rethrown
synchronized(lock) {
printError = t;
}
} finally {
// we're finished - hide the dialog
printingStatus.dispose();
}
}
};
and then we have to understand what kind of exception was thrown and how we can re-throw it back:
// check the type of error and handle it
if (pe != null) {
// a subclass of PrinterException meaning the job was aborted,
// in this case, by the user
if (pe instanceof PrinterAbortException) {
return false;
} else if (pe instanceof PrinterException) {
throw (PrinterException)pe;
} else if (pe instanceof RuntimeException) {
throw (RuntimeException)pe;
} else if (pe instanceof Error) {
throw (Error)pe;
}
// can not happen
throw new AssertionError(pe);
}
This boilerplate code can't be avoided, you can find the same pattern in the implementation of JTable.print().
If the methods that are called on the background thread threw another checked exceptions,
we would have to add another instanceof checks there.
More checked exceptions - more lines of code.
If there were no checked exceptions in java, that kind of code would be unnecessary,
we could freely re-throw any exception no matter what their type is.
I would definitely remove the checked exceptions from Java.
This was an entry from the Swing in a better world series
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 1026 reads
Comments
It is completely clear that
by tbee - 2011-03-23 22:26
It is completely clear that calling a method via reflection will add additional exceptions involving reflection. So if "o.m()" throws an exception X, then "invoke(o, m)" would have addional exceptions to catch, BUT the if call is succesful from the reflection perspective, I see no reason why it cannot behave like the original call and indeed throw exception X directly instead of wrapped. But I agree it's not the drama that this blog suggests, just catch the reflection associated exceptions and rethrow the causes.
But this IMHO is not the actual problem of checked exceptions, the real problem is that once you start doing binding between Swing and a business model, and that business model has (as a good boy) implemented checked exceptions, you're screwed. The binding layer is then forced to implement these specific checked exceptions and it hasn't, because it's a generic library.
Checked exceptions should go away. Forbidden code. Put in a small dark room and never be seen again. They severly limit the ability of exceptions to bubble up through the callstack and be handled at the appropriate place. Luckily there are some hacks allowing to throw a checked exception unchecked and in order to patch this design mistake of checked exceptions (one of) these hacks should become a formal approach. (Enough checked exception bashing? ;-)
The same sort of
by imichtch - 2011-03-24 02:31
The same sort of argumentation again: "It does not work for my GENERIC binding framework. it MUST be REMOVED!". But it does work in my GENERIC binding. So what? I think nobody is forced to use checked exceptions. But if one uses it certainly one has a reason (strategy). It may happen that the strategy does not fit you needs then you have a reason for complaints. But it is not caused by the technology (checked exceptions), it is a design issue. The worse case is when checked exceptions are used without any strategy in mind. Again it is not the technology to blame. ;-) It looks to be a very common issue for GENERIC (and VERY GENERIC) frameworks: they do not respect other systems. So what would your generic binding do in case runtime exceptions are thrown from the business layer? Would it passively pass it over to UI? How would UI recognize what exceptions are business related and what are low level (system) errors? Probably sequences of "instanceof" checks will appear here and there. But again how do I know what is business and needs to be shown to the end user? And what is system and needs to be reported in a standard way? One could use checked exceptions for business and the binding could transform those to GENERIC binding exceptions (checked) which is then recognized by UI as business problems (like BindingValidationException). All other issues can be reported as runtime exceptions and thus treated in a standard way by all layers. Yes, you need to ADAPT your generic binding to a particular business layer. "Good" generic binding frameworks allow for an easy adaption. Off cause it is all possible without checked exceptions but perhaps it is not that explicit then.
Let me begin with saying that
by tbee - 2011-03-28 00:01
Let me begin with saying that I do not use 'my' binding framework, but JGoodies binding. Which is, AFAIK, the first and about as a reference implementation for binding in Java as it gets. But it really does not matter what binding framework I use, any middleware layer suffers from the same problem; they are forced to handle the checked exceptions, which makes them not generic anymore. I'm not quite clear where are going with your reasoning about tailored middleware, but yes, middleware layers are suppose to only handle a piece of middleware logic, oblivious to the content it is handling, and just pass everything through. Just like HTTP is not suppose to do anything with the HTML, it just has to deliver it. Would be a funny world if HTTP would be custom tailored for each website (which conceptually is what you are suggesting).
The other side, the UI, is specifically written for the BM, and yes, it would know what to do with the BM's exceptions. The binding layer cannot transform the exceptions, because it needs to catch them first, which means be custom modified for the BM (or use a lot of reflection). But please show me a binding framework that handles checked exceptions well and I'll switch over.
Swing in a better world:
by larsstitz - 2011-03-22 10:46
First of all, reflection calls are not transparently replacing normal method calls. And since Method.invoke(...) has to inform the caller about any exceptions that happened during the actual method call, it has to wrap these to let you differentiate them later from exceptions that happen during the method dispatching in Method.invoke. This would also be the case if we were dealing with unchecked exceptions only. Otherwise, for example, you'd not be able to correctly tell an IllegalArgumentException thrown by the method invoked apart from one that originated somewhere in Method.invoke(...), and thus you'd be unable to correctly handle your IllegalArgumentExceptions.
Secondly, the problematic constructs from JTable.print() would also persist if we were dealing with unchecked exceptions only. The reason is that it is not possible to communicate exceptions between threads, e.g. from a child thread to its parent. So your statement about having to "re-throw" the exception is quite incorrect. It has to be stored in a variable to pass it back to the other thread. And this in turn is the only reason for the awkward instanceof construct at the end - which would otherwise be replaced by multiple catch clauses, and which actually does rethrow everything but the PrinterAbortException and thus could have been written in a much shorter fashion.
Also, your comment about "more checked exceptions - more lines of code" is quite misleading. This would be exactly the same issue for more unchecked exceptions you'd choose to handle. And moreover, it is possible to form class hierarchies from exception classes, to catch and handle alike culprits the same way.
I admit that there are some powerful arguments against checked exceptions, but the examples you provided do not convince me at all.
Very good remark! it is odd
by imichtch - 2011-03-23 13:13
Very good remark! it is odd to hear that sort of complaints from alexp. It sounds like "it does not work for me, so it must be removed". I like checked exceptions and they do help in my projects. I think the design fof the mentioned print() method is not optimal. But the cause is not the usage of checked exeptions.
Swing in a better world:
by cayhorstmann - 2011-03-23 06:53
Actually, I think they are pretty good examples.
Take the case of calling a method through reflection. Why does Method.invoke throw two unrelated checked exception? How hard would it have been to have one common superclass so that the 99% of people who have no interest in differentiating between the two could just deal with one?
And why does one have to go through this crazy dance of catching Error and RuntimeException separately in the other code example? Whose idea was it to put checked exceptions in between the two? Why not have a subclass CheckedException?
I can live with checked exceptions, as long as they are sensibly designed. I never had a lot of grief with IOException, for example. But I dread things like SAXException, which never occur in practice (or at least shouldn't if that subsystem wasn't such a house of cards) and I absolutely loathe cluttering up my code with InterruptedException.
cayhorstmann wrote: I can
by larsstitz - 2011-03-23 14:23
I can live with checked exceptions, as long as they are sensibly designed. I never had a lot of grief with IOException, for example. But I dread things like SAXException, which never occur in practice (or at least shouldn't if that subsystem wasn't such a house of cards) and I absolutely loathe cluttering up my code with InterruptedException.
Actually, I completely agree with you. It's not checked exceptions per se that are the problem, it is bad design of exception class hierarchies and not knowing when to use checked and when to use unchecked exceptions. Also, often it is missing documentation: if the API you are using and that is declaring to throw a checked exception doesn't give you a clue why that particular exception is raised, in what situations it will appear and what it does signify, your code will probably be unable to handle it, leaving you no other chance than to rethrow.
So, I'd rather put the blame on lazy API designers than on the language feature. And in my eyes, checked exceptions share the advantage of static typing, as they draw your attention to possible errors early in the development cycle and disallow radical changes that would break caller functionality.
Swing in a better world: java interfaces
We have all read the "Effective Java" book and know that we should prefer interfaces over abstract classes.
This is a known and respected pattern which should be used wherever possible.
However the years in the JDK team tauhgt me not to blindly trust
to good practices from the world of application programming.
A distinctive feature of the JDK is backward compatibility.
All programms written in public JDK API must compile and run
with every next JDK versions. It makes it really different.
Comptibility is good for Java programmers but not so good for JDK developers,
java interfaces is a part of a problem.
If you want to add an interface to the JDK API you have to be sure
that you know in advance all the methods that are to be included there.
You cannot make any mistakes because it will be impossible to add a new method
to an interface without breaking the user's code.
In every JDK release we add new methods to some of the existing classes.
Let's have a look what happens when it turned out that we need to expand an interface.
The LayoutManager interface is widely used across Swing/AWT toolkit.
This interface contains 5 methods and that was enough at the beginning.
Later on it was discovered that a complex layout needs more methods there,
but it was decided to intrdoduce a new interface,
because nobody wants to implement too many empty methods for a simple layout.
So here comes the LayoutManager2 interface
and now the layout related methods from java.awt.Container look like this:
public float getAlignmentX() {
float xAlign;
if (layoutMgr instanceof LayoutManager2) {
synchronized (getTreeLock()) {
LayoutManager2 lm = (LayoutManager2) layoutMgr;
xAlign = lm.getLayoutAlignmentX(this);
}
} else {
xAlign = super.getAlignmentX();
}
return xAlign;
}
However the layout setter and getter still work with the old LayoutManger type:
public void setLayout(LayoutManager mgr) {
layoutMgr = mgr;
invalidateIfValid();
}
so you have to read the spec to know that the new LayoutManager2 exists.
If it happens that more methods should be added in a next release,
the LayoutManager3 will appear, adding more mess to the Swing API.
So now you can see why I don't like java interfaces as much as I should do.
If I created Java...
Discussing the features of a programming language is very popular among programmers,
everybody knows how to make it in a right way, here is my try:
The interfaces in java are too restrictive and I wonder if they could be implemented more friendly for programmers.
I am dreaming about Java that allows implementing an interface without being made to implement every single method of it.
Look at the KeyAdapter class, we have it only because it is too inconvenient to implement every 3 methods
when you need only one of them. I am sure that in a perfect java there is no need in classes
like MouseAdapter, HierarchyBoundsAdapter and so on.
You don't want to type empty methods for a KeyListener?
You should use KeyAdapter.
don't want to type empty methods for a MouseListener?
Then you should use MouseAdapter.
But what if I want my class to implement KeyListener *and* MouseListener and I don't need most of the methods from them?
The only solution is to manually generate the empty stubs (thanks to my IDE which can do it automatically)
In the java of my dreams the compiler can generate empty stubs for a method from an interface your class is implementing,
so you can override only those methods that you really need.
The "empty" methods from a super interface have empty bodies and return null for reference types and zero for numbers.
Sometime it is desirable to remind a developer that a method just needs to be implemented
and abstract methods in Java classes ensure it. Currently all methods in an interface are considered abstract
no matter if they have the "abstract" keyword in their signature or not.
I think it should be more meaningful support of this keyword for java interfaces,
only methods with the "abstract" keyword must be implemented
when compiler takes care of all the rest.
With this proposal the LayoutManager interface would be implemented like this:
interface LayoutManager {
// methods that are currently in java.awt.LayoutManager
// the user must implement them (note the abstract keyword)
abstract void addLayoutComponent(String name, Component comp);
abstract void removeLayoutComponent(Component comp);
abstract Dimension preferredLayoutSize(Container parent);
abstract Dimension minimumLayoutSize(Container parent);
abstract void layoutContainer(Container parent);
// optional methods from java.awt.LayoutManager2
// they don't have to be implemented
void addLayoutComponent(Component comp, Object constraints);
Dimension maximumLayoutSize(Container target);
float getLayoutAlignmentX(Container target);
float getLayoutAlignmentY(Container target);
void invalidateLayout(Container target);
}
This was an entry from the Swing in a better world series
Thanks and see you soon
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 1391 reads
Comments
Swing in a better world: java
by rich.midwinter - 2011-03-15 14:20
You'd need to recompile for a new interface version with this proposal.
And I'd rather see the generated methods throw an UnsupportedOperationException instead of just returning null or similar.
There's merit to your suggestion though, it's definitely a problem and I'm sure it's one that is resolvable (I haven't looked at defender methods yet but I shall do so now)!
Swing in a better world: java
by alexfromsun - 2011-03-16 03:22
[quote=rich.midwinter]
You'd need to recompile for a new interface version with this proposal.
[/quote]
Actually if this feature had been implemented from the beginning, there would be no need to recompile,
just like you don't have to recompile your code when a new method is added to a JDK class.
Swing in a better world: java
by philho - 2011-03-12 03:30
Scala solved that (I think) in a rather elegant way (also solving multiple inheritence) with traits. Kind of interface allowing implementation of the methods. And fields...
Swing in a better world: java
by sciss - 2011-03-11 16:28
hey, good to know the swing world is still moving. i'm still hoping someone in the swing dev team finishes the nimbus project. jasper pott's promise that it is completely configured by uidefaults is not holding completely -- trying to get a decent dark looks seemed impossible in my attempt. the guys at jyloo did such a great job with synthetica blackeye theme. i wish someone could make a nimbus settings that comes close to this, and i think it would be possible with some tweeking, after all the blackeye theme doesn't look that much different from nimbus other than the color scheme. a dark lnf would be phantastic for professional apps in the creative sector.
regarding your actual post :) i was thinking that the java of your dreams might be reality already, and is called scala. its traits pretty much allow you to do exactly what you are describing here.
Swing in a better world: java
by alexfromsun - 2011-03-11 08:48
Jonathan Giles just let me know that there is a similar proposal called Defender Methods
it is nice to know that I am not alone :-)
Swing in a better world: java
by forax - 2011-03-12 05:46
> Jonathan Giles just let me know that there is a similar proposal called Defender Methods
> it is nice to know that I am not alone :-)
Defender methods are planned to be introduced in jd8 under project lambda [1] (JSR 335),
the original proposal was done by Neal Gafter [2] and Peter Ahé [3].
Rémi
[1] http://openjdk.java.net/projects/lambda/
[2] http://gafter.blogspot.com/2007/11/closures-prototype-update-and-extensi...
[3] http://digital-sushi.org/entry/declaration-site-extension-methods/
Swing in a better world
I truly love the Swing GUI toolkit, I enjoy its flexibility, opennes and great abilities.
I know that some people say that Swing is too difficult to learn,
and I partly accept it because it took me several years working in the Swing team
to get the whole picture of the AWT, Java 2D and the Swing itself.
The Swing history counts more then 10 years and it is definitely not about end.
The new features have already been added to JDK 7
and the new blogs are coming to describe them.
Swing is the best graphical toolkit I have ever worked with,
anyway it could have been implemented even better.
Even the best piece of software in the world would have bugs
and design glitches. At this point I want to stop for a moment,
to look back and remember the cases when
I wanted Swing to be designed in a different way.
This information may be useful for all developers
who are working on any other graphical toolkit.
Swing is written in Java,
so its API is tightly bound with Java language peculiarities
and event high level decisions of the Swing architecture are affected by the language sometimes.
So I'll cover the java related issues first
and then touch some exclusively Swing features.
Java related issues
Swing design
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 1971 reads
Comments
<p><!--[if gte mso ...
by avazqueznj - 2011-06-16 13:52
Hello All
It is very nice to see that Mr. Alex is still with us.
I would like to use this forum to express some frustration, excuse my offense.
I believe that whether Swing could be better or not is simply not the point. Just look at netbeans and all the other developer tools. What other tool can make the tools to do graphic interfaces? JavaFX is 100 light-years away of being able to do something like that. But that's not the point.
I keep on hearing people like Amy talking about "User interfaces in collision with graphics" in 2011?? Stop it!, we have been arguing about this since the past century. There is a place for fancy artistic interfaces, like commercial web pages and juvenile cell phones. That is great, but it is a very different thing from day to day business applications and developer tools.
I don't know about you guys, but I'm getting really tired trying to explain why markup language and ornamental oriented UIs are one thing and business or developer tools another, and why we need different and _separate_ tools. The one has to be easy and pretty, the other flexible and functional and, hence, more complex.
JavaFX is great, but for me, and lot of people I believe, seeing fancy bubbles in a screen demo is nonsense. There's not even a grid component or a printing framework! It feels like the first try of the AWT 10 years ago.
I'm confident swing is here to stay and evolve. If it is replaced, it will not be by JavaFX, definitely.
Anyway, thanks for your patience with this vulgar rant. By the way, these are some of things I've been doing for the past years with Swing, which I'm sure you will have fun looking at: http://k-framework.sourceforge.net/ … plus some help would be really appreciated.
Great to see you're back with
by Ivan_Prt - 2011-03-31 17:19
Great to see you're back with your amazing blog entries, Alex! Thanks for the help and clarification on many diffucult questions for my second edition Swing book, I mentioned your name there, it's out and available since January, I can send you one if you'd like.. Keep us informed on all latest and greatest in Swing, and not only Swing, world!
Wow, Ivan! It is nice to see
by alexfromsun - 2011-04-01 03:51
Wow, Ivan!
It is nice to see you here my friend,
I would certainly love to read the book.
Swing team doesn't mind to have the signed one from you
:-)
Thanks
Swing in a better world
by nipsu - 2011-03-18 07:07
Hello! Another long time java developer here.
Swing is a powerful toolkit and the customization potential is simply awesome. I'm still learning new stuff (mostly related to java2D) and new ways to extend existing components.
Most of the problems with swing (IMO) are/were related to poor tutorials and just plain wrong instructions from the early days. Some of those idioms live even today, and it can sometimes be frustrating to find the gems amidst the rubble.
Swing in a better world
by rjahn - 2011-03-16 05:17
I use Swing since 2000 and don't think that it is difficult to learn. Every new framework has its own APIs and "extras". If a Framework wrapps the technology behind you have to learn the framework and not the technology behind. If you work with the technology you have to learn it and maybe create a framework around that solves your problems - or better check if there are existing frameworks.
You don't have to be a top-class developer to understand Swing, but you need time to learn. And there are enough tutorials, examples, howtos available! You have the same problems with other APIs/frameworks like Netbeans RCP, SWT, QT, WPF, ...
In my opinion, the problem is that developers get tasks and need solutions for that tasks. Many developers don't know how to develop a framework and so they start developing a solution... Maybe the solution is not reusable... And it depends on the complexity how easy it is, to develop the solution. (Not really new information), and of course how many frameworks you need and need to know.
Back to JSR-296: It was a good idea but I think it solved only the first problem: How to start developing an application and how to start using actions.....
After the first hurdle, a developer has the next problem: How to solve my task. The application frame works and screens are configured, but how to sovle common problems like: Session Management, User authentication, Database access, ....
I know that a lot of frameworks exists in the Java world with which you can solve every problem. But the effort to dive into multiple frameworks is high and you need specialists.... I think that JSR-296 is a good base but for me, an Application Framework solves common tasks and reduces boilerplate code. And there are not many frameworks available which solves application development problems!
Swing in a better world
by andrew.osipenko - 2011-03-11 05:42
I liked development with Swing. It's archytecture is really great.
But never liked it's default look and feel. Can't understand why it does not look like Adobe Flash.
Swing in a better world
by alexfromsun - 2011-03-11 04:05
The Metal Look and Feel sucks indeed, the new Nimbus LaF is much better
Swing in a better world
by gquintana - 2011-03-10 19:33
Despite Swing being a great library, what is its future? Swing App Framework (JSR 296) was abandonned and JavaFX seems to be the next Desktop Java library.
Swing in a better world
by tomwheeler - 2011-03-11 11:42
Despite Swing being a great library, what is its future?
Alex, I think your reply only answered the second part of gquintana's question. I think the first part (which I've quoted here) is something a lot of people wonder. I'll be interested to read about new Swing features in Java 7, but I'll be far more interested to know what's planned for Swing in the next five years since it was largely ignored during the last five years.
Swing in a better world
by alexfromsun - 2011-03-12 09:42
The Swing and JavaFX relations are described by Amy.
About the future of Swing I can say two things
first - that Swing is a part of Java API so it can't be taken out from JDK
second - JDK 7 is coming and we have some new features there
Swing in a better world
by osbald - 2011-03-13 06:29
> JDK 7 is coming and we have some new features there
Oh please and this is why you've written this oddly formatted article that talks about Swing in the past tense? it reads more like a eulogy. Amy's comments make it clear Oracle see Swing as a legacy API only and unfit for modern UIs.
What new Swing features are in JDK7? Nimbus, J(X)Layer and the other Java6u10 rendering additions that had been missing from Java 7 till recently. As the roadmap for JDK8 is being mapped out why dont you tell us whats in store for Swing in JDK8? Cant you promise its not a Java2D/Swing/AWT jigsaw module of their very own so these 'legacy' APIs can be made optional?
Even with JDK7 you've broken your precious prime directive that all code in the previous version runs in the next without changes because they've relocated the Nimbus packages. There's several ways APIs can cope with change. The no changes law didnt always apply to Swing, Swing 1.0 code won't compile under Java 6, in the same kind of ways JavaFX 1.0, 1.5, 2.0 etc.. aren't binary compatible. That's not even taking into consideration all the Swing regressions over the years where developers have to check the Java version to compensate for changes to the default behaviour of the previous version. No changes seems as much an excuse for the comparatively scant resources thrown at client-side Java over the years as much as anything else. Now you expect developers to trust in the JavaFX APIs and they they won't be just as shoddly treated, again.. despite it running far short of its orginal promise of running on all the screens of your life. The truth is client side Java has never been so threadbare as it is right now.
Swing in a better world
by alexfromsun - 2011-03-10 23:29
Swing App Framework is currently on hold, but it I don't see it as a big problem.
The goal of JSR 296 is to help Swing newcomers when every existing application
uses its own framework which is different from anything else.
We should have introduced a framework in the early days of Swing,
currently this is not a priority.
Swing in a better world
by wwwjames - 2011-03-11 11:50
Swing App Framework is currently on hold, but it I don't see it as a big problem.
The goal of JSR 296 is to help Swing newcomers when every existing application
uses its own framework which is different from anything else.
We should have introduced a framework in the early days of Swing,
currently this is not a priority.
This however is unfortunate, because I believe that a good framework could overcome many of the difficulties developers have with learning to use Swing. I know that many people assert that GUI builders are the solution to this problem, but historically they have never worked well.
The alternative Swing frameworks
and don't forget about the mature Netbeans Platform
I am happy to promote those projects. If there is anything I can help with,please don't hesitate to contact with me, I'd be glad to get in touch with the development teams. Let me know if there are more good projects to be added in this list. Thanks and keep up the good work!
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 8755 reads
Comments
There's only one Swing framework...
by vieiro - 2009-11-16 10:30
... worth the effort of learning it, and it's called The NetBeans Platform. I've been there, seen that (during several years) and (with all respect) all I can say is that learning NetBeans RCP is the Best Thing I've done for building spiffy Swing applications. Cheers, AntonioNetbeans is too heavyweight
by janaudy - 2009-11-16 12:55
Netbeans is too heavyweight for some apps. My main issue is what do want to incorporate in SAF? Docking (Jide, InfoNode, Netbeans, ...), saving properties, etc. I'd run a poll first on what people would like to see in a simple SAF. Regards"Netbeans is too heavyweight for some apps."
by geertjan - 2009-11-17 01:22
"Netbeans is too heavyweight for some apps." That's a myth. It will continue to exist for as long as people continue saying it. The fact of the matter is that the NetBeans Platform is as heavyweight as you want it to be. That's because it is modular. You get to choose what you want/need. So, if it's "too heavyweight", you haven't grasped the central concept of modularity.It's not a myth...
by vieiro - 2009-11-17 03:02
... but simply untrue. A NetBeans RCP application can be as small as 5Mb, featuring the major components of the Platform (yes, including all the Windowing System, Options Panel, etc). And, well, I don't think it's that difficult at all. Maybe I should blog a little bit on how to use the NB RCP for simple Swing applications, right? Cheers, AntonioNetbeans Platform
by alexfromsun - 2009-11-17 04:57
Hello Antonio
I added a link to the Netbeans Platform, thanks for the pointer!It will be really helpful if you write a blog about using it for a simple Swing application Thanks
alexp
I will
by vieiro - 2009-11-18 01:06
Ok. I will then start a series of blog entries, probably during december. I'll let you all know when those are ready. Cheers, Antonio.Netbeans Platform Tutorial
by psychostud - 2009-11-17 07:22
I find most of the tutorials..use the netbeans wizard which further hinders the understanding of the platform. Please try and make the tutorials IDE agnostic..so that we can use it on IDEA & Eclipse too.Regards,
Pavan
A good way to have a project
by fabriziogiudici - 2009-11-18 01:45
A good way to have a project IDE-independent is to work with Maven. NetBeans 6.7/6.8 has got very good support for Maven, and IDEA seems to be the same (in contrast, I've got a lot of troubles in trying to open my Maven projects with Eclipse, but with a bit of work is for sure doable). I've posted the first of a series of tutorials that are focused about some projects of mine, but they use the Platform and at least half of that might be useful for people generically interested in the Platform. These tutorials are both textual and screencast - the first is linked from here: http://netbeans.dzone.com/videos/screencast-maven-and-netbeans.
Yeah, that would be really
by josefg - 2009-11-17 08:20
Yeah, that would be really nice.Rather than being "too
by ringerc - 2009-11-17 02:23
Rather than being "too heavyweight", the issue I have with the NBP is that I'm not smart enough to completely understand it. This may put me on the dimmer side, but perhaps it just means I like to _really_ understand the tools I work with if I'm going to build my entire app around them. I can't just swap the NBP out for another framework if issues arise - say, Oracle-related issues. If it has issues running on the latest borked Apple JVM, there's not much I can do about it unless I'm able to dedicate the time required to become a real NBP expert. This makes me nervous, especially as much of the code I write must be supported well after I've stopped looking after it and needs to run untouched for many years. With, say, Hibernate, while I don't fully understand the core of its workings I also know I can swap it out for something else via JPA 2.0, which is simple enough that I *can* get a good understanding of it. Joe Bloggs the 3rd year comp sci graduate has a chance of doing this when hired to work on the codebase to fix some painful bug five years after I've turned it over. The SAF is attractive to me because it's small and focused enough to be easily comprehensible. I see that as a big plus in a core app framework. It gets what I need done, but it's not the kitchen sink.SAF and JDK7
Hello Swing community
After much discussion it's become clear that the Swing Application Framework API as it is today hasn't reached
consensus and we feel still needs further design work done.
Since the SAF API was committed to milestone 5 of JDK7 and that time is already here,
this date is now impossible, and we need to decommit SAF from any specific JDK 7 milestone.
Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 9870 reads
Comments
SAF is dropped for JDK 7
by tomtom_live - 2009-09-17 07:00
Hi guys, I've just looked at http://openjdk.java.net/projects/jdk7/features/ and was shocked that SAF was dropped for JDK 7.So my question is: What the hell??
The only hope for better expirience in programming with Swing is dropped. Does this mean that there will be no SAF in JDK 7? What is the reason for that decision?
What discussions?
by lazyboy - 2009-08-27 03:11
What discussions are you referring to? I cannot see any discussion about this topic on the developer's or user's list of the framework. And in general, as already other people stated in comments on your blog, nobody did see any mail from you there for months. My questions about unclear versioning and wrong files in the file store of the project remain unanswered since weeks now. Shouldn't an openly developed, open source project care about it's user most, and discuss things with them? Apart from that: I don't think it's necessary to include the framework in the JDK, the framework needs further development, and a clear path for it's future so people can rely on it. But that does not need to be bound to jdk development. Henningby aleixmr - 2009-08-21 04:34
Uffffff !! I don't know what to say, simply I'm SAD, really sad of how things run in those big companies. For me, today RIA should be programmed in ONE general purpose compiled language, say Java, C#,C++ all what you want. I don't like those AJAX messup HTML,javascript, and another language to access the database layer. For me AJAX means learning a lot of things to to a simple java Applet, with the risk of those dinamic language typos !!!! So please give AJAX a kick in the ass !!! JavaFX: I tested, did some memo game to learn adn I liked how effects are easy done. javafx should be run in its own jvm (I mean in the desktop of course) to keep it Simple, small and downloaded as fast as Flash !! THings that I dont like from javafX: Code gets unreadable when your GUI is complex. it's a bit slow, and we need admin rights on the desktop to install ! !! So what can we do ???? Lots of problems for a simple developer like me who just wants the job done ! I think we need a 'java browser' like google did with chrome... dont know !! (Sorry for my bad english :-))by coderight - 2009-08-21 01:56
"There is a big need for something like SAF ..." Jazz Desktop Application Framework is a powerfull alternative to plain Swing, Eclipse/Netbeans RCP and SAF. It's free for personal use and commercially supported. http://jazz.coderight.nlby janerik - 2009-08-20 14:05
I think Sun did a good job on Java 1.6 Swing. I don't understand the point of JavaFX though. Custom shaped widgets are so 2001. Where is the marked ? Feels like J2ME angst. Even my website uses Swing, Java 2D and ImageIO to create live graphics.by mrmorris - 2009-08-20 12:41
> What I really do not understand: Why are there no reactions for all these posts here and the trouble from the key people at Sun Sun is in disarray, no employee know if their project and job is going to continue or not. Just look at the JRuby guys who fled. Before that of course, an impressive list of people (incl. Hans) had already left. Even though he did not mention it directly, it looks like he simply got tired of how things were run - the last 6 months or so he was tied up in JavaFX. Sun's motto seems to be "we do it all, but nothing really particular well". Harsh perhaps but come on, look at their history and how they i.e. screwed up Java in the browser to the point that it's now Java's bastard child JavaScript setting the agenda and making headlines.by geertjan - 2009-08-20 12:39
"RCP is in many use cases much oversized. " In fact, that's a myth. RCP (at least, NetBeans Platform) can be very small. As small as you need it to be. And most applications get bigger anyway, therefore a framework that you can scale upwards together with the needs of your applications is far preferable to one where you run into a brick wall as soon as you need something as simple as... a docking system, for example.by jede - 2009-08-20 11:58
Many people (also here) thinkt tat SAF / JSR 296 is just another Rich Client Platform. It itsn't - SAF and RCP have different goals and targeting an different audience. There is a big need for something like SAF which just provides the basic UI application infrastructure. RCP is in many use cases much oversized. What I really do not understand: Why are there no reactions for all these posts here and the trouble from the key people at Sun (Alexander, Richard, ...)? It's a shame when they just say "More work needs to be done". They've done almost nothing until today. Why they're not using public forums and discuss the problems they have? Probably because there are no problems when nothing get's done...by aehrenr - 2009-08-20 10:59
The way Sun/Oracle behaves with Swing is outrageous. We are not talking of a small test project but of the most commonly used GUI technology of the IT world. I have not the smallest interest in JavaFX because I think the idea to have a special language only for GUI programming is daffy. Above that declarative programming of advanced GUIs is a bad idea. And simple declarative GUIs are already made with HTML and AJAX. No need for something else, be it Flash, Silverlight or JavaFX. I only want to learn general programming languages such as Java or Scala and do not want to remember the peculiarities of languages used for a single small purpose. Really not. Above that, JavaFX might be appropriate for interactive television but not for cross platform applications distributed by web-start. And that is the main application of Java fat clients. I have never heard of a PR department as incapable as that from Sun. It looks as they are killing Swing with no need and they got me really angry on their company.by geertjan - 2009-08-20 09:59
Sun/Oracle isn't abandoning Swing. I work for Sun, just like everyone else on the NetBeans team, and we're all working in Swing...by opinali - 2009-08-20 09:32
(Disclaimer: I'm a JavaFX enthusiast.) I'm not deeply informed about SAF but there seems to be some redundancy. The Java desktop industry already have not one, but TWO major RCP frameworks, one from Sun/NetBeans and another from the Eclipse Foundation (much more mature and arguably more popular than NetBeans'). Even Swing itself is far from representing a de-facto standard, due to Eclipse's SWT/JFace/RCP/etc. Sun and Swing users may have little love for these competing frameworks from Eclipse, but cannot ignore them. Yeah, JavaFX may have been the last nail in Swing's coffin, but it was not the first and up to date even the major stab, that "honor" belongs to Eclipse. Not to mention other competing toolkits for Java ME (LCDUI, LWUIT - both also from Sun! - plus Android) because Swing was not designed with any level of architectural scalability, so a reasonable subset for mobile platforms was impossible. (AGUI was CDC only, and a fiasco AFAIK. And the latest smartphones, post-iPhone, heavily benefit from a new generation of toolkits anyway.) New application-level frameworks like SAF and BB would arrive in a ecosystem that's already divided and leaking developers to non-Swing toolkits and to non-Java platforms. And the community's inability to evolve the Java language is another major issue; the BB and SAF frameworks could be much better with proper usage of facilities like like closures and language-level properties... but no, we can only have "coin-sized" language enhancements, and just a handful of these. I looked at BB and it's totally horrible compared to JavaFX's properties and binding, so all empathy I might have for Swing/SAF/BB vanishes when I consider that the evolution of that platform can only happen by piling more and more layers of complex APIs, without necessarily hiding any complexity that already exists in the current APIs which are already massive.by cowwoc - 2009-08-20 08:15
Sad as it might be, I'm glad to see that Sun decided to "do this right" instead of shipping a half-assed solution.by carcour - 2009-08-20 07:56
Sad to see that Oracle/Sun is abandoning Swing. Swing is great and could have been improved but the toyish JavaFX route was chosen instead. Good luck!by mrmorris - 2009-08-20 07:42
@geertjan: Well there are no guarantees of course, but this is Java, where the community is encouraged to participate and join. Considering this was a full JSR backed by Sun, with spec lead of no less than Hans Muller, the risks seemed minuscule. But point taken, I will choose C# next time. Properties and the whole component model is already there and works. I had just hoped Swing would've gotten a little friendlier but it seems fairly evident Sun is betting everything on JavaFX which frankly feels no less complete than JSR-296.by mwildam - 2009-08-20 06:35
I just hope that Swing in general is not getting out of the focus and this is just one brick breaking away. - That said I am very glad to hear from geertjan, that there is active development on the Swing side. As I see more and more revival of thick clients maybe this will reflect in again more focus on Swing by Sun/Oracle.by haraldk - 2009-08-20 05:41
Sad news, but not really surprising. While I am actually happy that JSR-296 is NOT included in JDK7, I am really disappointed about the progress made. It's been several months since Alex blogged about SAF being the number one priority for the Swing team... And what has happened? A couple of minor bug fixes? I really hope someone pics up the good foundation in appframework.dev.java.net and makes something useful out of it. Because it really is a good start. .kby geertjan - 2009-08-20 04:59
osbald, the end user of industrial-size applications doesn't care so much about JavaFX. They want their applications to be flexibile and reliable, while developers of those applications don't want to need to recreate the wheel. That's what the NetBeans Platform is for and it continues to be developed, on a daily, hourly even, basis, including its Swing components. mrmorris, if you currently have products on top of JSR-296 while JSR-296 has consistently been "in progress" (and "always struggling"), then the decision to base your products on JSR-296 was always questionable.by mrmorris - 2009-08-20 04:02
> I don't see how all this is such a big loss, since Swing developers have had a Swing application framework all along: http://platform.netbeans.org/screenshots It is if you invested time and effort into it and currently have products using it. I'm at the same page as jede, I think I know why this happened (Sun preoccupied with JavaFX) and to be honest since Hans left I did not expect JSR-296 to move anywhere considering the other JSR's that have been dropped. For isntance, has JSR-296 been rewritten since such as to NOT depend on JSR-295?by osbald - 2009-08-20 03:09
geertjan, I guess you mean SAF and not the general slow decline of Swing by a thousand cuts - because Netbeans RCP is still very much Swing based. Unless you've got a RCP re-architecture up your sleeves much like Esclipse e4 is moving to adopt browser platform & javascript. Even then all of this is set against a general decline in interest of Java, in which case not even JFX will help you. Will be interesting to see how Oracle intends to reverse the trends and which APIs are deemed worthy of saving.by jfpoilpret - 2009-08-19 17:20
Well that's a big slap in the face of people who have invested their time (a lot for some) in JSR-296. I don't talk about us users of the framework, but I specially think of Karsten (and a few others, non Sun employees, involved in this Expert Group. While we are at Swing funerals, should we bury the JCP altogether as well? You can do whatever you want Sun/Oracle, don't expect all Swing developers to switch to JavaFX (I'd rather go to the "dark side"), because what JFX has to offer is useless compared with what Swing has offered us for years. I think (I hope?) Oracle has made a very bad calculus when deciding to continue the JFX effort, it will bite them (and all current and future JFX users) some day, probably sooner than later. Now I'm gonna infer on what I should do with my numerous Swing-related open source projects... Maybe I'll soon get a lot of time to do something else, more interesting, learn the guitar for instance, I don't think Gibson or Fender will someday decide to change the way guitars are tuned, by exchanging the positions of all strings although everybody is currently satisfied with the current disposition;-) This probably will be my last complaining post because such complaints in the void are such a waste of energy! Jean-Francoisby geertjan - 2009-08-20 01:38
I don't see how all this is such a big loss, since Swing developers have had a Swing application framework all along: http://platform.netbeans.org/screenshots@geertjan, I do respect your
by scotty69 - 2009-10-01 04:54
@geertjan, I do respect your heroic Swing/NB defense, but the big loss for Swing is the fact that SAF again has turned out to be vaporware like BB or many other Sun "initiatives" like JWebPane. There is no substantial Swing innovation perceptible at the moment. The Swing party seems to be over, so the party people start rushing to the other cool clubs in town...by osbald - 2009-08-19 12:58
I was thinking the same as jede, I dont think lack of consensus was the issue more like a lack of commitment from Sun. Honestly Alex you've only posted to the appframework mailing lists twice in the last year and one of those was back in March to express how SAF was now the Swings teams number 1 priority and youd not leave it six months between posts!! http://weblogs.java.net/blog/alexfromsun/archive/2009/03/swing_applicati... ..what happened there? where you or Sun lying to us? As the work on SAF hasn't happened can we expect new Swing features in Java7 instead? or are you saying the Swing teams resources where simply wasted in this case. Certainly I'd like to see some Windows 7 integration improvements for desktop Java. What's *really* new for Swing developers in Java7? what can it do that we cant with the current Java6 and the JXLayer jar?
On a similar note where does this leave the other Swing roadmap features also on the roadmap. Back at Devoxx SwingX datepicker and SwingX painters where also promised. I also know very little dialog has been happening between the developers and Sun since you cut funding to the Swinglabs projects. Is that going to be the next bit of news you'd care to share? I trust the Swing version of JWebPane and access to JavaFX from Java/Swing interop are running to schedule..? though the Netbeans team seem none to impressed.. http://wiki.netbeans.org/EmbeddedBrowserPrototypingJWebPane
OK I know you're going to give me the shifting priorities talk yet again, but after the last brohaha over Swinglabs Richard, Amy & Josh where all at pains to reassure us that Swing/Enterprise apps were important, the community was important and you guys weren't going to keep us in the dark.. But thats not been the case has it..? Will apppframework be seriously picked up post JDK7 or are we looking at another beanbindings? ie. so utterly abandoned the community has been forced to create their own fork. These feel like endings not bright futures, another nail in the Swing coffin and it seems Swing loses out in every one of these priority changes.. Should Swing now be considered a legacy API? because that's the message you guys are continuing to send.
by jede - 2009-08-19 10:45
These news are too sad :-( But where was this big discussion? It wasn't on the SAF mailing list. Was there any significant development since Hans Mueller has left the project and Sun? I don't think so - at least not in the public... This news sounds like SAF will not be included in JDK 7 for sure - am I right? Bye, StefanI was under the same
by cat - 2009-09-11 08:03
I was under the same impression. And at least one EG member I know well confirmed, there was little common and transparent joint effort involving the entire EG regularly. I have created Swing based modular/application based concepts with coffeeBeans back in 1999. Also played with SAF a little for demos supporting other JSRs, so if I know what issues exist I'd be happy to help with it (even as EG member if necessary ;-) Let me know if there's something you need help with. Cheers, WernerJDK 7 is moving forward!
I am happy to announce that Nimbus Look and Feel has been forward ported to JDK 7.
Among all other changes, the latest build #b57
contains the fix for 6591875: Nimbus Swing Look and Feel. It is a real pleasure to see the Nimbus LaF under "javax.swing.plaf" package! Check it out with the recent JDK 7 binaries. JXLayer will also be there soon, stay tuned... Thanks
alexp
- Login or register to post comments
- Printer-friendly version
- alexfromsun's blog
- 2908 reads
Comments
JDK 7 is moving forward!
by eykatz - 2011-01-16 13:37
I think we should really admit that Swing is dead - it's a dead project.
I've never seen a framework that its owners dpn't fixes 6 year old simple but terrible bugs (click on the edges of a JComboBox ,e.g. its bottom-left corener)
I'm developing UIs with Swing for the past 10 years, and 2011 is my last. it became impossible to create high-end UI with that framework, and all the blame goes to Sun, who for 10 years just let it to rotten...
Try telling DefaultRowSorter to treat nulls as greater than non-nulls - impossible (a private method) - because the people who maintain this framework are not serious or having difficulties in understanding what API means.
And just dont tell me that you have the face to show your customers Nimbus L&F - if they have some style, some asthetic awareness - they'll kick out of their office.
Sad words, from a developer who loves this framework most, and hates the mediocrity of its so-called developers.
by greggwon - 2009-07-21 13:10
SwingWorker is good for some things, but it still is missing the simple "on-swing", "off-swing", "on-swing", "off-Swing" sequences that are common for multi-component data updates. Please look at http://swingutil.dev.java.net and see what the org.wonderly.swing.SyncThread class does. It provides several ways that complex GUI updates can be managed for readily with proper syncronization. In addition, we need the Context ClassLoader to work in the EDT, so we remember it at construction, and set it in play when running code in the EDT. We also wanted to cover JAAS Subject use in the EDT as well, for more complex applications that involve security and remote code download.by greggwon - 2009-07-21 13:08
Please don't use a "text config" based layout engine as a new savior to layouts! A long time ago in a galaxy far far away, I put a nice simple layer over GridbagLayout that greatly simplifies how it is used and makes it trivial to read layouts of hand typed code. Have a look at http://packer.dev.java.net for what I think should really be the new face of rectangular layouts.by tmilard - 2009-05-06 14:43
I hate layout of swing. I just never used to it. complicated and not ... natural. It seem MigLayout could be a good add. I vote for it !by dutchiedave - 2009-05-05 18:13
I agree that MigLayout should definately be included in JDK7 and available for use in JavaFX.by geekycoder - 2009-05-04 23:48
Progress to JxLayer at http://www.pbjar.org/blogs/jxlayer/version_2/by geekycoder - 2009-05-04 23:45
Some improvements for Jdk7 ? - Listening for real clipboard data change (currently on flavour change is detected which has limited use) ? As of now, inefficient clipboard polling running in a thread can be used to detect data change but it prove problematic for large image (imagine polling for image in clipboard if the image is large) - global keyboard hook. Currently require JNI solution to listen for keys outside Java application.by geekycoder - 2009-05-04 23:37
Another critical improvement most developers will like to see in JDK7 is MIGLayout. It is a excellent layout, and I wonder why till now it is not planned for JDK7. Is it another NIH syndrome ? For Form development, MigLayout or JGoodies layout is really time-saving and indispensable , and I hope the Java desktop team really consider adding it for the sake of Java Swing/JavaFX 's future.



Comments
5 years ago you did a little side ...
by i30817 - 2011-12-29 15:10
5 years ago you did a little side project: alexfromsun/archive/2007/11/ debug_swing_rep.html
http://weblogs.java.net/blog/
that i think should be packaged into swinghelper's debug jar or similar:
http://swinghelper.java.net/
I also can no longer find it, so i'd request a new link.
Thank you, and good luck with swing redesigning (would be nice to get swing 2.0).
A problem that I often face is the lack of a ...
by AgostinoX - 2011-09-12 10:44
A problem that I often face is the lack of a consolidated binding architecture. As far as I know, BeansBindng (while adopted in Netbeans ide) is not part of the jdk yet, and the fact that its "ufficial" adoption is continuously delayed (was java 7, but has been delayed. Perhaps will be java 8, but nobody hazards a prediction anymore) seems to indicate that Oracle isn't intrested in that specific binding technology. While we, java developers, try to guess what the binding architecture will be (if there will be one) and many of us implement an home-made one, other developement environes comes with data-bound controls, that are able to connect to a database record out of the box.
For such scenarios I prefer to add a separate MouseListener ...
by wzberger - 2011-09-12 01:49
For such scenarios I prefer to add a separate MouseListener to the subcomponent and to redispatch mouse events. We had a similar blog post in the queue which is now online - see
http://www.jyloo.com/news/?pubId=1315817317000
The mouseListener approach doesn't work for all ...
by alexfromsun - 2011-09-13 03:25
The mouseListener approach doesn't work for all scenarious,
try to show the frame's glassPane, add a mouseListener to it
and then redispatch the events to the components below it.
Similarly if a component has a transparent panel inside,
adding a mouseListener to it will break the mouseEvents processing
The worst is JComboBox. I can think of several ...
by mcdev1 - 2011-09-08 19:34
The worst is JComboBox. I can think of several problems with it. It's too bad that Swing issues don't get any attention anymore, especially since JavaFX still is not actually usable for projects with long-term futures.
Hello mcdev1 I can't say that Swing issues don't get any ...
by alexfromsun - 2011-09-09 03:44
Hello mcdev1
I can't say that Swing issues don't get any attention,
we fix critical bugs and JLayer is a nice addition to JDK 7
Thanks
alexp
The Swing team does great work, but it's fighting a losing ...
by grandinj - 2011-09-09 05:29
The Swing team does great work, but it's fighting a losing battle.
The problem is that Swing is shipped inside the JDK, which mean it has horrible backwards compatibility guarantees to meet.
If Swing was split off from the JDK, the Swing team would be free to ship newer versions without the legacy cruft, enabling it to grow into the toolkit it should be.
Come over and have a look at Apache Pivot (http://pivot.apache.org/) to see how clean GUI toolkit code can be in Java when designing without a legacy burden.
The pivot project looks great! grandinj, are you one of its ...
by alexfromsun - 2011-09-09 05:45
The pivot project looks great!
grandinj, are you one of its contributors?
Thanks
alexp
Thanks! Yes, I'm one of the contributors - only in a ...
by grandinj - 2011-09-12 03:59
Thanks!
Yes, I'm one of the contributors - only in a very small way, I do minor bugfixes and some work on the Text components.
The primary committers are Todd Volkert and Greg Brown, and the toolkit is descended from an internal VMWare project.
You're welcome to contact me at noelgrandin@gmail.com if you want any more information.