Daniel Bobbert had the excellent suggestion that the
limitation on resizing Frames in MRJ 3.1 for OS X could be overcome by
overriding getMinimumSize in the Frame. This works, allowing resizing down
to the 50 x 50 size I specified. This is demonstrated in the applet
below.
Interestingly, on Windows (IE 6.0, NN 4.08, 4.7, 6.2) the
minimum size is ignored and the Frame can still go to 0 x 0. On Macintosh OS
9 (IE 5.0, NN 6.2 and Applet Runner) the minimum size is observed, though the
exact dimensions look different under the different environments.
This certainly qualifies as an acceptable workaround.
It may even be a good solution to the problem, though my favorite solution would
be to have resizing with GridBagLayout behave
like resizing with FlowLayout.
The source code is shown below and can be downloaded from this
link:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ResizingFrame extends Applet {
public void init()
{
setBackground(Color.yellow);
PoliteFrame frame = new PoliteFrame("A frame");
PanelWithBars panelWithBars = new PanelWithBars();
frame.add(panelWithBars);
frame.setBounds(300, 100, 400, 550);
frame.validate();
frame.show();
}
} // END OF Class ResizingFrame
class PanelWithBars extends Panel {
int barsShowing, maxBars, barHeight, pad;
Bar[] bar;
PanelWithBars()
{
setLayout(new GridBagLayout());
barsShowing = maxBars = 4;
barHeight = 100;
pad = 5;
bar = new Bar[maxBars];
for (int i=0; i<maxBars; i++)
{
bar[i] = new Bar(barHeight);
addBar(i);
}
}
public void setBounds(int x, int y, int width, int height)
{
int barsToShow = height/(barHeight + pad + pad);
if (barsToShow > maxBars) barsToShow = maxBars;
if (barsToShow < barsShowing) for (int i = barsToShow; i<barsShowing; i++) remove(bar[i]);
else if (barsToShow > barsShowing) for (int i = barsShowing; i<barsToShow; i++) addBar(i);
barsShowing = barsToShow;
super.setBounds(x, y, width, height);
}
void addBar(int index)
{
constrain(this, bar[index], 0, index, 1, 1, GridBagConstraints.NORTH, pad, pad, pad, pad,
GridBagConstraints.NONE, 0, 0);
}
static final void constrain(Container container, Component component, int grid_x, int grid_y,
int grid_width, int grid_height, int anchor, int topPad, int leftPad, int bottomPad,
int rightPad, int fill, double weightx, double weighty)
{
GridBagConstraints c = new GridBagConstraints();
c.gridx = grid_x;
c.gridy = grid_y;
c.gridwidth = grid_width;
c.gridheight = grid_height;
c.anchor = anchor;
c.insets.top = topPad;
c.insets.left = leftPad;
c.insets.bottom= bottomPad;
c.insets.right = rightPad;
c.fill = fill;
c.weightx = weightx;
c.weighty = weighty;
((GridBagLayout)container.getLayout()).setConstraints(component, c);
container.add(component);
}
} // END OF Class PanelWithBars
class PoliteFrame extends Frame implements WindowListener
{
PoliteFrame(String s)
{
super(s);
addWindowListener(this);
}
public final Dimension getMinimumSize()
{
return(new Dimension(50, 50));
}
public void windowOpened(WindowEvent we){}
public void windowClosed(WindowEvent we){}
public void windowIconified(WindowEvent we){}
public void windowDeiconified(WindowEvent we){}
public void windowActivated(WindowEvent we){}
public void windowDeactivated(WindowEvent we){}
public void windowClosing(WindowEvent we)
{
if (we.getSource() == this)
{
setVisible(false);
dispose();
}
}
} // END OF Class PoliteFrame
final class Bar extends Canvas {
int width;
int height;
Bar(int height)
{
this.height = height;
}
public void addNotify()
{
super.addNotify();
repaint();
}
public final void paint(Graphics g)
{
width = getSize().width;
g.setColor(Color.blue);
g.fillRect(0, 0, width, height);
}
public final Dimension getMinimumSize()
{
return(new Dimension(10, height));
}
public final Dimension getPreferredSize()
{
return(new Dimension(300, height));
}
} // END OF Class Bar