🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.jbuilder.java.swing
Article #1176

Re: Layout Question - BoxLayout and JTextAreas. Example program included.

#1176
From: Greg Hamer
Date: Mon, 22 Mar 2004 18:02
159 lines
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-mail
References: <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