This used to be a question, but during summarizing my thoughts into words, I found the solution. I have nowhere found any single word on this problem, so I think it can be valuable for others ;)
I want to make my JNLP JApplet resizable. I need the application to extend JApplet, JFrame is not sufficient for me. By default (at least in my JNLP launcher from the standard Sun JDK) the window is not resizable. I use this code to make it resizable:
Component parent = this;
while (parent.getParent() != null)
parent = parent.getParent();
if (parent instanceof Frame) {
((Frame) parent).setResizable(true);
// TODO the frame becomes resizable, but the layout doesn't resize the content
}
I place this code in the constructor of the applet. The maximize button really gets enabled and I can resize the window.
The problem is that the contents of the window do not know that resizing happens and do not relayout them to fit the new size.
If I run the applet using AppletViewer, resizing works well.
A bit of investigation:
layoutContainer(Container parent) method of the layout of the JApplet receives the applet's contentPane, and whatever the real size is, it always has getSize() == the size defined when running JNLP.
If I call parent.pack() on the main frame for every resize event, the window gets resized to the very minimum to show the three titlebar buttons (about 100x30px).
So I think that the
JNLP Launcher uses a weird layout in which it includes the JApplet. I think the layout isn't prepared for any resizing.
Do you know a way to get the resizing working?
I tried to call both getContentPane().setSize(parent.getSize) and setSize(parent.getSize) for the frame's resize events (yes, the resize events really get called), but that also doesn't change the odd behavior.
Ok, now I finally figured it out!
The whole thing was really a layoutManager problem! When I changed my function to the following, everything works fine!
Component parent = this;
while (parent.getParent() != null)
parent = parent.getParent();
if (parent instanceof Frame) {
if (!((Frame) parent).isResizable()) {
((Frame) parent).setResizable(true);
((Frame) parent).setLayout(new GridLayout());
}
}
And some final notes.
I chose GridLayout because it is the only standard layout that worked for me. (The others either need constraints or cannot be shared (BoxLayout), which - like I saw - is fatal, or do not resize their contents in the way I need (FlowLayout).
The test for isResizable() is here for the case the application is launched via AppletViewer - without this test, the appletviewer GUI was damaged (yes, AppletViewer adds some more components in the same panel as the applet).
PS: I don't like this solution, it seems hacky to me, but it is the only one that works. If you'll find a better one, please post it here.
So, I hope this will help someone ;)