BoxLayout bug in 1.5?

R

Ryan Stewart

I've looked around the web and Sun's bug DB, but don't seem to see any direct
mention of this problem. I came across it at work today (somebody flagged me
down with one of those, "What do you think about..." questions). It was quite
puzzling at first due to some other code cluttering it. Here is the simple
version:

import javax.swing.JFrame;
import javax.swing.BoxLayout;

public class BoxLayoutBug {

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame, BoxLayout.PAGE_AXIS));
frame.pack();
}
}

Run that and you'll get a java.awt.AWTError with message "BoxLayout can't be
shared". Why? The container passed to the BoxLayout must be the same container
on which the Layout is set. The above code causes the BoxLayout to be set on the
JFrame's contentPane, though the layout is referencing the frame. This is due to
JFrame's the overriden behavior of the setLayout method in 1.5. Would you
consider this a bug worthy of reporting? It seems that you have to have
knowledge of JFrame's internal workings in order to figure this out, so there's
at least a flaw in the interface.
 
R

Rhino

Ryan Stewart said:
I've looked around the web and Sun's bug DB, but don't seem to see any direct
mention of this problem. I came across it at work today (somebody flagged me
down with one of those, "What do you think about..." questions). It was quite
puzzling at first due to some other code cluttering it. Here is the simple
version:

import javax.swing.JFrame;
import javax.swing.BoxLayout;

public class BoxLayoutBug {

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame, BoxLayout.PAGE_AXIS));
frame.pack();
}
}

Run that and you'll get a java.awt.AWTError with message "BoxLayout can't be
shared". Why? The container passed to the BoxLayout must be the same container
on which the Layout is set. The above code causes the BoxLayout to be set on the
JFrame's contentPane, though the layout is referencing the frame. This is due to
JFrame's the overriden behavior of the setLayout method in 1.5. Would you
consider this a bug worthy of reporting? It seems that you have to have
knowledge of JFrame's internal workings in order to figure this out, so there's
at least a flaw in the interface.
I suspect that the reason you see this error is because you are
instantiating the BoxLayout in a static method. I'll bet that if you
executed the same code in a Constructor, you wouldn't get the error. (I've
instantiated BoxLayout successfully many times in Constructors, including in
1.5, but I've never tried it in a static method.)

That's not to say you SHOULD get an error if you do this in a static method;
my theory background isn't strong enough to be sure.

Maybe one of the gurus can weigh in with an opinion on this matter?

Have you tried the same code under previous versions of Java? Do you get the
same error? I wouldn't be certain that this error emerged in 1.5 unless I
verified that it didn't happen in earlier versions of Java.

Rhino
 
X

xarax

Ryan Stewart said:
I've looked around the web and Sun's bug DB, but don't seem to see any direct
mention of this problem. I came across it at work today (somebody flagged me
down with one of those, "What do you think about..." questions). It was quite
puzzling at first due to some other code cluttering it. Here is the simple
version:

import javax.swing.JFrame;
import javax.swing.BoxLayout;

public class BoxLayoutBug {

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame, BoxLayout.PAGE_AXIS));
frame.pack();
}
}

Run that and you'll get a java.awt.AWTError with message "BoxLayout can't be
shared". Why? The container passed to the BoxLayout must be the same container
on which the Layout is set. The above code causes the BoxLayout to be set on
the JFrame's contentPane, though the layout is referencing the frame. This is
due to JFrame's the overriden behavior of the setLayout method in 1.5. Would
you consider this a bug worthy of reporting? It seems that you have to have
knowledge of JFrame's internal workings in order to figure this out, so
there's at least a flaw in the interface.

It's not a bug. It's a "gotcha". The programmer should be
calling setLayout() on the contentPane, rather than on
the JFrame. The new 1.5 behavior of JFrame.setLayout() is
intended to be a convenience, and that new behavior won't
affect existing code. New code may be affected, as you have
discovered. The interaction with BoxLayout just needs to be
documented.
 
C

Chris Smith

Ryan Stewart said:
Would you consider this a bug worthy of reporting?

Certainly, go ahead and report it. I'd consider it a documentation bug
at most, though. I've never called setLayout on JFrame, so I was
unaware of the overridden behavior; but if JFrame does override
setLayout, then there should be a mention in the BoxLayout docs of this
case and the required solution.
It seems that you have to have
knowledge of JFrame's internal workings in order to figure this out,
so there's at least a flaw in the interface.

