JDK-4426701 : getPreferredSize() in JTextField/JTextArea ignores insets if getColumns() != 0
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.0,1.3.1,1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_nt
  • CPU: generic,x86
  • Submitted: 2001-03-16
  • Updated: 2013-05-21
  • Resolved: 2002-11-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description

Name: boT120536			Date: 03/16/2001


java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Client VM (build 1.3.1beta-b15, mixed mode)

This error also happens in jdk1.3, jdk1.2.x, etc

Related bug: 4339681

If a JTextField/JTextArea is created with the number of columns greater
than 0, getPreferredSize() returns columns * metrics.charWidth('m') which
is incorrect because it ignores the insets (border) of the component.

Compile and run the program below. It creates a window with two 10
character JTextField's.
The second JTextField has an overridden getPreferredSize() that adds
the insets to the width of the field.
Note that the last letter 'm' in the first text field is cut in the middle
and that the second text field shows correctly all the letters.
Also, pressing the Home and End keys in the first field makes the text
move to the right and to the left so that the first/last letter can
be shown.

With variable sized fonts the problem isn't much noticed, but when fixed
size fonts are used it's very annoying.

Note that the JTextArea component also suffers from the same feature, both
with the width and the height of the component


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

public class SizeTest {

    public static void main(String[] args) {
        new SizeTest();
    }

    private JFrame frame;
    private JTextField textfield1, textfield2;

    private SizeTest() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent cpanel = (JComponent) frame.getContentPane();
        cpanel.setLayout(new FlowLayout());
        cpanel.setPreferredSize(new Dimension(150, 80));

        textfield1 = new JTextField("mmmmmmmmmm", 10);

        textfield2 = new JTextField("mmmmmmmmmm", 10) {
             public Dimension getPreferredSize() {
                 Dimension size = super.getPreferredSize();
                 if (getColumns() != 0) {
                     Insets insets = getInsets();
                     size.width += insets.left + insets.right + 2;
                     // The + 2 accounts for 1 pixel in the left and right
                     // side of the field that is used by the caret
                 }
                 return size;
             }
        };
        cpanel.add(textfield1);
        cpanel.add(textfield2);


        frame.pack();

        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screen.width - frame.getWidth()) / 2;
        int y = (screen.height - frame.getHeight()) / 3;
        frame.setLocation(x, y);
        frame.setVisible(true);
        
    }
}


  Suggested correction:

Alter JTextField.getPreferredSize() to:

public Dimension getPreferredSize() {
   synchronized (getTreeLock()) {
      Dimension size = super.getPreferredSize();
      if (columns != 0) {
         Insets insets = getInsets();
         size.width = columns * getColumnWidth()
                              + insets.left + insets.right + 2;
      }
      return size;
   }
}

Alter JTextArea.getPreferredSize() to:

public Dimension getPreferredSize() {
	Dimension d = super.getPreferredSize();
   d = (d == null) ? new Dimension(400,400) : d;
   if (rows != 0 || columns != 0) {
      Insets insets = getInsets();
      if (columns != 0) {
         d.width = Math.max(d.width, columns * getColumnWidth()
                                        + insets.left + insets.right + 2);
      }
      if (rows != 0) {
         d.height = Math.max(d.height, rows * getRowHeight()
                                        + insets.top + insets.bottom + 2);
      }
   }
	return d;
}
(Review ID: 118967) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b08
24-08-2004

WORK AROUND Name: boT120536 Date: 03/16/2001 Subclass JTextField.getPreferredSize() and JTextArea.getPreferredSize() so that the insets are added to the width/height of the component. ======================================================================
24-08-2004

EVALUATION Commit to mantis. ###@###.### 2002-05-21
21-05-2002