JDK-4345920 : setMinimumSize() has no effect, presumably overridden by setPreferredSize()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2000-06-15
  • Updated: 2002-01-03
  • Resolved: 2002-01-03
Description

Name: rl16235			Date: 06/15/2000


java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)

/*
  JLabel.SetMinimumSize doesn't work.
  
  Run the test program. The window contains a JTextField, and a JLabel
  that shows a count of the number of characters in the field.
  The JLabel's minimum width is set to the width of two numeric
  characters, which comes to 14 in the Metal L&F. However, the actual
  width is determined by the number of characters in the field.
  if there are less than two characters in the label, it will be
  smaller than the minimum width, so setMinimumWidth had no effect.
  The second field successfully uses the workaround.
  
  Am I misunderstanding the intended effect of setMinimumSize()? If
  the minimum size can be overridden by the preferred size, the
  documentation should say so.
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class MinSizeBug extends JPanel
{
  public static void main(String[] args)
  {
    JFrame mf = new JFrame("JLabel Minimum Size Bug");
    WindowListener wl = new WindowAdapter()
    {
      public void windowClosing(WindowEvent evt) { System.exit(0); }
    };
    mf.addWindowListener(wl);
    mf.setBounds(10, 10, 400, 100);
    System.out.println("Java version " + System.getProperty("java.version"));
    mf.getContentPane().add(new MinSizeBug(), BorderLayout.NORTH);
    mf.show();
  }

  MinSizeBug()
  {
    super(new GridLayout(0, 1));
    JLabel countLabel = new JLabel("0");
    setUpField(countLabel);
    JLabel fixedLabel = new JLabel("0")
    {
      public Dimension getPreferredSize()
      {
        Dimension pSize = super.getPreferredSize();
        Dimension mSize = getMinimumSize();
        int wid, ht;
        
        wid = pSize.width < mSize.width  ? mSize.width : pSize.width;
        ht = pSize.height < mSize.height ? mSize.height: pSize.height;
        return new Dimension(wid, ht);
      }
    };
    setUpField(fixedLabel);
  }
  
  private void setUpField(JLabel lbl)
  {
    JPanel topPnl = new JPanel(new BorderLayout());
    Dimension min = new
Dimension(lbl.getFontMetrics(lbl.getFont()).stringWidth("00"), 0);
    lbl.setMinimumSize(min);
    lbl.setHorizontalAlignment(JLabel.RIGHT);
    lbl.setToolTipText("Character Count");
    topPnl.add(lbl, BorderLayout.WEST);
    
    JTextField txtFld = new JTextField();
    DocumentListener countEar = new Counter(lbl);
    txtFld.getDocument().addDocumentListener(countEar);
    topPnl.add(txtFld, BorderLayout.CENTER);
    add(topPnl);
  }
  
  private class Counter implements DocumentListener
  {
    private JLabel myLabel;
    private Counter(JLabel lbl) { myLabel = lbl; }
    public void insertUpdate(DocumentEvent e) { doShow(e); }
    public void removeUpdate(DocumentEvent e) { doShow(e); }
    public void changedUpdate(DocumentEvent e) { doShow(e); }
    private void doShow(DocumentEvent evt)
    {
      myLabel.setText("" + evt.getDocument().getLength());
    }
  }
}
(Review ID: 103232) 
======================================================================

Comments
WORK AROUND Name: rl16235 Date: 06/15/2000 Override getPreferredSize(), and prevent it from returning a size smaller than the minimum size, like this: public class FixedLabel extends JLabel { public Dimension getPreferredSize() { Dimension pSize = super.getPreferredSize(); Dimension mSize = getMinimumSize(); int wid, ht; wid = pSize.width < mSize.width ? mSize.width : pSize.width; ht = pSize.height < mSize.height ? mSize.height: pSize.hieght; return new Dimension(wid, ht); } }; ======================================================================
11-06-2004

EVALUATION This is really a function of the layout manager. Many layout managers assume that min <= pref <= max holds. Additionally some LayoutManagers will never check the min/max, they will always layout using the preferred. In fact BorderLayout behaves in this manner in that layoutContainer only consults the preferred size. The contract most layout managers try to use is use the pref, if the Components won't fit, then use the min or the max or some value in between. In the included code you are setting the min size, but since BorderLayout doesn't use the min size, it appears to have no effect. ###@###.### 2002-01-02
02-01-2002