Sorta... but the existence of multiple panes in a top-level Swing
container is not an internal working, per se. It's really just
confusing, rather than wrong.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Ryan Stewart

Rhino said:
I suspect that the reason you see this error is because you are
instantiating the BoxLayout in a static method. I'll bet that if you
executed the same code in a Constructor, you wouldn't get the error. (I've
instantiated BoxLayout successfully many times in Constructors, including in
1.5, but I've never tried it in a static method.)
No, nothing to do with being in a static context. If that were the case, it
would more likely be a JVM bug, which would be far more serious.
That's not to say you SHOULD get an error if you do this in a static method;
my theory background isn't strong enough to be sure.

Maybe one of the gurus can weigh in with an opinion on this matter?

Have you tried the same code under previous versions of Java? Do you get the
same error? I wouldn't be certain that this error emerged in 1.5 unless I
verified that it didn't happen in earlier versions of Java.
In earlier versions of Java, you couldn't call setLayout on a JFrame, so no, you
wouldn't get that same error. That's why it's new to 1.5.
 
R

Ryan Stewart

Chris Smith said:
Certainly, go ahead and report it. I'd consider it a documentation bug
at most, though. I've never called setLayout on JFrame, so I was
unaware of the overridden behavior; but if JFrame does override
setLayout, then there should be a mention in the BoxLayout docs of this
case and the required solution.
The overridden behavior is an "enhancement" in 1.5.
Sorta... but the existence of multiple panes in a top-level Swing
container is not an internal working, per se. It's really just
confusing, rather than wrong.
It was definitely confusing at first.
 
R

Ryan Stewart

xarax said:
It's not a bug. It's a "gotcha". The programmer should be
calling setLayout() on the contentPane, rather than on
the JFrame. The new 1.5 behavior of JFrame.setLayout() is
intended to be a convenience, and that new behavior won't
affect existing code. New code may be affected, as you have
discovered. The interaction with BoxLayout just needs to be
documented.
What is the point of defining a method setLayout(LayoutManager) that can only
accept *some* LayoutManagers?
 
K

Knute Johnson

Ryan said:
The overridden behavior is an "enhancement" in 1.5.



It was definitely confusing at first.

The really interesting thing is that BoxLayout is the only layout
manager to require the container it is going to layout as an argument.
It makes one wonder what they are doing with the Container reference.
 
R

Ryan Stewart

Knute Johnson said:
The really interesting thing is that BoxLayout is the only layout manager to
require the container it is going to layout as an argument. It makes one
wonder what they are doing with the Container reference.
See also javax.swing.OverlayLayout.

What they do with it:
void checkContainer(Container target) {
if (this.target != target) {
throw new AWTError("BoxLayout can't be shared");
}
}

That method is called from:
invalidateLayout
preferredLayoutSize
minimumLayoutSize
maximumLayoutSize
getLayoutAlignmentX
getLayoutAlignmentY
layoutContainer

I don't see any obvious reason why all of those methods couldn't simply use the
Container that is passed to them without checking to make sure it is the one the
BoxLayout was constructed on.
 
K

Knute Johnson

Ryan said:
See also javax.swing.OverlayLayout.

What they do with it:
void checkContainer(Container target) {
if (this.target != target) {
throw new AWTError("BoxLayout can't be shared");
}
}

That method is called from:
invalidateLayout
preferredLayoutSize
minimumLayoutSize
maximumLayoutSize
getLayoutAlignmentX
getLayoutAlignmentY
layoutContainer

I don't see any obvious reason why all of those methods couldn't simply use the
Container that is passed to them without checking to make sure it is the one the
BoxLayout was constructed on.

Ryan:

That is interesting. I don't know enough about the insides of layout
managers to know what's what but all the other layout managers must have
these same methods.

Did you submit a bug report? I can't imagine you are the first person
to run across this issue. It would have cost me some time if I had run
across it. There are too many of these poorly documented features.
 
R

Ryan Stewart

[...]
Did you submit a bug report? I can't imagine you are the first person to run
across this issue. It would have cost me some time if I had run across it.
There are too many of these poorly documented features.
Just did. We'll see what happens.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top