Article View: borland.public.jbuilder.java.swing
Article #1176Re: Layout Question - BoxLayout and JTextAreas. Example program included.
From: Greg Hamer
Date: Mon, 22 Mar 2004 18:02
Date: Mon, 22 Mar 2004 18:02
159 lines
6460 bytes
6460 bytes
You could use a JTextPane instead. It can handle multiple fonts in the
document.
"Hal Brooks" <dont@spamme.com> wrote in message
news:405bbe99.82703921@newsgroups.borland.com...
> Hi all,
>
> I'm trying to create a resizeable chat-ish area for displaying
> messages. Each message gets it own font. Messages are stacked
> vertically with the newest at the bottom, and a scrollbar allows
> history access to older messages. You get the idea.
>
> What I've tried thus far is to use a JTextArea for each message (which
> handles the necessary wordwrap), place all these onto a Box for
> layout, use a JScrollPane for scrolling, and put the JScrollPane into
> a JFrame for resizeability. I had to derive from most of those to get
> things even close to right.
>
> Problem is, the JTextArea-derived class is always a step behind in
> calculating its preferred size. So if you expand the frame
> horizonally far enough that none of the lines need to wrap, then smash
> it back to its minimum width, the text areas don't grow vertically to
> account for the line wrap, and things look bad.
>
> I've spent many hours on this, Googled various resources, read Help
> files, references, and all sorts of things on Sun's site. No luck. I
> would greatly appreciate any advice. I'm still developing an
> understanding of how Swing layout works. For all I know, I'm
> approaching this completely wrong. I once did a similar thing in
> Windows/C++ by implementing everything myself including the wordwrap
> logic and all the drawing. I was hoping to get Swing to do much of
> the work for me. The C++ solution took a while to code...
>
> An example program follows. I abused some good practices herein for
> brevity. (Ex. public variables.) I also put a red border around the
> Box and a black border around each text area, and did some logging to
> the console, to be able to tell what is going on.
>
> ----------------------------------------
>
> import java.util.logging.*;
> import javax.swing.*;
> import java.awt.*;
> import java.awt.event.*;
>
>
> public class uitest {
> public static void main(String[] strings) {
> JFrame frame = new JFrame("UI Text");
>
> uiPanel uip = new uiPanel();
> frame.getContentPane().add(uip);
> frame.pack();
> frame.setVisible(true);
>
> uip.AUiBox.addUiText("Test Message One, \"serif\" font, plain, 12
> point", new Font("serif", Font.PLAIN, 12));
> uip.AUiBox.addUiText("Text Message Two, \"monospaced\" font, bold,
> 14 point", new Font("monospaced", Font.BOLD, 14));
> uip.AUiBox.addUiText("Text Message Three, \"sansserif\" font,
> italic, 18 point", new Font("monospaced", Font.ITALIC, 16));
> }
> }
>
>
> class uiPanel extends JPanel {
> public final uiBox AUiBox;
>
> public uiPanel() {
> setPreferredSize(new Dimension(350, 100));
> setLayout(new BorderLayout());
>
> AUiBox = new uiBox();
> final JScrollPane sp = new JScrollPane(AUiBox,
>
> JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
>
> JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
> sp.addComponentListener(new java.awt.event.ComponentAdapter() {
> public void componentResized(ComponentEvent e) {
> AUiBox.scrollPaneResized(sp.getViewport().getWidth());
> }
> });
> add(sp, BorderLayout.CENTER);
> }
> }
>
>
> class uiBox extends Box {
> public uiBox() {
> super(BoxLayout.Y_AXIS);
> setBorder(BorderFactory.createLineBorder(new Color(0xFF0000), 1));
> }
>
> public void addUiText(String text, Font font) {
> uiText uit = new uiText(text, font);
> add(uit);
>
> Dimension d = getSize();
> d.height += uit.recalcSize(d.width);
> setPreferredSize(d);
> setSize(d);
> }
>
> public void scrollPaneResized(int viewportWidth) {
> int newWidth = viewportWidth;
> int newHeight = 0;
> int numComponents = getComponentCount();
> for (int i = 0; i < numComponents; i++) {
> uiText uit = (uiText)getComponent(i);
> newHeight += uit.recalcSize(newWidth);
> }
>
> Dimension d = new Dimension(newWidth, newHeight);
> setMaximumSize(d);
> setMinimumSize(d);
> setPreferredSize(d);
> setSize(d);
>
> String msg = "newWidth: " + newWidth + ", newHeight: " +
> newHeight;
> new ConsoleHandler().publish(new LogRecord(Level.SEVERE, msg));
> }
> }
>
>
> class uiText extends JTextArea {
> public uiText(String text, Font font) {
> super(text);
> setOpaque(false);
> setEditable(false);
> setLineWrap(true);
> setWrapStyleWord(true);
> setAlignmentX(0);
> setFont(font);
>
> setBorder(BorderFactory.createLineBorder(new Color(0), 1));
> }
>
> public int recalcSize(int parentWidth) {
> setMinimumSize(new Dimension(parentWidth, 0));
> setMaximumSize(new Dimension(parentWidth, Integer.MAX_VALUE));
>
> setSize(parentWidth, 1);
>
> String msg = "parentWidth: " + parentWidth +
> ", prefWidth: " + getPreferredSize().getWidth() +
> ", prefHeight: " + getPreferredSize().getHeight();
> new ConsoleHandler().publish(new LogRecord(Level.SEVERE, msg));
>
> return (int)getPreferredSize().getHeight();
> }
>
> public Dimension getMaximumSize() {
> return new Dimension((int)super.getMaximumSize().getWidth(),
> (int)getPreferredSize().getHeight());
> }
> }
>
Technical Details
Message-ID:
<405f29cc$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mailReferences:
<405bbe99.82703921@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,dd7cb71a5712f2ed X-Google-Attributes: gid111d45,public X-Google-ArrivalTime: 2004-03-22 10:07:18 PST From: "Greg Hamer" <ghamer@dslextreme.com> Newsgroups: borland.public.jbuilder.java.swing References: <405bbe99.82703921@newsgroups.borland.com> Subject: Re: Layout Question - BoxLayout and JTextAreas. Example program included. Date: Mon, 22 Mar 2004 10:02:17 -0800 Lines: 161 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 NNTP-Posting-Host: 24.52.242.126 Message-ID: <405f29cc$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1079978444 24.52.242.126 (22 Mar 2004 10:00:44 -0800) Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail