21 April 2009

GroupLayout vs JFrame - the content pane problem

I really like the "new" GroupLayout that was introduced in JDK 1.6. It originates from Netbeans GUI editor. It is a layout that groups components in logical groups. For a tutorial of GroupLayout see http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html.

The JFrame is a sneaky Swing implementation. It has a content pane where the main things of your application should be in. But is has convenience methods (for example add() and setLauout()) that actually invokes call in the content pane. This might make you believe you can use is just as a normal container when using GroupLayout. The naive approach is to do this:
public class MyFrame extends JFrame {
GroupLayout layout = new GroupLayout(this);
...

This will unfortunately not work. The GroupLayout is fooled to control the JFrame, but in fact it should control the content pane inside the JFrame. The solution is instead to to this:

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class GroupLayoutJFrameExample extends JFrame {

private GroupLayout layout = new GroupLayout(this.getContentPane());

public GroupLayoutJFrameExample() {
initLayout();
pack();
}

private void initLayout() {
this.getContentPane().removeAll();
this.getContentPane().setLayout(layout);

JLabel helloLabel = new JLabel("Hello!");

layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(helloLabel)
);

layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(helloLabel)
);
}

public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new GroupLayoutJFrameExample();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

No comments:

Post a Comment