JDK-4924163 : JTextArea with word wrap does not return correct preffered size
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P2
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_2000
  • CPU: generic
  • Submitted: 2003-09-17
  • Updated: 2004-03-18
  • Resolved: 2004-03-18
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
This bug is reproducible with Java Control Panel (available with JRE).  In 1.5 the Control Panel uses JTextArea components with word wrap.  The pack() method does not determine the size of the Control Panel correctly if setLineWrap(true);
setWrapStyleWord(true); are set on the JTextArea components.  This causes some components of Control Panel to show up off the viewable area.
Control Panel is localized application, and in different languages the size of each text area will change.  In order to make Control Panel show up correctly in all locals this has to be fixed.
I am attaching an easy test case which demonstrates the problem.  If you comment out lines where you set the word line wrap to true, the frame will pack and show up correctly.


Comments
EVALUATION Name: ik75403 Date: 09/22/2003 here goes simplified test case: -- import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MyFrame extends JFrame { public MyFrame() { JTextArea textArea = new JTextArea("Some text here lkjsdf lkjsdflk" + " lkjsdflkj lkjsdfl lk lkjsdfd " + "lksd lkjseflk lkjksddf"); textArea.setEditable(false); textArea.setLineWrap(true); textArea.setWrapStyleWord(true); setLayout(new BorderLayout()); add(textArea, BorderLayout.NORTH); JPanel btnsPanel = new JPanel(); btnsPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); btnsPanel.add(new JButton("One")); btnsPanel.add(new JButton("Two")); btnsPanel.add(new JButton("Three")); add(btnsPanel, BorderLayout.SOUTH); setResizable(false); } public static void main(String args[]) { MyFrame test = new MyFrame(); test.pack(); test.setVisible(true); test.toFront(); } } -- For TextArea preferred height depends upon given width. It gets width after pack(). This widht changes preferred height. We get this ugly looking dialog. With a gap between TextArea and buttons. What do we do? Two pack() in a row ? ====================================================================== Begin evaluation by ###@###.### There is no bug in the layout manager's algorithm in this case. The mentioned in the description behavior happens because of the following: 1. JTextArea has been added not in the BorderLayout.CENTER region. JTextArea is added in the BorderLayout.NORTH region in the original test case. 2. JTextArea changes its preferred height depending on its preferred width. Since JTextArea is added in the BorderLayout.NORTH region, the layout manager uses its preferred height as a component height. The layout manager processes a component correctly only if this component does not change its preferred size during laying out components, since it uses cached value of component's preferred size. The component should care for that the layout manager has learned the new preferred size by itself. The layout manager works as expected in this case. As a workaround you might add JTextArea in the BorderLayout.CENTER region. End evaluation by ###@###.### I discussed this with Scott and Brent. This is not a regression: the code is working just as it always has. And it isn't a bug in AWT. However, it could be an rfe requiring a new API. Someone from Swing will take another look at what might be done about this. ###@###.### 2003-11-20 Any fix really needs to be made in JTextArea. Even if a new API could be added to the layout manager, there are hundreds, if not thousands of layout managers in existence. Realistically, they can't all change to accomodate the anomalous behavior of JTextArea. If we can't come up with a better solution than adding a new API to the layout manager (or layout managers), it is possible to do it. However, investigation really needs to be done on the swing side. ###@###.### 2003-11-21 Swing's text components are unique in that one axis is typically dependant upon another. In this case how tall the JTextArea wants to be depends upon how wide it currently is. A ramification of this is that if the JTextArea is not given it's preferred width it will most likely need to be layed out again. A shortened version of pack looks like: Dimension pref = getPreferredSize(); setSize(pref.width, pref.height); In certain cases it's entirely possible for a component to be given a completely different size than it requested, and that's what's happening here. JTextArea, because it has no size assumes a default width and calculates it's preferred size based on that. The other buttons end up forcing the width of the Dialog to be bigger than the size the JTextArea assumes, so that the JTextArea is given a bigger width, and therefor bigger height than it needs. AWT was not designed to accomodate such components and therefor it would be extremely difficult to retrofit this in. Instead we'll likely add API that allows you to fix the preferred size of one axis and leave the other flexible. There is already an RFE for this: 4903046. As it's too late to retrofit a real solution for this in, I'm closing this bug out as will not fix. ###@###.### 2003-11-21 ------ 4924163 might get much better. BorderLayout.java -- layoutContainer( ) c.setSize(right - left, c.height); Dimension d = c.getPreferredSize(); c.setBounds(left, top, right - left, d.height); -- First it sets size for the component and after that it uses preferredHeight for the layout. If we are to calculate correct PreferredHeight after setSize it would help. Even better we do not need to calculate. It could be done upfront. For wrapped plain document function getPreferredHeight(width) is simple. The text could be wrapped on certain points: words boundaries or character bounders. Thus the function getPreferredHeight(width) would change the value only certain number of times (every time new line is created after the wrapping) I am reopening 4924163 to give it a try. ###@###.### 2004-03-17 The bug the way it is described in the description is fixed in tiger already. All components showup in the page. The new problem we have got is described above by ###@###.### This new problem happens because we do return the updated preferredSize after setSize Sorry guys. As ###@###.### suggested closing as 'will not fix' again.
03-09-2004