🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Layout Question - BoxLayout and JTextAreas. Example program included.

#1165
From: Hal Brooks
Date: Sat, 20 Mar 2004 04:02
153 lines
5881 bytes
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: <405bbe99.82703921@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 111d45,dd7cb71a5712f2ed,start
X-Google-Attributes: gid111d45,public
X-Google-ArrivalTime: 2004-03-19 20:09:38 PST
From: dont@spamme.com (Hal Brooks)
Newsgroups: borland.public.jbuilder.java.swing
Subject: Layout Question - BoxLayout and JTextAreas.  Example program included.
Date: Sat, 20 Mar 2004 04:02:40 GMT
Message-ID: <405bbe99.82703921@newsgroups.borland.com>
X-Newsreader: Forte Free Agent 1.21/32.243
NNTP-Posting-Host: 65.40.211.220
X-Trace: newsgroups.borland.com 1079755369 65.40.211.220 (19 Mar 2004 20:02:49 -0800)
Lines: 154
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail