Keilly: June 2013

Monday, June 17, 2013

Preferred Height of JTextComponents

Given some text and a text component (e.g. JTextArea), it is not obvious how to set the preferred size of the component to only show the current content.
Skip to Answer

This:
     JTextArea ta = new JTextArea();  
     ta.setLineWrap(true);  
     ta.setText("112 312 3 12 31 2432135r34534t 3 t3 4t34y4hthefbasdgagaergergwreg"  
         + "rwergerg ergergergefdav asdvsadg sadgsad gsdgsdgsadgsgd sdgsdg"  
         + "sdg sdgsdgsdg sdgsdgsdgsgh4hgaregwaegasdg sdgsdg sagae4gsaegs "  
         + " sdgsdg sdg s gs dg sd gs dg sdg sdg sadgsdg sad gsa dg s"  
         + "se gs eg se g saeg sa eg s eg sa eg e g eg aweg");  
     JScrollPane sp = new JScrollPane(ta);  
     System.out.println("TextArea Pref Size: " + ta.getPreferredSize());  
     System.out.println("ScrollPane Pref Size: " + sp.getPreferredSize());  

Gives:
TextArea Pref Size: java.awt.Dimension[width=100,height=16]
ScrollPane Pref Size: java.awt.Dimension[width=104,height=20]

The layout manager follows the preferred sizes and it looks like this:


Lets say we want a preferred width of 300, what do we put for the preferred height?
We can't put in an arbitrary preferred height and hope Swing will trim it down, instead it just obeys what we tell it:

     ta.setPreferredSize(new Dimension(300, 100000));

TextArea Pref Size: java.awt.Dimension[width=300,height=10000]
ScrollPane Pref Size: java.awt.Dimension[width=304,height=10004]




So the trick is to get Swing to calculate the height for a given width and text...

We're told never to user setSize() methods on components, we should let the layout manager set the size, we should always use setPreferredSize().
This is an exception, if we set our actual width and also pass an arbitrary and very large height: Swing will automatically set the preferred size to suit only the text at our given width. All the extra height will be ignored.

     JTextArea ta = new JTextArea();  
     ta.setLineWrap(true);  
     ta.setText("112 312 3 12 31 2432135r34534t 3 t3 4t34y4hthefbasdgagaergergwreg"  
         + "rwergerg ergergergefdav asdvsadg sadgsad gsdgsdgsadgsgd sdgsdg"  
         + "sdg sdgsdgsdg sdgsdgsdgsgh4hgaregwaegasdg sdgsdg sagae4gsaegs "  
         + " sdgsdg sdg s gs dg sd gs dg sdg sdg sadgsdg sad gsa dg s"  
         + "se gs eg se g saeg sa eg s eg sa eg e g eg aweg");  
     JScrollPane sp = new JScrollPane(ta);  
     ta.setSize(300, 100000); // desired width, but deliberately large height.  
     System.out.println("TextArea Pref Size: " + ta.getPreferredSize());  
     System.out.println("ScrollPane Pref Size: " + sp.getPreferredSize());  


TextArea Pref Size: java.awt.Dimension[width=300,height=112]
ScrollPane Pref Size: java.awt.Dimension[width=304,height=116]


Look, the component has been sized to exactly match our text at our preferred width!

Use textComponent.setSize(preferredWidth, 1000000)to set a preferred size for text components.