SlideShare a Scribd company logo
TFD
This, class TFD, shows adding controls to the frame without a Layout
manager.
Chapter Four of The JFC Swing Tutorial Second Edition
by Kathy Walrath et. al. discusses using the layout manager.
(http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html)
At the end, the section on "Absolute Positioning" or "Dong without a
Layout Manager" Of course, I note that the authors chide us taht, "you
should
use a layout if at all possible." In XXXX, I explain the impetus for
my dealing with absolute positioning now.
There is a series of operations, a pattern, for each control when we
do absolute positioning. They consist of the steps listed below.
I give a template for each step.
(In the document TFBackground--I discuss why I am doing this series of
gist's and companion power points.)
In the templates, I use:
ControlType for the Java Class such as JTextField or JButton.
V for the instance of that type, which, of course, is a pointer,
such as in JButton One, I generalize this to be ControlType V.
Of course, for each template, I tell you where it is exemplified in the
example source file, TFD.java.
That example at the beginning displays
a button and a text box. (designated One and Three). However, when the
user clicks on the button, another Button and Textbox are created.
They are called Two and Four. Note that the actual allocation is
in the main program. The actionPerfomed for the button is in
the class I defined, L, from lines 17 to 42.
As I am teaching absolute positioning, we have to write:
T.getContentPane().setLayout(null);
That turns off the normal default layout manager. (Many years ago, it
took
me much headscratching to discover that I needed to do that, as the
buttons,
etc. would come up but sometimes do strange things or move around in
strange
ways.)
1) Declare the V, ControlType V.
You will see I have four controls, with V's of One, Two, Three and
Four.
They are declared as follows:
static JButton One; // this is the one always on the screen.
static JButton Two; // this will be created by the first
static JTextField Three;
static JTextField Four;
2) For each one of these, do the standard Java thing
to actually create a new operator. That is:
V = new ControlType();
See the lines 55, 59, 60, and 67.
Note: I create the control and set its size in the main method. One and
Three
will actually be made visible to the user there. Two and Four will be
made visible to the user when they pressed the button One. That will
be in the code for the actionPerformed in the actionListener, L.
3) set the size for each control. That is:
V .setSize (width, height);
Alternatively, one can use the form:
Dimension d-name;
d-name = new Dimension( width, height);
V.setSize(d-name);
That is good software-enginnering to have several buttons of the same
size--one only changes that size respectively. For example, in
ABFEAapp, I want one of several messages to all be at the same size (and
location). I coded this as follows, with MS being the size.
MS = new Dimension (1000,50);
V.setSize(MS);
where V is the textbox containing the error messages
4) set the position. As we are using "absolute positioning," this
simply is the x and y location. The template is
V.setLocation( x-location, y-location)
Remember that the y-location is given from the TOP of the window.
Thus, V.setLocation (35,27) positions the top left hand corner of V
35 pixels from the left of the window and 27 pixels from the top.
(One can say this puts this 35,27 from the upper-left hand corner of the
frame.)
You wil find the lines to position One, Two, Three and Four in lines:
57, 64, 62, 69, respectively.
(Sorry my example did not have these in order.)
5) Add the control to the frame:
Frame.getContentPane().add( V );
As mentioned above, we only add the controls Two and Four when the First
button
is pressed: thus, you will see the statement to add these in the
ActionListener , L. (lines 26 and 30, respectively).
One and Three are shown when the application is started. Those, thus,
appear in the main method at lines 65 and 66.
As mentioned above, the controls Two and Four are made visible,
that is, added to the window, a JFrame, T, iwhen the button is pressed.
That is, this code is in the L, actionPerformed. However, I found
that they wer enot seen unless we do the following:
T.repaint() (on line 38).
import java.util.*;import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import Debug.*;
public class TFD {
static JFrame T;
static JButton One; // this is the one always on the screen.
static JButton Two; // this will be created by the first
static JTextField Three;
static JTextField Four;
static PrintWriter F;
static boolean SA=false;;
static public class L implements ActionListener {
public void actionPerformed (ActionEvent e) {
Debug.P(" in action Performed");
F.println (" in action performed");F.flush();
String t;
t = Three.getText();
F.println ( "String in actino performed |"+t+"|");F.flush();
if (!SA) {
SA=true;
T.getContentPane().add(Two);
M m;
m = new M();
Two.addActionListener(m);
T.getContentPane().add(Four);
Debug.P("finished adding Two and Four");
}
else {
t = Four.getText();
F.println ("got stuff from second text box |"+"|");F.flush();
Debug.P("in else");
}
T.repaint();
Debug.P("leaving action performed");
}
}
static public class M implements ActionListener{
public void actionPerformed (ActionEvent e) {
Debug.P("clicked Two");
}
}
public static void main (String [] args) throws IOException {
F = new PrintWriter (new FileOutputStream ("TF.out"));
T = new JFrame ();
T.setSize(150,350);
T.getContentPane().setLayout(null);
One = new JButton ("One");
One.setSize (100,50);
One.setLocation (20,70);
T.getContentPane().add(One);
Two = new JButton();
Three = new JTextField();
Three.setSize(100,50);
Three.setLocation(20,200);
Two.setSize(100,50);
Two.setLocation(20,130);
T.getContentPane().add(One);
T.getContentPane().add(Three);
Four = new JTextField();
Four.setSize(100,50);
Four.setLocation(20,280);
L L;
L = new L();
One.addActionListener(L);
T.setVisible(true);
}
}
TP
This short program shows adding a JTextArea to a frame. I am trying to
put it at the bottom of the window (I am turning off the layout manager,
using absolute positioning).
Since the height of the frame is in FH and the height of the JTextArea is
in TH,
positioning it with
T.setLocation (0,FH-TH) should put the text area at the bottom of the
screen with its bottom edge coincident with the bottom edge ofthe window.
It does not!
The problem is the top part of the window put in by Microsoft Windows.
When I add the line
Fr.setUndecorated(true);
the item is positioned correctly.
I looked for a command to get the height of that part, put in by Microsoft
Windows so I could allow for it. Found it as the call getInsets
( a member of the Component class). That worked fine.
Example: (f is the frame in which I wish to put the component TA).
(this corectly puts the TA at the bottom cnter of the frame with TA's
bottom
border properly flush against the bottom of the frame!)
Insets I;
I = f.getInsets();
int height=TA.getHeight();
int width = TA.getWidth();
int ypos = MyHeight - height - I.top-I.bottom;
MyWidth = MyWidth - I.left - I.right;
int xpos = I.left+MyWidth/2 - width /2;
TA.setLocation(xpos,ypos);
import java.io.*;import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TP {
static int FH = 200; // height of containing window
static int FW = 300; // width of containging window
static int TW = 75; // width of component
static int TH = 32; // height of component
static JFrame Fr; // containing window
public static void main (String[] args) {
Fr = new JFrame();
Fr.setLayout(null);
Fr.setSize(FW,FH);
JTextArea T;
T = new JTextArea();
javax.swing.border.Border B;
B = BorderFactory.createLineBorder(Color.red,3);
T.setBorder(B);
T.setSize(TW,TH);
T.setLocation(0,FH-TH);
Fr.add(T);
Fr.repaint();
Fr.setVisible(true);
}
}
T0
T0.java shows creating multi-line text boxes using both the
Abstract Window Toolkit (AWT) TextArea
and
Java Swing JTextArea.
As you know, AWT came with the original Java. Java Swing was built on top
of it. One can recognize the classes created by Java Swing--they begin
with
the letter J.
Often, the Java Swing has a version of each class
in AWT, but with a little gloss upon it. This unit (T0) covers and shows
TextArea and JTextArea.
In the case of AWT, the TextArea includes scrolling functionality.
That is, if one puts more text into the
TextArea than can be shown in the amount of space given to it with
setSize method, scroll bars will appear and function appropriately, In
Java Swing, one has to put the JTextArea in a JScrollPane if one wants to
have it scroll when this happens. (This is more of a difference than
one usually sees between the AWT class and the corresponding Java Swing
class.)
Our program creates one of each--I follow the steps and templates in
TFD unit. The routine stuff, I simply show the template. The lines
for AWT are in the left-hand column. The lines for Java Swing are in
the right-hand column. I put the line numbers for T0.java in parentheses.
How we get the text.
In my application, I wish to support receiving and displaying the text in
one of three ways:
An Array of Strings.
A big long String containing carriage returns.
Passing the name (or path name) of a file containing the text to be
displayed
A Collection of Strings. (See Chapter 21 on Collections in Java in
The Java Programming Language , Fourth Edition.)
For this example, I just show the first (Array of String) The example
input
is in JT on lines 79 to 84. Obviously, the extension of this to the other
three is straightforward, but I show it in the set XXX.
Step One:
ControlType V
TextArea TA (151) JTextArea RT (136)
JScrollPane J; (149)
Remember that in using the JSwing classes, one has to put the text area
within a JScrollPane. This is to handle the case when the text is too big
to fit in the space we care to allot on the screen for it.
Step Two:
V = new ControlType()
TA = new TextArea (B.toString(), RT = new JTextArea(NORows,MaxLL);
NoRows,NoCols);
Assume one has a Dimension D giving the space we care to allot to display
our text.
For using Java Swing, we need to find out how big the text is, assuming
we had a screen big enough to hold it. I call that measuring the text.
We assign that as the size of RT. Then, we set the JScrollPane to size D.
It is much a simpler for us programmers when we use
the AWT TextArea. We simply setSize TextArea to D. Any necessary
measuring of the text seems to be done internally by the TextArea.
Measuring the Text.
For the JTextArea (Java Swing), we have to find out how big the text would
be if we were to display it in all its glory. That is how big would the
text be if we were to allot enough space on the screen so the user could
see all of it at once (assuming that the display hardware were big
enough).
I call this "measuring the text."
We loop through the lines of the text. We get the length of each line,
both in pixels and in characters. We take the maximum of each.
This is a loop such as the following (lines 137 to 148):
See the JT discussion below.
for (i=0;i<JT.length;i++){
String L = JT[i]; // line that we are checking
Rectangle2D WR = SFM.getStringBounds (L,C);
int W= (int)WR.getWidth();
Debug.P(" processing line |"+L+"| position "+i+ " width is: "+W);
if (W>maxLW){
maxLW = W;
}
if (L.length() > maxLL) {
maxLL = L.length();
}
}
Remember that maxLW is the size of the JTextArea in pixels--that gets
passed
to its setSize call. maxLL is the length of the longest line in
characters!
We passed that to the constructor.
(That is known as the number of "columns" and there is a
getColumns method to get this value from the JTextArea--should one lose
track
of it.)
Some important things that I found the hard way.
Be sure that SFM is gotten by doing the getFontMetrics that one actually
is using on the JTextArea. We set that font with a command such as
RT.setFont(SF) or TA.setFont(TA). (lines 128 or 163).
Expletive-deleting this caused ugly space to appear to the right and
bottom of
our text as I scrolled it!
Also, C is gotten by using getGraphics() on the component in which we
are placing the text. I tried C = f.getGraphics() (line 109)
where f was simply the whole frame for our Windows program.
Sometimes, that seemed to work OK; sometimes it seemed to
matter that I actually got the context of the TextArea after I put it
on the frame.
Lastly, we get measure the height. That is easier as each line is
the same height. We get that by using the getHeight method of
the FontMetrics. It is important to realize that "This is the distance
between the baselines of adjacent lines of text." I call your attention
to the Java API documentation for FontMetrics.getHeight() (I took
the quote in the previous sentence from that documentation.)
We simply multipy that value by the number of lines that we include
in the text. See lines 149 to 151.
Glomming or Concatenating the text.
As mentioned above, I want my class to handle receiving the text in all
kinds of ways. In this set, I just show receiving the text as an array
of strings. That is, in T0.java, I declared (lines 79 to 84):
static String [] JT = new String [] {
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True",
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True",
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True",
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True"
};
Step Three:
For the TextArea, we simply apply the setSize method to it.
However, when using the JTextArea, as mentioned above, we put it in
a JScrollPane.
However, as mentioned, the size that is for the JTextArea is that of the
text in all its glory.
These are the variables maxLW and HT found in
Measuring the text. (lines 137 to 148 and 149)
Then, we simply write RT.setSize(maxLW,H);
The size on the screen is given to the JScrollPane itself. We have to put
the JTextArea inside the JScrollBar(). One should be able to do this
with the JScrollPane constructor:
JScrollPane J;
J = new JScrollPane(RT);
but I had better luck doing it piece-by-piece explicitly. Besides, it
helps
one understand what happens.
On lines 129 to 136 see something like the following:
JScrollPane J;
J = new JScrollPane();
J.setSize(100,50);
J.setLocation(50,50);
JViewport V;
V = (JViewport)J.getViewport();
V.add(RT);
At the beginning of the Swing API documetnation for the class JScrollPane,
you will see the discussionof the JViewPort which contains that which is
to
be scrolled. One can explicitly add the control representing that which
we are to scroll. In this case, that is the JTextArea RT.
Step Four
Of course, we just give the TextArea the size which it has to display
the text--which will usually be smaller than is needed to display all
that it will display. The TextArea will provide scroll bars and scrolling
that is needed:
TA.setSize(100,50);
TA.setLocation(50,200);
One thing I learned the hard way is that we need to explicitly set the
Font and color for the JTextArea. That is (lines 127 to 128):
RT.setForeground(Color.black);
RT.setFont(SF);
Remember, that we give the JScrollPane the explicit location
and size where we want them to appear on the screen for our user!
J.setLocation(50,50);
Step Five:
Remember that we add the TextArea directly to the screen; we add
the JScrollBar (containing the JTextArea) to the screen:
f.getContentPane().add(TA);
f.getContentPane().add(J);
(Lines 164 and 165)
In T1, I show creating a class to control these.
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Font;
public class T0{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*<P>
* It is irrelevant to that which these examples are trying to teach.
*/
static class Debug {
public PrintWriter D;
Debug (){
try {
D = new PrintWriter (new FileOutputStream("T0.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
public void P(String s) {
D.println (s);D.flush();
}
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, call {@code toString()} on the {@code Object} but shorten
* overlong results -- also protects from Null Exception if object is
* null.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.toString();
if (RT.length() > 50) {
return RT.substring(0,50);
}
else {
return RT;
}
}
else {
return "null";
}
} // end SS method
} // end class Debug
static Debug Debug;
static JFrame f;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* The {@code Graphics} for the frame-- which we will need
* to get an accurate width for a line as wit will be displayed.
*/
static Graphics C;
/**
* the string on which we will test; the string that we will put in the
* text area;
*/
static String [] JT = new String [] {
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True",
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True",
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True",
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True"
};
/**
* The maximum length of a line, based upon the number of characters
*/
static int maxLL=0;
/**
* The maximum length of a line, based upon pixels.
*/
static int maxLW =0;
/**
* We will put the text area inside this to get it to scroll.
*/
public static void main (String [] args) throws IOException {
Debug = new Debug();
int i;
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
f.setVisible(true);
f.validate();
C = f.getGraphics();
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
v
// determine maximum width and height of the text area
// based on putting in the text JT
JTextArea RT;
RT = new JTextArea();
// assemble text area
StringBuffer B;
B = new StringBuffer();
for (i=0;i<JT.length;i++){
B.append(JT[i]);
if (i!=JT.length-1){B.append ('n');}
}
RT.setForeground(Color.black);
RT.setFont(SF);
RT.setText(B.toString());
JScrollPane J;
J = new JScrollPane();
J.setSize(100,50);
J.setLocation(50,50);
JViewport V;
V = (JViewport)J.getViewport();
V.add(RT);
for (i=0;i<JT.length;i++){
String L = JT[i]; // line that we are checking
Rectangle2D WR = SFM.getStringBounds (L,C);
int W= (int)WR.getWidth();
Debug.P(" processing line |"+L+"| position "+i+ " width is: "+W);
if (W>maxLW){
maxLW = W;
}
if (L.length() > maxLL) {
maxLL = L.length();
}
}
int NORows = JT.length;
int height = SFM.getHeight(); // height of text area in pixels
int H = NORows*height;
Debug.P(" after loop max LW is "+maxLW + " pixels; max LL = "+maxLL+ "
characters ");
RT.setSize(maxLW,H);
Debug.P (" RT 's text is |"+RT.getText()+"| its font " +RT.getFont() + "
its color "+RT.getForeground() + " checking that it is in the view port
"+V.getComponent(0) + " number of rows in RT is " + RT.getRows() + "
number of columns in RT is " + RT.getColumns());
Debug.P(" the text sent to text area is |"+B.toString()+"|",false);
Debug.P(" after measuring text ("+maxLW+","+H+")");
TextArea TA;
TA = new TextArea (B.toString(),NORows,maxLL);
Debug.P(" Constructing Text Area with
|"+B.toString()+"|,"+NORows+","+maxLL+")");
TA.setSize(100,50);
TA.setLocation(50,200);
TA.setFont(SF);
f.getContentPane().add(J);
f.getContentPane().add(TA);
f.validate();
f.repaint();
} // end of main method
} //end of class
T1
In T1, we create a class SWA to handle much of these. I will be building
on these to add more wonderful complications :-) in the T2 and T3 series.
Be sure to see the Unified Model Language (UML) diagram in T1.pptx.
It shows the relationships
between SWA, the outer Frame, and, right now, the single text area on
that Frame!
Now, please remember from your understanding of Java GUI programming
(that is the AWT package and the Java Swing package) that one can
associate a ComponentListener to a main window of an application.
It detects when the user resizes the window by dragging the sides.
Conveniently, it also detects when the Component first comes up.
SWA implements that ComponentListener interface!
(There are four methods in the interface.
That means that SWA will have a definition for each of these four methods.
However, all that we need to do, all the action for this series,
I put in the method I define, Adjust. All four of those methods simply
call Adjust!
All four of those methods have a single argument, a ComponentEvent.
(This
is fairly typical for methods in listeners and adapters in Java
Swing/AWT.)
From that, we get the Component that was resized or shown. This is the
OUTER window!
(By the way, I do check that the Component is a Resized or Shown--if it
was one of the other two things (hidden or moved), we do nothing.)
In order to proceed, we need to know the new width and height of the
OUTER window!
(Or the initial height and width if this window is the first time shown).
I get them in lines 262 to 264.
I put them in global variables, MyHeight and MyWidth.
In this example, there is a single component for which the SWA is
responsible. That is indicated by the connection mc (see that UML
diagram).
The T2 series will have multiple things managed by each SWA instance.
The T3 series will have multiple SWA instances, one for each Frame (outer
window) in the application program.
In this example, T1.java, we only support centering the item in the lower
left-hand corner of its outer window. That item's size
is given bythe variables height and width. CSP sets these in the
SWA instance.
To adjust the item properly, we use the formula:
xpos = MyWidth / 2 – width/2;
Then, we set the location:
mc.setLocation(xpos,ypos);
(The ypos is computed from the vertical room in the window - the height
of its object. Remember that in Java Swing, as in most graphical
systems,
the y axis goes downward with zero representing the top of the window.
In fact, we have to allow for what are called "Decorations." In
particular,
the bar at the top of the window, so familiar that you probably that you
don't think about it. It is where the little button to minimize the
window,
make the window go to the entire size of your screen or exit the
application
with an X are. (We can turn these off with setDecorations(false)'
Unfortunately, that also means that we cannot resize the window, the whole
point of this exercise.)
The Java AWT Frame class implements the method getInsets(). That enables
us
to find out how much space is taken up by these decorations. (There is a
smaller amount of space taken up by borders on the left, right and bottom
sides of a typical window.)
See, in particular lines 266, 270.
Also, shoudl the user make the screen so small that we cannot display
the text area completely, we make the item smaller. Note that the
SWA class variables height and width don't change when this occurs.
The result is that the component size snaps right back when the user makes
the window big enough to contain the component completely.
Note that T1.java's implementation of SWA only allows for items to be
centered. (Note that the whole series only provides for items on the
bottom of the window.)
See T1b.java, where we pass a position to addTextArea when we create
the text area. A zero value means that the item should be centered,
as in T1.java. A positive value is the number of pixels from the left-
hand
corner. A negative value allows one to define that the item should
be so many pixels from the right-hand margin. That is, a -1 right-
justifies
the smaller text area or component within the main screen.
In T1B.java, see line 328 for the calculation in Adjust
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T1{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T1.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, wil have to get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame},
the
* caller will have to
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/*
* This is the component that we are adjusting and displaying here
* A later version will do arrays of these things.
*/
Component mc;
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
*/
void addTextArea (Component JTA){
this.mc = JTA;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
if (Width < width){
width = Width;
}
if (Height < height) {
height = Height;
}
J.setSize(width,height);
JViewport V;
V = (JViewport)J.getViewport();
V.add(JTA);
mc = J;
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (Dx) {
}
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
if (mc!=null){
Component w = e.getComponent();
int MyHeight=w.getHeight();
int MyWidth = w.getWidth();
Insets I;
I = F.getInsets();
int height=mc.getHeight();
int width = mc.getWidth();
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
boolean flag=false;// if the component's size does not fit in the window,
// we set this true, so we change the size of the
// textbox to fit.
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag=true;
}
MyWidth = MyWidth - I.left - I.right;
int xpos;
if (width <MyWidth) {
xpos = I.left+MyWidth/2 - width /2;
}
else {
xpos = I.left;
width = MyWidth;
flag = true;
}
mc.setLocation(xpos,ypos);
if (flag) { mc.setSize(width,height);}
} // there really is a component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String JT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
public static void main (String [] args) throws IOException {
Debug = new Debu();
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
SWA wa = new SWA();
wa.Dx = true;
wa.AM(f.getContentPane(),f);
JTextArea JTA;
JScrollPane J;
JTA = wa.CTA(JT);
J = wa.CSP(JTA,275,100);
wa.addTextArea(J);
f.setVisible(true);
f.repaint();
} // end of main
} //end of program (class)
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T1A{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T1.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, wil have to get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame},
the
* caller will have to
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/**
* This is the component that we are adjusting and displaying here
* A later version will do arrays of these things.
*/
Component mc;
/**
* This is the preferred width of the component added, assuming there is
* enough room for it.
*/
int mcw;
/**
* This is the preferred height of the component added, assuming there is
* enough room for it.
*/
int mch;
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
*/
void addTextArea (Component JTA){
this.mc = JTA;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
if (Width < width){
width = Width;
}
if (Height < height) {
height = Height;
}
J.setSize(width,height);
JViewport V;
V = (JViewport)J.getViewport();
V.add(JTA);
mc = J;
mcw = width;
mch = height;
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (Dx) {
}
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
if (mc!=null){
Component w = e.getComponent();
int MyHeight=w.getHeight();
int MyWidth = w.getWidth();
Insets I;
I = F.getInsets();
int height=mch;
int width = mcw;
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
boolean flag=false;// if the component's size does not fit in the window,
// we set this true, so we change the size of the
// textbox to fit.
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag=true;
}
MyWidth = MyWidth - I.left - I.right;
int xpos;
if (width <MyWidth) {
xpos = I.left+MyWidth/2 - width /2;
}
else {
xpos = I.left;
width = MyWidth;
flag = true;
}
mc.setLocation(xpos,ypos);
if (flag) { mc.setSize(width,height);}
} // there really is a component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String JT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
public static void main (String [] args) throws IOException {
Debug = new Debu();
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
SWA wa = new SWA();
wa.Dx = true;
wa.AM(f.getContentPane(),f);
JTextArea JTA;
JScrollPane J;
JTA = wa.CTA(JT);
J = wa.CSP(JTA,275,100);
wa.addTextArea(J);
f.setVisible(true);
f.repaint();
} // end of main
} //end of program (class)
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T1B{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T1.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, wil have to get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame},
the
* caller will have to
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/**
* This is the component that we are adjusting and displaying here
* A later version will do arrays of these things.
*/
Component mc;
/**
* This is the preferred width of the component added, assuming there is
* enough room for it.
*/
int mcw;
/**
* This is the preferred height of the component added, assuming there is
* enough room for it.
*/
int mch;
/**
* position to put {@link mc} relative to the containing window (@link
MC}
* <UL><LI>
* If positive, will be the number of pixels of right of the left-hand
side
* of {@link MC}
* <LI>
* If negative, will give the number of pixels to the left of the right-
hand
* edge of the containing window (@link MC}. That is, the {@code
Component}
* will be kept with a certain right margin.
* <LI>
* If zero, will be centered like in {@code T1A.java}.
* </UL>
*/
int position;
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
* @param position <UL><LI> position is positive, that is the number of
pixels from the lower=left <LI>position is negative, then this will give
the number of pixels from the right<LI>if position is zero, then it will
be centered</UL>--note, it is impossible to align this precisely with the
lower left hand corner. Simply have it one pixel just to the right of
that.
*/
void addTextArea (Component JTA,int position){
this.position = position;
this.mc = JTA;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
*/
void addTextArea(Component JTA) {
addTextArea(JTA,0);
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
if (Width < width){
width = Width;
}
if (Height < height) {
height = Height;
}
J.setSize(width,height);
JViewport V;
V = (JViewport)J.getViewport();
V.add(JTA);
mc = J;
mcw = width;
mch = height;
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (Dx) {
}
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
if (mc!=null){
Component w = e.getComponent();
int MyHeight=w.getHeight();
int MyWidth = w.getWidth();
Insets I;
I = F.getInsets();
int height=mch;
int width = mcw;
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
boolean flag=false;// if the component's size does not fit in the window,
// we set this true, so we change the size of the
// textbox to fit.
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag=true;
}
int myWidth; // my real width after subtracting any insets
myWidth = MyWidth - I.left - I.right;
int xpos;
if (width <MyWidth) {
xpos=0;
if (position ==0){
xpos = I.left+MyWidth/2 - width /2;
}
else
if (position > 0) {
xpos = I.left + position;
}
else
if (position <0) {
xpos = -I.right + myWidth - width + position;
}
}
else {
xpos = I.left;
width = MyWidth;
flag = true;
}
mc.setLocation(xpos,ypos);
if (flag) { mc.setSize(width,height);}
} // there really is a component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String JT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
public static void main (String [] args) throws IOException {
Debug = new Debu();
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
SWA wa = new SWA();
wa.Dx = true;
wa.AM(f.getContentPane(),f);
JTextArea JTA;
JScrollPane J;
JTA = wa.CTA(JT);
J = wa.CSP(JTA,275,100);
wa.addTextArea(J,-11);
f.setVisible(true);
f.repaint();
} // end of main
} //end of program (class)
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T1T{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debug {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debug (){
try {
D = new PrintWriter (new FileOutputStream("T1T.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame [] f;
/**
* number of frames on which we will test
*/
static int NOF = 3;
static Debug Debug;
/**
* We will use this font throughout this example.
*/
static Font []SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics [] SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, wil have to get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame},
the
* caller will have to
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/*
* This is the component that we are adjusting and displaying here
* A later version will do arrays of these things.
*/
Component mc;
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
*/
void addTextArea (Component JTA){
this.mc = JTA;
if (MC!=null) {
MC.add(JTA);
}
if (Dx) {Debug.P(" returning from add Text Area, added component
"+Debug.SS(JTA)+ " TO " + Debug.SS(MC)+ " ",false);}
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
Insets I = J.getInsets();
if (Width < width){
width = Width;
}
if (Height < height) {
height = Height;
}
JViewport V;
if (Dx) {Debug.P( " returning scroll Pane "+Debug.SS(J) +
" new location ("+width+","+height+") ",false);
J.setSize(width,height);
mc = J;
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD, Font SF,FontMetrics SFM){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
if (mc!=null){
Component c = e.getComponent();
if (Dx) {Debug.P (" Resizing the frame (or outer container) " +
Debug.SS(c),false);}
int MyHeight=c.getHeight();
int MyWidth = c.getWidth();
if (Dx) {Debug.P (" My Height " + MyHeight + " My Width " + MyWidth + "
",false);}
Insets I;
I = F.getInsets();
int height=mc.getHeight();
int width = mc.getWidth();
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
if (Dx){Debug.P (" of component being adjusted , height "+ height + "
width "+ width + " vertical Room " + room + " I.top "+I.top + " I.bottom
"+I.bottom + " ",false);}
boolean flag=false;// if the component's size does not fit in the window,
// we set this true, so we change the size of the
// textbox to fit.
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag=true;
}
if (Dx){Debug.P ( " room " + room + " height " + height + " ypos "
+ypos,false);}
MyWidth = MyWidth - I.left - I.right;
if (Dx){Debug. P (" new My Width (or horizontal room ) " + MyWidth + "
I.left "+I.left + " I.right "+I.right,false);}
int xpos;
if (width <MyWidth) {
xpos = I.left+MyWidth/2 - width /2;
}
else {
xpos = I.left;
width = MyWidth;
flag = true;
}
if (Dx){Debug.P(" new xpos " + xpos + " ypos " + ypos );}
mc.setLocation(xpos,ypos);
JScrollPane J=null;
try {
J = (JScrollPane) mc;
}
catch (ClassCastException cce) {
Debug.P (" class cast exception encountered on converting to JScrollPane
");
}
JViewport V;
V=null;
// if the text area is now smaller than the scroll bar space, we will
change it
// to be the scroll base space -- after allowing for the width of the
vertical
// scroll bar and the height of the horizontal scroll bar.
if (J!=null){
V = (JViewport)J.getViewport();
JScrollBar VSB = J.getVerticalScrollBar();
int VSBw=0;
if (VSB !=null) {
VSBw = VSB.getWidth();
}
JScrollBar HSB = J.getHorizontalScrollBar();
int HSBh = 0;
if (HSB !=null) {
HSBh = HSB.getHeight();
}
if (Dx){
Debug.P (" scroll bar width: "+width +
" height " + height + " vertical scroll bar "+Debug.SS (VSB) +
" horizontal scroll bar " + Debug.SS (HSB) +
" vertical scroll bar width "+VSBw + " horizontal scroll bar height " +
HSBh
+
"("+width+"+"+I.left+"+"+I.right+"+"+VSBw+","+
height+"+"+I.top+"+"+I.bottom+"+"+HSBh+") ",false);
}
int Cc = V.getComponentCount();
if (Cc == 1){
Component C = V.getComponent(0);
int H,W,h,w;
// if the text area is now smaller than the scroll space, we will change
it
// to be the scroll base space -- after allowing for the width of the
vertical
// scroll bar and the height of the horizontal scroll bar.
H = C.getHeight() ;
W = C.getWidth();
if (Dx){
Debug.P (" got the text area or whatever was inside the Component:
"+Debug.SS(C)+ " H is " + H + " W is "+ W + " ",false);
}
h= height - HSBh;
w = width - VSBw;
boolean Flag;
Flag = false;
if (Dx) {
Debug.P (" h is " + h + " w " + w + " ",false);
}
if (H < h) {
Flag = true;
h = H;
}
if (w > W) {
Flag = true;
w = W;
}
if (flag){
C.setSize(W+VSBw,H+HSBh);
if (Dx) {
Debug.P (" resetting size of text area to ("+w + ","+h + ")
",false);
}
}
} // C in getting component of the scroll pane finds exactly one
} // J in converting component to scroll pane NOT NULL
if (flag) { mc.setSize(width,height);}
} // there really is a component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String JT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
static String ST = "ONnTWOnTHREE";
public static void main (String [] args) throws IOException {
Debug = new Debug();
f = new JFrame[NOF];
SFM = new FontMetrics[NOF];
SF = new Font[NOF];
SWA []wa;
wa = new SWA [NOF];
JTextArea[] JTA;
JTA = new JTextArea[NOF];
JScrollPane []J;
J = new JScrollPane[NOF];
int i;
for (i=0;i<NOF;i++) {
f[i] = new JFrame();
f[i].setSize(400,500);
f[i].setLayout(null);
SF[i] = new Font ("Arial",Font.BOLD,24);
SFM[i] = f[i].getFontMetrics(SF[i]);
wa[i] = new SWA();
wa[i].Dx = true;
wa[i].AM(f[i].getContentPane(),f[i]);
switch (i){
case 0:
JTA[i] = wa[i].CTA(JT,SF[i],SFM[i]);
J[i] = wa[i].CSP(JTA[i],75,100);
break;
case 1:
JTA[i] = wa[i].CTA(ST,SF[i],SFM[i]);
J[i] = wa[i].CSP(JTA[i],300,300);
break;
case 2:
JTA[i] = wa[i].CTA(ST,SF[i],SFM[i]);
J [i] = wa[i].CSP(JTA[i],500,300);
break;
default:
System.err.println (" should not be here , wrong case in switchn");
System.exit(-100);
}
Debug.P(" adding component " + Debug.SS(J[i]) + " to frame # "+i+ "
"+Debug.SS(f[i]) + " Scroll panel is "+Debug.SS(J[i])+ " Text Area is
"+Debug.SS(JTA[i])+ " ",false);
wa[i].addTextArea(J[i]);
Debug.P ("returned from wa addTextArea ");
f[i].setVisible(true);
f[i].repaint();
} // loop to do all (NOF) frames
} // end of main
} //end of program (class)
T2
In T2.java, I promised you that we would allow each instance of the SWA
class to manage several items or text areas. (Note, here we are still
only
supporting one outer window; that is, we only have one instance of SWA).
I have four parallel arrays:
mc - the text area or component within the outer frame
mcw - its width
mch - its height
position - (*)
Thus, assume we call AddTextArea three times. The last time, the
last time, we call it with a component or JScrollPane 789 with
a position of -11. (See T2T.java where we do call it such.)
Then mc[2] will point to JScrollPane 789. position[2] will be -11.
And mcw[2] and mch[2] will give the preferred width and height
for component 789. (The latter two values are copied from the
JTextArea or component being added in line 184 of T2T.java.
(*) Recall that in T1B.java, we introduced passing zero to have the item
centered horizontally, a positive number to be left justified or justified
against the left-hand margin, and a negative number to have it right-
justified
or given a position relative to the right-hand border of the outer frame.
The Adjust subroutine follows that in the T1 series--it just loops
through all the items in those four parallel arrays. Thus, you will
see height=mch[i] and width=mcw[i] and then height and width are used
in the remainder of Adjust, copied from the T1 series.
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T2{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T1.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, will have to
get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the
* caller will have to:
* <BR>
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/**
* This array contains the component that we are
* adjusting and displaying here .
*/
Component [] mc;
/**
* This tells how many components we have to which keep track.
* Note, there are parallel arrays {@link mc}, {@link mcw}, {@link
position},
* and {@link mch}
**/
int CC;
/**
* This is the preferred width of the component added, assuming there is
* enough room for it.
*/
int [] mcw;
/**
* This is the preferred height of the component added, assuming there is
* enough room for it.
*/
int [] mch;
/**
* position to put {@link mc} relative to the containing window (@link
MC}
* <UL><LI>
* If positive, will be the number of pixels of right of the left-hand
side
* of {@link MC}
* <LI>
* If negative, will give the number of pixels to the left of the right-
hand
* edge of the containing window (@link MC}. That is, the {@code
Component}
* will be kept with a certain right margin.
* <LI>
* If zero, will be centered like in {@code T1A.java}.
* </UL>
*/
int []position;
/**
* maximum number of components we allow
*/
final int MNC=1000;
SWA () {
mc = new Component[MNC];
mcw = new int[MNC];
mch = new int [MNC];
position = new int [ MNC];
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
* @param position <UL><LI> position is positive, that is the number of
pixels from the lower=left <LI>position is negative, then this will give
the number of pixels from the right<LI>if position is zero, then it will
be centered</UL>--note, it is impossible to align this precisely with the
lower left hand corner. Simply have it one pixel just to the right of
that.
*/
void addTextArea (Component JTA,int position){
this.position[CC] = position;
this.mc[CC] = JTA;
this.mcw[CC] = JTA.getWidth();
this.mch[CC] = JTA.getHeight();
CC++;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
*/
void addTextArea(Component JTA) {
addTextArea(JTA,0);
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
if (Width < width){
width = Width;
}
if (Height < height) {
height = Height;
}
J.setSize(width,height);
JViewport V;
V = (JViewport)J.getViewport();
V.add(JTA);
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (Dx) {
}
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
Component w = e.getComponent();
int MyHeight=w.getHeight();
int MyWidth = w.getWidth();
Insets I;
I = F.getInsets();
int height;
int width;
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
boolean []flag;
flag = new boolean[CC];
int i; // position within arrays mc,position,mch,mcw;
// tells which component is being adjusted
for ( i = 0; i < CC; i++) {
flag[i]=false;// if the component's size does not fit in the window,
// if we set this true, so we change the size of the
// textbox to fit.
height = mch[i];
width = mcw[i];
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag[i]=true;
}
int myWidth; // my real width after subtracting any insets
myWidth = MyWidth - I.left - I.right;
int xpos;
if (width <MyWidth) {
xpos=0;
if (position[i] ==0){
xpos = I.left+MyWidth/2 - width /2;
}
else
if (position[i] > 0) {
xpos = I.left + position[i];
}
else
if (position[i]<0) {
xpos = -I.right + myWidth - width + position[i];
}
}
else {
xpos = I.left;
width = MyWidth;
flag[i] = true;
}
mc[i].setLocation(xpos,ypos);
if (flag[i]) { mc[i].setSize(width,height);}
} // for each component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String JT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
public static void main (String [] args) throws IOException {
Debug = new Debu();
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
SWA wa = new SWA();
wa.Dx = true;
wa.AM(f.getContentPane(),f);
JTextArea JTA;
JScrollPane J;
JTA = wa.CTA(JT);
J = wa.CSP(JTA,275,100);
wa.addTextArea(J,0);
f.setVisible(true);
f.repaint();
} // end of main
} //end of program (class)
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T2T{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T1.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, will have to
get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the
* caller will have to:
* <BR>
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/**
* This array contains the component that we are
* adjusting and displaying here .
*/
Component [] mc;
/**
* This tells how many components we have to which keep track.
* Note, there are parallel arrays {@link mc}, {@link mcw}, {@link
position},
* and {@link mch}
**/
int CC;
/**
* This is the preferred width of the component added, assuming there is
* enough room for it.
*/
int [] mcw;
/**
* This is the preferred height of the component added, assuming there is
* enough room for it.
*/
int [] mch;
/**
* position to put {@link mc} relative to the containing window (@link
MC}
* <UL><LI>
* If positive, will be the number of pixels of right of the left-hand
side
* of {@link MC}
* <LI>
* If negative, will give the number of pixels to the left of the right-
hand
* edge of the containing window (@link MC}. That is, the {@code
Component}
* will be kept with a certain right margin.
* <LI>
* If zero, will be centered like in {@code T1A.java}.
* </UL>
*/
int []position;
/**
* maximum number of components we allow
*/
final int MNC=1000;
SWA () {
mc = new Component[MNC];
mcw = new int[MNC];
mch = new int [MNC];
position = new int [ MNC];
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
* @param position <UL><LI> position is positive, that is the number of
pixels from the lower=left <LI>position is negative, then this will give
the number of pixels from the right<LI>if position is zero, then it will
be centered</UL>--note, it is impossible to align this precisely with the
lower left hand corner. Simply have it one pixel just to the right of
that.
*/
void addTextArea (Component JTA,int position){
this.position[CC] = position;
this.mc[CC] = JTA;
this.mcw[CC] = JTA.getWidth();
this.mch[CC] = JTA.getHeight();
CC++;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
*/
void addTextArea(Component JTA) {
addTextArea(JTA,0);
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
*/
JScrollPane CSP (Component JTA) {
return CSP ( JTA, 200,50);
}
/**
* Take the indicated {@code Component} {@code JTA} and put it on
* a {@code JScrollPane} on the associated {@link Frame}. Uses the
* indicated size. Except if the {@code JTA} is smaller than that size,
* we make the scrollbar fit the text. In other words, if the text is
shorter
* or narrower than the programmer expects, we use the width or height
that
* we actually need rather than what the programmer specified.
* Programmer is responsible for setting its location.
*/
JScrollPane CSP(Component JTA, int width, int height){
JScrollPane J;
J = new JScrollPane();
int Width = JTA.getWidth();
int Height = JTA.getHeight();
if (Width < width){
width = Width+31;
}
if (Height < height) {
height = Height;
}
J.setSize(width,height);
JViewport V;
V = (JViewport)J.getViewport();
V.add(JTA);
return J;
}
/**
* Create a {@code JTextArea} from the {@code String WTD} , which
presumably
* has carriage returns separating the lines or rows in the {@code
TextArea}
* @param WTD stick this content in the return {@code TextArea}
* @returns a {@code TextArea} set with the appropriate number of rows
and columns as well as the width and height in pixels.
* <P>
* To better measure the text
* (see companion files {@code T0} and {@code T1} or {@code T0.pptx}
* or {@code T1.pptx}, we will add this, at least temporarily to the
* {@code Container} with which this is associated. That assume that
this was
* associated with one; we tell by seeing if {@code MC} is not {@code
null}.
*/
public JTextArea CTA ( String WTD){
int NoRows;
NoRows = 0;
char c; int i; int W /* width */; // temps
int LastPos=0;
int maxLL = 0; // maximum length of a line based on the number of
characters
int maxLW = 0; // maximum length of a line based upon the font
// (in a unit like pixels)
int NumberChars;
JTextArea RT; // text area to be returned. (This is an abbreviation for
// Return This.
RT = new JTextArea();
RT.setFont(SF);
RT.setForeground(Color.black);
Graphics C;
if (MC !=null) {
MC.add(RT);
}
C = RT.getGraphics();
for (i=0 ; i < WTD.length();i++) {
c = WTD.charAt(i);
if (c== 'n') {
NoRows++;
NumberChars = i-LastPos;
if (NumberChars > maxLL) {
maxLL = NumberChars;
}
String L;
if (LastPos==0) {
L = WTD.substring(0,i);
}
else {
L = WTD.substring(LastPos+1,i);
}
C = RT.getGraphics();
Rectangle2D WR = SFM.getStringBounds(L,C);
W = (int)WR.getWidth();
if (Dx) {
}
if (W > maxLW) {
maxLW = W;
}
LastPos=i;
if (Dx) {
}
} // we have a new line, separating actual lines in the text area.
} // loop through all characters in the String to put in the text area.
int height = SFM.getHeight();
int H = NoRows*height; // height that we will make our JTextArea to be
RT.setSize(maxLW,H);
RT.setText(WTD);
return RT;
}
/**
* Put this text area (or other component) at the bottom center of the
frame
* {@link F} to whom I belong. <P>Later versions of this class will give
* more control over multiple components.
* This is called whenever {@link F} has an event associated with
* {@code ComponentListener} interface.
*/
private void Adjust (ComponentEvent e) {
int eid=e.getID();
if (eid == ComponentEvent.COMPONENT_RESIZED || eid ==
ComponentEvent.COMPONENT_SHOWN){
Component w = e.getComponent();
int MyHeight=w.getHeight();
int MyWidth = w.getWidth();
Insets I;
I = F.getInsets();
int height;
int width;
int ypos;
int room = MyHeight-I.top-I.bottom; // how much room there is in the
window;
boolean []flag;
flag = new boolean[CC];
int i; // position within arrays mc,position,mch,mcw;
// tells which component is being adjusted
for ( i = 0; i < CC; i++) {
flag[i]=false;// if the component's size does not fit in the window,
// if we set this true, so we change the size of the
// textbox to fit.
height = mch[i];
width = mcw[i];
if (room>height){
ypos = MyHeight - height - I.top-I.bottom;
}
else {
ypos = I.top;
height = room;
flag[i]=true;
}
int myWidth; // my real width after subtracting any insets
myWidth = MyWidth - I.left - I.right;
int xpos;
if (width <MyWidth) {
xpos=0;
if (position[i] ==0){
xpos = I.left+MyWidth/2 - width /2;
}
else
if (position[i] > 0) {
xpos = I.left + position[i];
}
else
if (position[i]<0) {
xpos = -I.right + myWidth - width + position[i];
}
}
else {
xpos = I.left;
width = MyWidth;
flag[i] = true;
}
mc[i].setLocation(xpos,ypos);
if (flag[i]) { mc[i].setSize(width,height);}
} // for each component to adjust
} // this is one of the events for which we could move around the
component
} // end of Adjust method.
public void componentResized (ComponentEvent e) {
Adjust(e);
}
public void componentMoved (ComponentEvent e) {
Adjust(e);
}
public void componentHidden(ComponentEvent e){
Adjust(e);
}
public void componentShown (ComponentEvent e){
Adjust(e);
}
} // end of SWA class, this is the class, we are trying to demonstrate.
/**
* For testing, the string to be put in the {@code JTextArea} on the
screen.
*/
static String FT =
"ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE
True"+'n'+
"TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO
True"+'n'+
"THREE True --- THREE THREE ----- THREE True ----- THREE True
---- THREE True"+'n'+
"FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ----
FOUR True";
static String ST =
"FIVE True n"+
"SIX True n"+
"SEVEN Truen"+
"EIGHT True";
public static void main (String [] args) throws IOException {
Debug = new Debu();
f = new JFrame();
f.setSize(400,500);
f.setLayout(null);
SF = new Font ("Arial",Font.BOLD,24);
SFM = f.getFontMetrics(SF);
SWA wa = new SWA();
wa.Dx = true;
wa.AM(f.getContentPane(),f);
JTextArea JTA;
JScrollPane J;
JTA = wa.CTA(FT);
J = wa.CSP(JTA,275,100);
wa.addTextArea(J,0);
JTA = wa.CTA(ST);
J = wa.CSP(JTA,275,300);
wa.addTextArea(J,-11);
f.setVisible(true);
f.repaint();
} // end of main
} //end of program (class)
T3
We now truly support having one SWA instance for each frame. We
demonstrate
having an array of Frames to show how this works.
Also SWA will stack
up the controls when there is not enough room at the bottom of the screen
for all of them.
(As we did in the T2 series, SWA has arrays to track all the controls
added. Each control is entered in the mc array, along with its
corresponding
desired size in mcw and mcw, w ith its desired position relative to the
left margin in position.)
But here, SWA.Adjust implements the following pseudocode:
for each control (i)
try to place it based upon the position[i] specified when we added it
to the frame with SWA.AddTextArea
for each control previously placed (for j from 0 to i-1)
see if the new control (i) conflicts with it.
if so, find out how far up we have to move it so it doesn't overlap
with any control.
move it there
T3A.java, T3T.java and T3AF.java exercises multiple SWA instances, one
for each Frame or JFrame in the application program.
I will focus on T3A.java and T3AF.java; these create an array of frames;
A doubly-nested loop generates a set of text boxes on each frame.
In T3AF, each frame uses a different font name and each
text box on that frame is in a different sizes (12, 16, 24 and 32).
(As I discussed in T0, one needs to get a FontMetrics for the font
and frame that we are using. Thus, I modified CTA method
calling sequence slightly--one passes the font that one is using along
with the string. It sets the font for
and gets the FontMetrics from the JTextArea that it creates.)
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
public class T3{
/**
* A simple debugging class I have been using for years.
* I put a shortened version, so
* this program is self-contained.
*/
static class Debu {
/**
* This is the debugging file; normally, one puts stuff in it
* with {@link P(String} or {@link P(String,booolean)}; but, one
* can write directly to it, if convenient.
*/
public PrintWriter D;
/**
* Create/open debugging file, {@link D}.
*/
Debu (){
try {
D = new PrintWriter (new FileOutputStream("T3.out"));
}
catch (IOException e) {
System.out.println ("cannot open debug file");
}
}
/**
* output string to debugging file, with a new line.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s) {
D.println (s);D.flush();
}
/**
* output string to debugging file, with a new line only if {@code b}
* is true.
* <BR>
* Flushes output,
* just in case program crashes afterward.
*/
public void P(String s,boolean b) {
if (b) {D.println (s);}else { D.print(s);}D.flush();
}
/**
* Simply, get Hash code and then call {@code toString()} on the
{@code Object} but shorten
* overlong results -- also it protects from Null Exception if object
is
* null.
* @param O - that which is to be output to debugging file
* @returns {@code String} which will usually be sent to {@code P}.
*/
public String SS (Object O) {
if (O != null) {
String RT = O.hashCode()+": "+O.toString();
if (RT.length() > 57) {
return RT.substring(0,57);
}
else {
return RT;
}
}
else {
return "null";
}
} // end of SS method
} // end of Debug class
static JFrame f;
static Debu Debug;
/**
* We will use this font throughout this example.
*/
static Font SF;
/**
* The {@code FontMetrics} for the standard font {@link SF}
* being used for text areas.
*/
static FontMetrics SFM;
/**
* see the discussion in the companion files {@code T1} and {@code
T1.pptx}.
*/
static class SWA implements ComponentListener {
/**
* if on, then, we will write some stuff to the debugging file,using my
* {@code Debug} class.
*/
boolean Dx=false;
/**
* To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we
will
* call {@code getInsets} to get the proper width and height without the
* "decorations". See the discussion at the beginning of the {@code AWT}
* class {@code Frame}. Otherwise, {@code F} will be empty and we will
* just have C set. If we are using a frame, the caller, will have to
get
* the component by calling {@code getContentPane()}.
*/
Frame F;
/**
* To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the
* caller will have to:
* <BR>
* call {@code getContentPane()}.
* @see F
*/
Container MC;
/**
* This associates this with the frame or other thing containing the
* components being adjusted.
*/
public void AM (Container WTA, JFrame F) {
MC = WTA;
this.F=F;
F.addComponentListener(this);
}
/**
* This array contains the component that we are
* adjusting and displaying here .
*/
Component [] mc;
/**
* This tells how many components we have to which keep track.
* Note, there are parallel arrays {@link mc}, {@link mcw}, {@link
position},
* and {@link mch}
**/
int CC;
/**
* This is the preferred width of the component added, assuming there is
* enough room for it.
*/
int [] mcw;
/**
* This is the preferred height of the component added, assuming there is
* enough room for it.
*/
int [] mch;
/**
* position to put {@link mc} relative to the containing window (@link
MC}
* <UL><LI>
* If positive, will be the number of pixels of right of the left-hand
side
* of {@link MC}
* <LI>
* If negative, will give the number of pixels to the left of the right-
hand
* edge of the containing window (@link MC}. That is, the {@code
Component}
* will be kept with a certain right margin.
* <LI>
* If zero, will be centered like in {@code T1A.java}.
* </UL>
*/
int []position;
/**
* maximum number of components we allow
*/
final int MNC=1000;
SWA () {
mc = new Component[MNC];
mcw = new int[MNC];
mch = new int [MNC];
position = new int [ MNC];
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
* @param position <UL><LI> position is positive, that is the number of
pixels from the lower=left <LI>position is negative, then this will give
the number of pixels from the right<LI>if position is zero, then it will
be centered</UL>--note, it is impossible to align this precisely with the
lower left hand corner. Simply have it one pixel just to the right of
that.
*/
void addTextArea (Component JTA,int position){
this.position[CC] = position;
this.mc[CC] = JTA;
this.mcw[CC] = JTA.getWidth();
this.mch[CC] = JTA.getHeight();
CC++;
if (MC!=null) {
MC.add(JTA);
}
}
/**
* In spite of its name, will take any {@code Component} and associate it
with the
* frame to which this {@code SWA} is attached.
* It is intended to be used by simply
* passing {@code frame.getContentPane()} for the one argument, {@code
JTA}.
* @see AddScrollPane
* @param JTA that which is to be added.
*/
void addTextArea(Component JTA) {
addTextArea(JTA,0);
}
/**
* Take the indicated {@code Component} and put it in a {@code
JScrollPane}.
* Note, programmer is responsible
* for setting its location and actually adding it
* to the frame to be seen to the unit.
* Uses default size with which to show this for the user.
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T

More Related Content

What's hot

How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
Taisuke Oe
 
Storage classes arrays & functions in C Language
Storage classes arrays & functions in C LanguageStorage classes arrays & functions in C Language
Storage classes arrays & functions in C Language
Jenish Bhavsar
 
Types of Statements in Python Programming Language
Types of Statements in Python Programming LanguageTypes of Statements in Python Programming Language
Types of Statements in Python Programming Language
Explore Skilled
 
Flow of control ppt
Flow of control pptFlow of control ppt
C language UPTU Unit3 Slides
C language UPTU Unit3 SlidesC language UPTU Unit3 Slides
C language UPTU Unit3 Slides
Rakesh Roshan
 
Python for Beginners(v2)
Python for Beginners(v2)Python for Beginners(v2)
Python for Beginners(v2)
Panimalar Engineering College
 
Python Control structures
Python Control structuresPython Control structures
Python Control structures
Siddique Ibrahim
 
Looping Statements and Control Statements in Python
Looping Statements and Control Statements in PythonLooping Statements and Control Statements in Python
Looping Statements and Control Statements in Python
PriyankaC44
 
Looping statement in python
Looping statement in pythonLooping statement in python
Looping statement in python
RaginiJain21
 
Types of loops in c language
Types of loops in c languageTypes of loops in c language
Types of loops in c language
sneha2494
 
Stacks
StacksStacks
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested LoopLoops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
Priyom Majumder
 
Java căn bản - Chapter6
Java căn bản - Chapter6Java căn bản - Chapter6
Java căn bản - Chapter6
Vince Vo
 
stack
stackstack
stack
Raj Sarode
 
Decision Making Statement in C ppt
Decision Making Statement in C pptDecision Making Statement in C ppt
Decision Making Statement in C ppt
MANJUTRIPATHI7
 
Controls & Loops in C
Controls & Loops in C Controls & Loops in C
Controls & Loops in C
Thesis Scientist Private Limited
 
Control structures ii
Control structures ii Control structures ii
Control structures ii
Ahmad Idrees
 
C# Loops
C# LoopsC# Loops
C# Loops
Hock Leng PUAH
 
04 control structures 1
04 control structures 104 control structures 1
04 control structures 1
Jomel Penalba
 
Stacks
StacksStacks
Stacks
sweta dargad
 

What's hot (20)

How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Storage classes arrays & functions in C Language
Storage classes arrays & functions in C LanguageStorage classes arrays & functions in C Language
Storage classes arrays & functions in C Language
 
Types of Statements in Python Programming Language
Types of Statements in Python Programming LanguageTypes of Statements in Python Programming Language
Types of Statements in Python Programming Language
 
Flow of control ppt
Flow of control pptFlow of control ppt
Flow of control ppt
 
C language UPTU Unit3 Slides
C language UPTU Unit3 SlidesC language UPTU Unit3 Slides
C language UPTU Unit3 Slides
 
Python for Beginners(v2)
Python for Beginners(v2)Python for Beginners(v2)
Python for Beginners(v2)
 
Python Control structures
Python Control structuresPython Control structures
Python Control structures
 
Looping Statements and Control Statements in Python
Looping Statements and Control Statements in PythonLooping Statements and Control Statements in Python
Looping Statements and Control Statements in Python
 
Looping statement in python
Looping statement in pythonLooping statement in python
Looping statement in python
 
Types of loops in c language
Types of loops in c languageTypes of loops in c language
Types of loops in c language
 
Stacks
StacksStacks
Stacks
 
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested LoopLoops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
Loops in C Programming | for Loop | do-while Loop | while Loop | Nested Loop
 
Java căn bản - Chapter6
Java căn bản - Chapter6Java căn bản - Chapter6
Java căn bản - Chapter6
 
stack
stackstack
stack
 
Decision Making Statement in C ppt
Decision Making Statement in C pptDecision Making Statement in C ppt
Decision Making Statement in C ppt
 
Controls & Loops in C
Controls & Loops in C Controls & Loops in C
Controls & Loops in C
 
Control structures ii
Control structures ii Control structures ii
Control structures ii
 
C# Loops
C# LoopsC# Loops
C# Loops
 
04 control structures 1
04 control structures 104 control structures 1
04 control structures 1
 
Stacks
StacksStacks
Stacks
 

Similar to T

CORE JAVA-2
CORE JAVA-2CORE JAVA-2
Ppt on java basics1
Ppt on java basics1Ppt on java basics1
Ppt on java basics1
Mavoori Soshmitha
 
Java swing
Java swingJava swing
Java swing
ssuser3a47cb
 
Awt, Swing, Layout managers
Awt, Swing, Layout managersAwt, Swing, Layout managers
Awt, Swing, Layout managers
swapnac12
 
Swing
SwingSwing
Chapter2pp
Chapter2ppChapter2pp
Chapter2pp
J. C.
 
Bar graph
Bar graphBar graph
Bar graph
John Reinhardt
 
Advance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.SwingAdvance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.Swing
Payal Dungarwal
 
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdfPLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
mohammedfootwear
 
Part 1 Project Setup, Building the ViewUIIn the video belo.pdf
Part 1 Project Setup, Building the ViewUIIn the video belo.pdfPart 1 Project Setup, Building the ViewUIIn the video belo.pdf
Part 1 Project Setup, Building the ViewUIIn the video belo.pdf
amazing2001
 
Conditional Statements
Conditional StatementsConditional Statements
Conditional Statements
MuhammadBakri13
 
Swing
SwingSwing
Swing
Nataraj Dg
 
JAVA AWT
JAVA AWTJAVA AWT
JAVA AWT
shanmuga rajan
 
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKDPPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
chessvashisth
 
Maxbox starter
Maxbox starterMaxbox starter
Maxbox starter
Max Kleiner
 
You can look at the Java programs in the text book to see how commen
You can look at the Java programs in the text book to see how commenYou can look at the Java programs in the text book to see how commen
You can look at the Java programs in the text book to see how commen
anitramcroberts
 
Reading Keyboard Output
Reading Keyboard OutputReading Keyboard Output
Reading Keyboard Output
shaylor_swift
 
Java: GUI
Java: GUIJava: GUI
Java: GUI
Tareq Hasan
 
GUI Programming with Java
GUI Programming with JavaGUI Programming with Java
GUI Programming with Java
Jussi Pohjolainen
 
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdfYour 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
abhijitmaskey
 

Similar to T (20)

CORE JAVA-2
CORE JAVA-2CORE JAVA-2
CORE JAVA-2
 
Ppt on java basics1
Ppt on java basics1Ppt on java basics1
Ppt on java basics1
 
Java swing
Java swingJava swing
Java swing
 
Awt, Swing, Layout managers
Awt, Swing, Layout managersAwt, Swing, Layout managers
Awt, Swing, Layout managers
 
Swing
SwingSwing
Swing
 
Chapter2pp
Chapter2ppChapter2pp
Chapter2pp
 
Bar graph
Bar graphBar graph
Bar graph
 
Advance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.SwingAdvance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.Swing
 
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdfPLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
PLEASE HELP ME !!IT IS Due Tonight ;(!i have to submit it before.pdf
 
Part 1 Project Setup, Building the ViewUIIn the video belo.pdf
Part 1 Project Setup, Building the ViewUIIn the video belo.pdfPart 1 Project Setup, Building the ViewUIIn the video belo.pdf
Part 1 Project Setup, Building the ViewUIIn the video belo.pdf
 
Conditional Statements
Conditional StatementsConditional Statements
Conditional Statements
 
Swing
SwingSwing
Swing
 
JAVA AWT
JAVA AWTJAVA AWT
JAVA AWT
 
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKDPPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
PPThbkjn;l sdc a;s'jjN djkHBSDjhhIDoj LKD
 
Maxbox starter
Maxbox starterMaxbox starter
Maxbox starter
 
You can look at the Java programs in the text book to see how commen
You can look at the Java programs in the text book to see how commenYou can look at the Java programs in the text book to see how commen
You can look at the Java programs in the text book to see how commen
 
Reading Keyboard Output
Reading Keyboard OutputReading Keyboard Output
Reading Keyboard Output
 
Java: GUI
Java: GUIJava: GUI
Java: GUI
 
GUI Programming with Java
GUI Programming with JavaGUI Programming with Java
GUI Programming with Java
 
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdfYour 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
Your 1ab8 c file is doe by Friday 1159pm to be submitted.pdf
 

More from LaurenceLLeffLeff

T4
T4T4
T3
T3T3
T2
T2T2
T1
T1T1
T0
T0T0
Tp
TpTp
Tfd
TfdTfd

More from LaurenceLLeffLeff (7)

T4
T4T4
T4
 
T3
T3T3
T3
 
T2
T2T2
T2
 
T1
T1T1
T1
 
T0
T0T0
T0
 
Tp
TpTp
Tp
 
Tfd
TfdTfd
Tfd
 

Recently uploaded

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
Mariano Tinti
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 

Recently uploaded (20)

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 

T

  • 1. TFD This, class TFD, shows adding controls to the frame without a Layout manager. Chapter Four of The JFC Swing Tutorial Second Edition by Kathy Walrath et. al. discusses using the layout manager. (http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html) At the end, the section on "Absolute Positioning" or "Dong without a Layout Manager" Of course, I note that the authors chide us taht, "you should use a layout if at all possible." In XXXX, I explain the impetus for my dealing with absolute positioning now. There is a series of operations, a pattern, for each control when we do absolute positioning. They consist of the steps listed below. I give a template for each step. (In the document TFBackground--I discuss why I am doing this series of gist's and companion power points.) In the templates, I use: ControlType for the Java Class such as JTextField or JButton. V for the instance of that type, which, of course, is a pointer, such as in JButton One, I generalize this to be ControlType V. Of course, for each template, I tell you where it is exemplified in the example source file, TFD.java. That example at the beginning displays a button and a text box. (designated One and Three). However, when the user clicks on the button, another Button and Textbox are created. They are called Two and Four. Note that the actual allocation is in the main program. The actionPerfomed for the button is in the class I defined, L, from lines 17 to 42. As I am teaching absolute positioning, we have to write: T.getContentPane().setLayout(null); That turns off the normal default layout manager. (Many years ago, it took me much headscratching to discover that I needed to do that, as the buttons, etc. would come up but sometimes do strange things or move around in strange ways.) 1) Declare the V, ControlType V. You will see I have four controls, with V's of One, Two, Three and Four. They are declared as follows: static JButton One; // this is the one always on the screen. static JButton Two; // this will be created by the first
  • 2. static JTextField Three; static JTextField Four; 2) For each one of these, do the standard Java thing to actually create a new operator. That is: V = new ControlType(); See the lines 55, 59, 60, and 67. Note: I create the control and set its size in the main method. One and Three will actually be made visible to the user there. Two and Four will be made visible to the user when they pressed the button One. That will be in the code for the actionPerformed in the actionListener, L. 3) set the size for each control. That is: V .setSize (width, height); Alternatively, one can use the form: Dimension d-name; d-name = new Dimension( width, height); V.setSize(d-name); That is good software-enginnering to have several buttons of the same size--one only changes that size respectively. For example, in ABFEAapp, I want one of several messages to all be at the same size (and location). I coded this as follows, with MS being the size. MS = new Dimension (1000,50); V.setSize(MS); where V is the textbox containing the error messages 4) set the position. As we are using "absolute positioning," this simply is the x and y location. The template is V.setLocation( x-location, y-location) Remember that the y-location is given from the TOP of the window. Thus, V.setLocation (35,27) positions the top left hand corner of V 35 pixels from the left of the window and 27 pixels from the top. (One can say this puts this 35,27 from the upper-left hand corner of the frame.) You wil find the lines to position One, Two, Three and Four in lines: 57, 64, 62, 69, respectively. (Sorry my example did not have these in order.) 5) Add the control to the frame: Frame.getContentPane().add( V ); As mentioned above, we only add the controls Two and Four when the First button is pressed: thus, you will see the statement to add these in the ActionListener , L. (lines 26 and 30, respectively). One and Three are shown when the application is started. Those, thus, appear in the main method at lines 65 and 66.
  • 3. As mentioned above, the controls Two and Four are made visible, that is, added to the window, a JFrame, T, iwhen the button is pressed. That is, this code is in the L, actionPerformed. However, I found that they wer enot seen unless we do the following: T.repaint() (on line 38). import java.util.*;import java.io.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import Debug.*; public class TFD { static JFrame T; static JButton One; // this is the one always on the screen. static JButton Two; // this will be created by the first static JTextField Three; static JTextField Four; static PrintWriter F; static boolean SA=false;; static public class L implements ActionListener { public void actionPerformed (ActionEvent e) { Debug.P(" in action Performed"); F.println (" in action performed");F.flush(); String t; t = Three.getText(); F.println ( "String in actino performed |"+t+"|");F.flush(); if (!SA) { SA=true; T.getContentPane().add(Two); M m; m = new M(); Two.addActionListener(m); T.getContentPane().add(Four); Debug.P("finished adding Two and Four"); } else { t = Four.getText(); F.println ("got stuff from second text box |"+"|");F.flush(); Debug.P("in else"); } T.repaint(); Debug.P("leaving action performed"); } } static public class M implements ActionListener{ public void actionPerformed (ActionEvent e) {
  • 4. Debug.P("clicked Two"); } } public static void main (String [] args) throws IOException { F = new PrintWriter (new FileOutputStream ("TF.out")); T = new JFrame (); T.setSize(150,350); T.getContentPane().setLayout(null); One = new JButton ("One"); One.setSize (100,50); One.setLocation (20,70); T.getContentPane().add(One); Two = new JButton(); Three = new JTextField(); Three.setSize(100,50); Three.setLocation(20,200); Two.setSize(100,50); Two.setLocation(20,130); T.getContentPane().add(One); T.getContentPane().add(Three); Four = new JTextField(); Four.setSize(100,50); Four.setLocation(20,280); L L; L = new L(); One.addActionListener(L); T.setVisible(true); } }
  • 5. TP This short program shows adding a JTextArea to a frame. I am trying to put it at the bottom of the window (I am turning off the layout manager, using absolute positioning). Since the height of the frame is in FH and the height of the JTextArea is in TH, positioning it with T.setLocation (0,FH-TH) should put the text area at the bottom of the screen with its bottom edge coincident with the bottom edge ofthe window. It does not! The problem is the top part of the window put in by Microsoft Windows. When I add the line Fr.setUndecorated(true); the item is positioned correctly. I looked for a command to get the height of that part, put in by Microsoft Windows so I could allow for it. Found it as the call getInsets ( a member of the Component class). That worked fine. Example: (f is the frame in which I wish to put the component TA). (this corectly puts the TA at the bottom cnter of the frame with TA's bottom border properly flush against the bottom of the frame!) Insets I; I = f.getInsets(); int height=TA.getHeight(); int width = TA.getWidth(); int ypos = MyHeight - height - I.top-I.bottom; MyWidth = MyWidth - I.left - I.right; int xpos = I.left+MyWidth/2 - width /2; TA.setLocation(xpos,ypos); import java.io.*;import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TP { static int FH = 200; // height of containing window static int FW = 300; // width of containging window static int TW = 75; // width of component static int TH = 32; // height of component static JFrame Fr; // containing window public static void main (String[] args) { Fr = new JFrame();
  • 6. Fr.setLayout(null); Fr.setSize(FW,FH); JTextArea T; T = new JTextArea(); javax.swing.border.Border B; B = BorderFactory.createLineBorder(Color.red,3); T.setBorder(B); T.setSize(TW,TH); T.setLocation(0,FH-TH); Fr.add(T); Fr.repaint(); Fr.setVisible(true); } }
  • 7. T0 T0.java shows creating multi-line text boxes using both the Abstract Window Toolkit (AWT) TextArea and Java Swing JTextArea. As you know, AWT came with the original Java. Java Swing was built on top of it. One can recognize the classes created by Java Swing--they begin with the letter J. Often, the Java Swing has a version of each class in AWT, but with a little gloss upon it. This unit (T0) covers and shows TextArea and JTextArea. In the case of AWT, the TextArea includes scrolling functionality. That is, if one puts more text into the TextArea than can be shown in the amount of space given to it with setSize method, scroll bars will appear and function appropriately, In Java Swing, one has to put the JTextArea in a JScrollPane if one wants to have it scroll when this happens. (This is more of a difference than one usually sees between the AWT class and the corresponding Java Swing class.) Our program creates one of each--I follow the steps and templates in TFD unit. The routine stuff, I simply show the template. The lines for AWT are in the left-hand column. The lines for Java Swing are in the right-hand column. I put the line numbers for T0.java in parentheses. How we get the text. In my application, I wish to support receiving and displaying the text in one of three ways: An Array of Strings. A big long String containing carriage returns. Passing the name (or path name) of a file containing the text to be displayed A Collection of Strings. (See Chapter 21 on Collections in Java in The Java Programming Language , Fourth Edition.) For this example, I just show the first (Array of String) The example input is in JT on lines 79 to 84. Obviously, the extension of this to the other three is straightforward, but I show it in the set XXX. Step One: ControlType V TextArea TA (151) JTextArea RT (136) JScrollPane J; (149)
  • 8. Remember that in using the JSwing classes, one has to put the text area within a JScrollPane. This is to handle the case when the text is too big to fit in the space we care to allot on the screen for it. Step Two: V = new ControlType() TA = new TextArea (B.toString(), RT = new JTextArea(NORows,MaxLL); NoRows,NoCols); Assume one has a Dimension D giving the space we care to allot to display our text. For using Java Swing, we need to find out how big the text is, assuming we had a screen big enough to hold it. I call that measuring the text. We assign that as the size of RT. Then, we set the JScrollPane to size D. It is much a simpler for us programmers when we use the AWT TextArea. We simply setSize TextArea to D. Any necessary measuring of the text seems to be done internally by the TextArea. Measuring the Text. For the JTextArea (Java Swing), we have to find out how big the text would be if we were to display it in all its glory. That is how big would the text be if we were to allot enough space on the screen so the user could see all of it at once (assuming that the display hardware were big enough). I call this "measuring the text." We loop through the lines of the text. We get the length of each line, both in pixels and in characters. We take the maximum of each. This is a loop such as the following (lines 137 to 148): See the JT discussion below. for (i=0;i<JT.length;i++){ String L = JT[i]; // line that we are checking Rectangle2D WR = SFM.getStringBounds (L,C); int W= (int)WR.getWidth(); Debug.P(" processing line |"+L+"| position "+i+ " width is: "+W); if (W>maxLW){ maxLW = W; } if (L.length() > maxLL) { maxLL = L.length(); } } Remember that maxLW is the size of the JTextArea in pixels--that gets passed to its setSize call. maxLL is the length of the longest line in characters! We passed that to the constructor.
  • 9. (That is known as the number of "columns" and there is a getColumns method to get this value from the JTextArea--should one lose track of it.) Some important things that I found the hard way. Be sure that SFM is gotten by doing the getFontMetrics that one actually is using on the JTextArea. We set that font with a command such as RT.setFont(SF) or TA.setFont(TA). (lines 128 or 163). Expletive-deleting this caused ugly space to appear to the right and bottom of our text as I scrolled it! Also, C is gotten by using getGraphics() on the component in which we are placing the text. I tried C = f.getGraphics() (line 109) where f was simply the whole frame for our Windows program. Sometimes, that seemed to work OK; sometimes it seemed to matter that I actually got the context of the TextArea after I put it on the frame. Lastly, we get measure the height. That is easier as each line is the same height. We get that by using the getHeight method of the FontMetrics. It is important to realize that "This is the distance between the baselines of adjacent lines of text." I call your attention to the Java API documentation for FontMetrics.getHeight() (I took the quote in the previous sentence from that documentation.) We simply multipy that value by the number of lines that we include in the text. See lines 149 to 151. Glomming or Concatenating the text. As mentioned above, I want my class to handle receiving the text in all kinds of ways. In this set, I just show receiving the text as an array of strings. That is, in T0.java, I declared (lines 79 to 84): static String [] JT = new String [] { "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True", "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True", "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True", "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True" }; Step Three: For the TextArea, we simply apply the setSize method to it. However, when using the JTextArea, as mentioned above, we put it in a JScrollPane.
  • 10. However, as mentioned, the size that is for the JTextArea is that of the text in all its glory. These are the variables maxLW and HT found in Measuring the text. (lines 137 to 148 and 149) Then, we simply write RT.setSize(maxLW,H); The size on the screen is given to the JScrollPane itself. We have to put the JTextArea inside the JScrollBar(). One should be able to do this with the JScrollPane constructor: JScrollPane J; J = new JScrollPane(RT); but I had better luck doing it piece-by-piece explicitly. Besides, it helps one understand what happens. On lines 129 to 136 see something like the following: JScrollPane J; J = new JScrollPane(); J.setSize(100,50); J.setLocation(50,50); JViewport V; V = (JViewport)J.getViewport(); V.add(RT); At the beginning of the Swing API documetnation for the class JScrollPane, you will see the discussionof the JViewPort which contains that which is to be scrolled. One can explicitly add the control representing that which we are to scroll. In this case, that is the JTextArea RT. Step Four Of course, we just give the TextArea the size which it has to display the text--which will usually be smaller than is needed to display all that it will display. The TextArea will provide scroll bars and scrolling that is needed: TA.setSize(100,50); TA.setLocation(50,200); One thing I learned the hard way is that we need to explicitly set the Font and color for the JTextArea. That is (lines 127 to 128): RT.setForeground(Color.black); RT.setFont(SF); Remember, that we give the JScrollPane the explicit location and size where we want them to appear on the screen for our user!
  • 11. J.setLocation(50,50); Step Five: Remember that we add the TextArea directly to the screen; we add the JScrollBar (containing the JTextArea) to the screen: f.getContentPane().add(TA); f.getContentPane().add(J); (Lines 164 and 165) In T1, I show creating a class to control these. import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Font; public class T0{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. *<P> * It is irrelevant to that which these examples are trying to teach. */ static class Debug { public PrintWriter D; Debug (){ try { D = new PrintWriter (new FileOutputStream("T0.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } public void P(String s) { D.println (s);D.flush(); } public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, call {@code toString()} on the {@code Object} but shorten * overlong results -- also protects from Null Exception if object is * null. */
  • 12. public String SS (Object O) { if (O != null) { String RT = O.toString(); if (RT.length() > 50) { return RT.substring(0,50); } else { return RT; } } else { return "null"; } } // end SS method } // end class Debug static Debug Debug; static JFrame f; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * The {@code Graphics} for the frame-- which we will need * to get an accurate width for a line as wit will be displayed. */ static Graphics C; /** * the string on which we will test; the string that we will put in the * text area; */ static String [] JT = new String [] { "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True", "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True", "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True", "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True" }; /** * The maximum length of a line, based upon the number of characters */ static int maxLL=0; /**
  • 13. * The maximum length of a line, based upon pixels. */ static int maxLW =0; /** * We will put the text area inside this to get it to scroll. */ public static void main (String [] args) throws IOException { Debug = new Debug(); int i; f = new JFrame(); f.setSize(400,500); f.setLayout(null); f.setVisible(true); f.validate(); C = f.getGraphics(); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); v // determine maximum width and height of the text area // based on putting in the text JT JTextArea RT; RT = new JTextArea(); // assemble text area StringBuffer B; B = new StringBuffer(); for (i=0;i<JT.length;i++){ B.append(JT[i]); if (i!=JT.length-1){B.append ('n');} } RT.setForeground(Color.black); RT.setFont(SF); RT.setText(B.toString()); JScrollPane J; J = new JScrollPane(); J.setSize(100,50); J.setLocation(50,50); JViewport V; V = (JViewport)J.getViewport(); V.add(RT); for (i=0;i<JT.length;i++){ String L = JT[i]; // line that we are checking Rectangle2D WR = SFM.getStringBounds (L,C); int W= (int)WR.getWidth(); Debug.P(" processing line |"+L+"| position "+i+ " width is: "+W); if (W>maxLW){ maxLW = W; }
  • 14. if (L.length() > maxLL) { maxLL = L.length(); } } int NORows = JT.length; int height = SFM.getHeight(); // height of text area in pixels int H = NORows*height; Debug.P(" after loop max LW is "+maxLW + " pixels; max LL = "+maxLL+ " characters "); RT.setSize(maxLW,H); Debug.P (" RT 's text is |"+RT.getText()+"| its font " +RT.getFont() + " its color "+RT.getForeground() + " checking that it is in the view port "+V.getComponent(0) + " number of rows in RT is " + RT.getRows() + " number of columns in RT is " + RT.getColumns()); Debug.P(" the text sent to text area is |"+B.toString()+"|",false); Debug.P(" after measuring text ("+maxLW+","+H+")"); TextArea TA; TA = new TextArea (B.toString(),NORows,maxLL); Debug.P(" Constructing Text Area with |"+B.toString()+"|,"+NORows+","+maxLL+")"); TA.setSize(100,50); TA.setLocation(50,200); TA.setFont(SF); f.getContentPane().add(J); f.getContentPane().add(TA); f.validate(); f.repaint(); } // end of main method } //end of class
  • 15. T1 In T1, we create a class SWA to handle much of these. I will be building on these to add more wonderful complications :-) in the T2 and T3 series. Be sure to see the Unified Model Language (UML) diagram in T1.pptx. It shows the relationships between SWA, the outer Frame, and, right now, the single text area on that Frame! Now, please remember from your understanding of Java GUI programming (that is the AWT package and the Java Swing package) that one can associate a ComponentListener to a main window of an application. It detects when the user resizes the window by dragging the sides. Conveniently, it also detects when the Component first comes up. SWA implements that ComponentListener interface! (There are four methods in the interface. That means that SWA will have a definition for each of these four methods. However, all that we need to do, all the action for this series, I put in the method I define, Adjust. All four of those methods simply call Adjust! All four of those methods have a single argument, a ComponentEvent. (This is fairly typical for methods in listeners and adapters in Java Swing/AWT.) From that, we get the Component that was resized or shown. This is the OUTER window! (By the way, I do check that the Component is a Resized or Shown--if it was one of the other two things (hidden or moved), we do nothing.) In order to proceed, we need to know the new width and height of the OUTER window! (Or the initial height and width if this window is the first time shown). I get them in lines 262 to 264. I put them in global variables, MyHeight and MyWidth. In this example, there is a single component for which the SWA is responsible. That is indicated by the connection mc (see that UML diagram). The T2 series will have multiple things managed by each SWA instance. The T3 series will have multiple SWA instances, one for each Frame (outer window) in the application program. In this example, T1.java, we only support centering the item in the lower left-hand corner of its outer window. That item's size is given bythe variables height and width. CSP sets these in the SWA instance. To adjust the item properly, we use the formula:
  • 16. xpos = MyWidth / 2 – width/2; Then, we set the location: mc.setLocation(xpos,ypos); (The ypos is computed from the vertical room in the window - the height of its object. Remember that in Java Swing, as in most graphical systems, the y axis goes downward with zero representing the top of the window. In fact, we have to allow for what are called "Decorations." In particular, the bar at the top of the window, so familiar that you probably that you don't think about it. It is where the little button to minimize the window, make the window go to the entire size of your screen or exit the application with an X are. (We can turn these off with setDecorations(false)' Unfortunately, that also means that we cannot resize the window, the whole point of this exercise.) The Java AWT Frame class implements the method getInsets(). That enables us to find out how much space is taken up by these decorations. (There is a smaller amount of space taken up by borders on the left, right and bottom sides of a typical window.) See, in particular lines 266, 270. Also, shoudl the user make the screen so small that we cannot display the text area completely, we make the item smaller. Note that the SWA class variables height and width don't change when this occurs. The result is that the component size snaps right back when the user makes the window big enough to contain the component completely. Note that T1.java's implementation of SWA only allows for items to be centered. (Note that the whole series only provides for items on the bottom of the window.) See T1b.java, where we pass a position to addTextArea when we create the text area. A zero value means that the item should be centered, as in T1.java. A positive value is the number of pixels from the left- hand corner. A negative value allows one to define that the item should be so many pixels from the right-hand margin. That is, a -1 right- justifies the smaller text area or component within the main screen. In T1B.java, see line 328 for the calculation in Adjust import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*;
  • 17. import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T1{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T1.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file
  • 18. * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, wil have to get * the component by calling {@code getContentPane()}. */ Frame F; /**
  • 19. * To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame}, the * caller will have to * call {@code getContentPane()}. * @see F */ Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /* * This is the component that we are adjusting and displaying here * A later version will do arrays of these things. */ Component mc; /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane */ void addTextArea (Component JTA){ this.mc = JTA; if (MC!=null) { MC.add(JTA); } } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); } /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size,
  • 20. * we make the scrollbar fit the text. In other words, if the text is shorter * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); if (Width < width){ width = Width; } if (Height < height) { height = Height; } J.setSize(width,height); JViewport V; V = (JViewport)J.getViewport(); V.add(JTA); mc = J; return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD){ int NoRows; NoRows = 0; char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels)
  • 21. int NumberChars; JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i); } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (Dx) { } if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD); return RT; } /** * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */
  • 22. private void Adjust (ComponentEvent e) { int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ if (mc!=null){ Component w = e.getComponent(); int MyHeight=w.getHeight(); int MyWidth = w.getWidth(); Insets I; I = F.getInsets(); int height=mc.getHeight(); int width = mc.getWidth(); int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; boolean flag=false;// if the component's size does not fit in the window, // we set this true, so we change the size of the // textbox to fit. if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag=true; } MyWidth = MyWidth - I.left - I.right; int xpos; if (width <MyWidth) { xpos = I.left+MyWidth/2 - width /2; } else { xpos = I.left; width = MyWidth; flag = true; } mc.setLocation(xpos,ypos); if (flag) { mc.setSize(width,height);} } // there really is a component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) { Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e);
  • 23. } } // end of SWA class, this is the class, we are trying to demonstrate. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String JT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; public static void main (String [] args) throws IOException { Debug = new Debu(); f = new JFrame(); f.setSize(400,500); f.setLayout(null); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); SWA wa = new SWA(); wa.Dx = true; wa.AM(f.getContentPane(),f); JTextArea JTA; JScrollPane J; JTA = wa.CTA(JT); J = wa.CSP(JTA,275,100); wa.addTextArea(J); f.setVisible(true); f.repaint(); } // end of main } //end of program (class) import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T1A{
  • 24. /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T1.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString();
  • 25. if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, wil have to get * the component by calling {@code getContentPane()}. */ Frame F; /** * To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame}, the * caller will have to * call {@code getContentPane()}. * @see F */
  • 26. Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /** * This is the component that we are adjusting and displaying here * A later version will do arrays of these things. */ Component mc; /** * This is the preferred width of the component added, assuming there is * enough room for it. */ int mcw; /** * This is the preferred height of the component added, assuming there is * enough room for it. */ int mch; /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane */ void addTextArea (Component JTA){ this.mc = JTA; if (MC!=null) { MC.add(JTA); } } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); }
  • 27. /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size, * we make the scrollbar fit the text. In other words, if the text is shorter * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); if (Width < width){ width = Width; } if (Height < height) { height = Height; } J.setSize(width,height); JViewport V; V = (JViewport)J.getViewport(); V.add(JTA); mc = J; mcw = width; mch = height; return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD){ int NoRows; NoRows = 0;
  • 28. char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels) int NumberChars; JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i); } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (Dx) { } if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD); return RT; } /**
  • 29. * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */ private void Adjust (ComponentEvent e) { int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ if (mc!=null){ Component w = e.getComponent(); int MyHeight=w.getHeight(); int MyWidth = w.getWidth(); Insets I; I = F.getInsets(); int height=mch; int width = mcw; int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; boolean flag=false;// if the component's size does not fit in the window, // we set this true, so we change the size of the // textbox to fit. if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag=true; } MyWidth = MyWidth - I.left - I.right; int xpos; if (width <MyWidth) { xpos = I.left+MyWidth/2 - width /2; } else { xpos = I.left; width = MyWidth; flag = true; } mc.setLocation(xpos,ypos); if (flag) { mc.setSize(width,height);} } // there really is a component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) {
  • 30. Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e); } } // end of SWA class, this is the class, we are trying to demonstrate. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String JT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; public static void main (String [] args) throws IOException { Debug = new Debu(); f = new JFrame(); f.setSize(400,500); f.setLayout(null); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); SWA wa = new SWA(); wa.Dx = true; wa.AM(f.getContentPane(),f); JTextArea JTA; JScrollPane J; JTA = wa.CTA(JT); J = wa.CSP(JTA,275,100); wa.addTextArea(J); f.setVisible(true); f.repaint(); } // end of main } //end of program (class) import java.util.*; import java.awt.geom.*; import java.io.*;
  • 31. import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T1B{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T1.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is
  • 32. * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, wil have to get * the component by calling {@code getContentPane()}. */ Frame F;
  • 33. /** * To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame}, the * caller will have to * call {@code getContentPane()}. * @see F */ Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /** * This is the component that we are adjusting and displaying here * A later version will do arrays of these things. */ Component mc; /** * This is the preferred width of the component added, assuming there is * enough room for it. */ int mcw; /** * This is the preferred height of the component added, assuming there is * enough room for it. */ int mch; /** * position to put {@link mc} relative to the containing window (@link MC} * <UL><LI> * If positive, will be the number of pixels of right of the left-hand side * of {@link MC} * <LI> * If negative, will give the number of pixels to the left of the right- hand * edge of the containing window (@link MC}. That is, the {@code Component} * will be kept with a certain right margin. * <LI> * If zero, will be centered like in {@code T1A.java}. * </UL> */ int position; /**
  • 34. * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. * @param position <UL><LI> position is positive, that is the number of pixels from the lower=left <LI>position is negative, then this will give the number of pixels from the right<LI>if position is zero, then it will be centered</UL>--note, it is impossible to align this precisely with the lower left hand corner. Simply have it one pixel just to the right of that. */ void addTextArea (Component JTA,int position){ this.position = position; this.mc = JTA; if (MC!=null) { MC.add(JTA); } } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. */ void addTextArea(Component JTA) { addTextArea(JTA,0); } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); } /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size, * we make the scrollbar fit the text. In other words, if the text is shorter
  • 35. * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); if (Width < width){ width = Width; } if (Height < height) { height = Height; } J.setSize(width,height); JViewport V; V = (JViewport)J.getViewport(); V.add(JTA); mc = J; mcw = width; mch = height; return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD){ int NoRows; NoRows = 0; char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels)
  • 36. int NumberChars; JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i); } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (Dx) { } if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD); return RT; } /** * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */
  • 37. private void Adjust (ComponentEvent e) { int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ if (mc!=null){ Component w = e.getComponent(); int MyHeight=w.getHeight(); int MyWidth = w.getWidth(); Insets I; I = F.getInsets(); int height=mch; int width = mcw; int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; boolean flag=false;// if the component's size does not fit in the window, // we set this true, so we change the size of the // textbox to fit. if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag=true; } int myWidth; // my real width after subtracting any insets myWidth = MyWidth - I.left - I.right; int xpos; if (width <MyWidth) { xpos=0; if (position ==0){ xpos = I.left+MyWidth/2 - width /2; } else if (position > 0) { xpos = I.left + position; } else if (position <0) { xpos = -I.right + myWidth - width + position; } } else { xpos = I.left; width = MyWidth; flag = true; } mc.setLocation(xpos,ypos); if (flag) { mc.setSize(width,height);} } // there really is a component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method.
  • 38. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) { Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e); } } // end of SWA class, this is the class, we are trying to demonstrate. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String JT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; public static void main (String [] args) throws IOException { Debug = new Debu(); f = new JFrame(); f.setSize(400,500); f.setLayout(null); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); SWA wa = new SWA(); wa.Dx = true; wa.AM(f.getContentPane(),f); JTextArea JTA; JScrollPane J; JTA = wa.CTA(JT); J = wa.CSP(JTA,275,100); wa.addTextArea(J,-11); f.setVisible(true); f.repaint(); } // end of main } //end of program (class)
  • 39. import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T1T{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debug { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debug (){ try { D = new PrintWriter (new FileOutputStream("T1T.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); }
  • 40. /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame [] f; /** * number of frames on which we will test */ static int NOF = 3; static Debug Debug; /** * We will use this font throughout this example. */ static Font []SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics [] SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /**
  • 41. * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, wil have to get * the component by calling {@code getContentPane()}. */ Frame F; /** * To Whom I belong. If ultimate is a {@code JFrame} or {@code Frame}, the * caller will have to * call {@code getContentPane()}. * @see F */ Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /* * This is the component that we are adjusting and displaying here * A later version will do arrays of these things. */ Component mc; /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane */ void addTextArea (Component JTA){ this.mc = JTA; if (MC!=null) { MC.add(JTA); } if (Dx) {Debug.P(" returning from add Text Area, added component "+Debug.SS(JTA)+ " TO " + Debug.SS(MC)+ " ",false);} } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}.
  • 42. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); } /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size, * we make the scrollbar fit the text. In other words, if the text is shorter * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); Insets I = J.getInsets(); if (Width < width){ width = Width; } if (Height < height) { height = Height; } JViewport V; if (Dx) {Debug.P( " returning scroll Pane "+Debug.SS(J) + " new location ("+width+","+height+") ",false); J.setSize(width,height); mc = J; return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was
  • 43. * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD, Font SF,FontMetrics SFM){ int NoRows; NoRows = 0; char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels) int NumberChars; JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i); } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD);
  • 44. return RT; } /** * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */ private void Adjust (ComponentEvent e) { int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ if (mc!=null){ Component c = e.getComponent(); if (Dx) {Debug.P (" Resizing the frame (or outer container) " + Debug.SS(c),false);} int MyHeight=c.getHeight(); int MyWidth = c.getWidth(); if (Dx) {Debug.P (" My Height " + MyHeight + " My Width " + MyWidth + " ",false);} Insets I; I = F.getInsets(); int height=mc.getHeight(); int width = mc.getWidth(); int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; if (Dx){Debug.P (" of component being adjusted , height "+ height + " width "+ width + " vertical Room " + room + " I.top "+I.top + " I.bottom "+I.bottom + " ",false);} boolean flag=false;// if the component's size does not fit in the window, // we set this true, so we change the size of the // textbox to fit. if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag=true; } if (Dx){Debug.P ( " room " + room + " height " + height + " ypos " +ypos,false);} MyWidth = MyWidth - I.left - I.right; if (Dx){Debug. P (" new My Width (or horizontal room ) " + MyWidth + " I.left "+I.left + " I.right "+I.right,false);} int xpos; if (width <MyWidth) { xpos = I.left+MyWidth/2 - width /2; } else {
  • 45. xpos = I.left; width = MyWidth; flag = true; } if (Dx){Debug.P(" new xpos " + xpos + " ypos " + ypos );} mc.setLocation(xpos,ypos); JScrollPane J=null; try { J = (JScrollPane) mc; } catch (ClassCastException cce) { Debug.P (" class cast exception encountered on converting to JScrollPane "); } JViewport V; V=null; // if the text area is now smaller than the scroll bar space, we will change it // to be the scroll base space -- after allowing for the width of the vertical // scroll bar and the height of the horizontal scroll bar. if (J!=null){ V = (JViewport)J.getViewport(); JScrollBar VSB = J.getVerticalScrollBar(); int VSBw=0; if (VSB !=null) { VSBw = VSB.getWidth(); } JScrollBar HSB = J.getHorizontalScrollBar(); int HSBh = 0; if (HSB !=null) { HSBh = HSB.getHeight(); } if (Dx){ Debug.P (" scroll bar width: "+width + " height " + height + " vertical scroll bar "+Debug.SS (VSB) + " horizontal scroll bar " + Debug.SS (HSB) + " vertical scroll bar width "+VSBw + " horizontal scroll bar height " + HSBh + "("+width+"+"+I.left+"+"+I.right+"+"+VSBw+","+ height+"+"+I.top+"+"+I.bottom+"+"+HSBh+") ",false); } int Cc = V.getComponentCount(); if (Cc == 1){ Component C = V.getComponent(0); int H,W,h,w; // if the text area is now smaller than the scroll space, we will change it // to be the scroll base space -- after allowing for the width of the vertical // scroll bar and the height of the horizontal scroll bar.
  • 46. H = C.getHeight() ; W = C.getWidth(); if (Dx){ Debug.P (" got the text area or whatever was inside the Component: "+Debug.SS(C)+ " H is " + H + " W is "+ W + " ",false); } h= height - HSBh; w = width - VSBw; boolean Flag; Flag = false; if (Dx) { Debug.P (" h is " + h + " w " + w + " ",false); } if (H < h) { Flag = true; h = H; } if (w > W) { Flag = true; w = W; } if (flag){ C.setSize(W+VSBw,H+HSBh); if (Dx) { Debug.P (" resetting size of text area to ("+w + ","+h + ") ",false); } } } // C in getting component of the scroll pane finds exactly one } // J in converting component to scroll pane NOT NULL if (flag) { mc.setSize(width,height);} } // there really is a component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) { Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e); } } // end of SWA class, this is the class, we are trying to demonstrate.
  • 47. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String JT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; static String ST = "ONnTWOnTHREE"; public static void main (String [] args) throws IOException { Debug = new Debug(); f = new JFrame[NOF]; SFM = new FontMetrics[NOF]; SF = new Font[NOF]; SWA []wa; wa = new SWA [NOF]; JTextArea[] JTA; JTA = new JTextArea[NOF]; JScrollPane []J; J = new JScrollPane[NOF]; int i; for (i=0;i<NOF;i++) { f[i] = new JFrame(); f[i].setSize(400,500); f[i].setLayout(null); SF[i] = new Font ("Arial",Font.BOLD,24); SFM[i] = f[i].getFontMetrics(SF[i]); wa[i] = new SWA(); wa[i].Dx = true; wa[i].AM(f[i].getContentPane(),f[i]); switch (i){ case 0: JTA[i] = wa[i].CTA(JT,SF[i],SFM[i]); J[i] = wa[i].CSP(JTA[i],75,100); break; case 1: JTA[i] = wa[i].CTA(ST,SF[i],SFM[i]); J[i] = wa[i].CSP(JTA[i],300,300); break; case 2: JTA[i] = wa[i].CTA(ST,SF[i],SFM[i]); J [i] = wa[i].CSP(JTA[i],500,300); break; default: System.err.println (" should not be here , wrong case in switchn"); System.exit(-100);
  • 48. } Debug.P(" adding component " + Debug.SS(J[i]) + " to frame # "+i+ " "+Debug.SS(f[i]) + " Scroll panel is "+Debug.SS(J[i])+ " Text Area is "+Debug.SS(JTA[i])+ " ",false); wa[i].addTextArea(J[i]); Debug.P ("returned from wa addTextArea "); f[i].setVisible(true); f[i].repaint(); } // loop to do all (NOF) frames } // end of main } //end of program (class)
  • 49. T2 In T2.java, I promised you that we would allow each instance of the SWA class to manage several items or text areas. (Note, here we are still only supporting one outer window; that is, we only have one instance of SWA). I have four parallel arrays: mc - the text area or component within the outer frame mcw - its width mch - its height position - (*) Thus, assume we call AddTextArea three times. The last time, the last time, we call it with a component or JScrollPane 789 with a position of -11. (See T2T.java where we do call it such.) Then mc[2] will point to JScrollPane 789. position[2] will be -11. And mcw[2] and mch[2] will give the preferred width and height for component 789. (The latter two values are copied from the JTextArea or component being added in line 184 of T2T.java. (*) Recall that in T1B.java, we introduced passing zero to have the item centered horizontally, a positive number to be left justified or justified against the left-hand margin, and a negative number to have it right- justified or given a position relative to the right-hand border of the outer frame. The Adjust subroutine follows that in the T1 series--it just loops through all the items in those four parallel arrays. Thus, you will see height=mch[i] and width=mcw[i] and then height and width are used in the remainder of Adjust, copied from the T1 series. import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T2{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient.
  • 50. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T1.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; }
  • 51. } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, will have to get * the component by calling {@code getContentPane()}. */ Frame F; /** * To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the * caller will have to: * <BR> * call {@code getContentPane()}. * @see F */ Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F;
  • 52. F.addComponentListener(this); } /** * This array contains the component that we are * adjusting and displaying here . */ Component [] mc; /** * This tells how many components we have to which keep track. * Note, there are parallel arrays {@link mc}, {@link mcw}, {@link position}, * and {@link mch} **/ int CC; /** * This is the preferred width of the component added, assuming there is * enough room for it. */ int [] mcw; /** * This is the preferred height of the component added, assuming there is * enough room for it. */ int [] mch; /** * position to put {@link mc} relative to the containing window (@link MC} * <UL><LI> * If positive, will be the number of pixels of right of the left-hand side * of {@link MC} * <LI> * If negative, will give the number of pixels to the left of the right- hand * edge of the containing window (@link MC}. That is, the {@code Component} * will be kept with a certain right margin. * <LI> * If zero, will be centered like in {@code T1A.java}. * </UL> */ int []position; /** * maximum number of components we allow */ final int MNC=1000; SWA () { mc = new Component[MNC]; mcw = new int[MNC]; mch = new int [MNC]; position = new int [ MNC]; } /**
  • 53. * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. * @param position <UL><LI> position is positive, that is the number of pixels from the lower=left <LI>position is negative, then this will give the number of pixels from the right<LI>if position is zero, then it will be centered</UL>--note, it is impossible to align this precisely with the lower left hand corner. Simply have it one pixel just to the right of that. */ void addTextArea (Component JTA,int position){ this.position[CC] = position; this.mc[CC] = JTA; this.mcw[CC] = JTA.getWidth(); this.mch[CC] = JTA.getHeight(); CC++; if (MC!=null) { MC.add(JTA); } } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. */ void addTextArea(Component JTA) { addTextArea(JTA,0); } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); } /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size,
  • 54. * we make the scrollbar fit the text. In other words, if the text is shorter * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); if (Width < width){ width = Width; } if (Height < height) { height = Height; } J.setSize(width,height); JViewport V; V = (JViewport)J.getViewport(); V.add(JTA); return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD){ int NoRows; NoRows = 0; char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels) int NumberChars;
  • 55. JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i); } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (Dx) { } if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD); return RT; } /** * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */ private void Adjust (ComponentEvent e) {
  • 56. int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ Component w = e.getComponent(); int MyHeight=w.getHeight(); int MyWidth = w.getWidth(); Insets I; I = F.getInsets(); int height; int width; int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; boolean []flag; flag = new boolean[CC]; int i; // position within arrays mc,position,mch,mcw; // tells which component is being adjusted for ( i = 0; i < CC; i++) { flag[i]=false;// if the component's size does not fit in the window, // if we set this true, so we change the size of the // textbox to fit. height = mch[i]; width = mcw[i]; if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag[i]=true; } int myWidth; // my real width after subtracting any insets myWidth = MyWidth - I.left - I.right; int xpos; if (width <MyWidth) { xpos=0; if (position[i] ==0){ xpos = I.left+MyWidth/2 - width /2; } else if (position[i] > 0) { xpos = I.left + position[i]; } else if (position[i]<0) { xpos = -I.right + myWidth - width + position[i]; } } else { xpos = I.left; width = MyWidth; flag[i] = true; }
  • 57. mc[i].setLocation(xpos,ypos); if (flag[i]) { mc[i].setSize(width,height);} } // for each component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) { Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e); } } // end of SWA class, this is the class, we are trying to demonstrate. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String JT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; public static void main (String [] args) throws IOException { Debug = new Debu(); f = new JFrame(); f.setSize(400,500); f.setLayout(null); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); SWA wa = new SWA(); wa.Dx = true; wa.AM(f.getContentPane(),f); JTextArea JTA; JScrollPane J; JTA = wa.CTA(JT); J = wa.CSP(JTA,275,100); wa.addTextArea(J,0); f.setVisible(true); f.repaint();
  • 58. } // end of main } //end of program (class) import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T2T{ /** * A simple debugging class I have been using for years. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T1.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush();
  • 59. } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57); } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener {
  • 60. /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, will have to get * the component by calling {@code getContentPane()}. */ Frame F; /** * To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the * caller will have to: * <BR> * call {@code getContentPane()}. * @see F */ Container MC; /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /** * This array contains the component that we are * adjusting and displaying here . */ Component [] mc; /** * This tells how many components we have to which keep track. * Note, there are parallel arrays {@link mc}, {@link mcw}, {@link position}, * and {@link mch} **/ int CC; /** * This is the preferred width of the component added, assuming there is * enough room for it. */ int [] mcw; /**
  • 61. * This is the preferred height of the component added, assuming there is * enough room for it. */ int [] mch; /** * position to put {@link mc} relative to the containing window (@link MC} * <UL><LI> * If positive, will be the number of pixels of right of the left-hand side * of {@link MC} * <LI> * If negative, will give the number of pixels to the left of the right- hand * edge of the containing window (@link MC}. That is, the {@code Component} * will be kept with a certain right margin. * <LI> * If zero, will be centered like in {@code T1A.java}. * </UL> */ int []position; /** * maximum number of components we allow */ final int MNC=1000; SWA () { mc = new Component[MNC]; mcw = new int[MNC]; mch = new int [MNC]; position = new int [ MNC]; } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. * @param position <UL><LI> position is positive, that is the number of pixels from the lower=left <LI>position is negative, then this will give the number of pixels from the right<LI>if position is zero, then it will be centered</UL>--note, it is impossible to align this precisely with the lower left hand corner. Simply have it one pixel just to the right of that. */ void addTextArea (Component JTA,int position){ this.position[CC] = position; this.mc[CC] = JTA; this.mcw[CC] = JTA.getWidth(); this.mch[CC] = JTA.getHeight(); CC++;
  • 62. if (MC!=null) { MC.add(JTA); } } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. */ void addTextArea(Component JTA) { addTextArea(JTA,0); } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user. */ JScrollPane CSP (Component JTA) { return CSP ( JTA, 200,50); } /** * Take the indicated {@code Component} {@code JTA} and put it on * a {@code JScrollPane} on the associated {@link Frame}. Uses the * indicated size. Except if the {@code JTA} is smaller than that size, * we make the scrollbar fit the text. In other words, if the text is shorter * or narrower than the programmer expects, we use the width or height that * we actually need rather than what the programmer specified. * Programmer is responsible for setting its location. */ JScrollPane CSP(Component JTA, int width, int height){ JScrollPane J; J = new JScrollPane(); int Width = JTA.getWidth(); int Height = JTA.getHeight(); if (Width < width){ width = Width+31; } if (Height < height) { height = Height; } J.setSize(width,height); JViewport V;
  • 63. V = (JViewport)J.getViewport(); V.add(JTA); return J; } /** * Create a {@code JTextArea} from the {@code String WTD} , which presumably * has carriage returns separating the lines or rows in the {@code TextArea} * @param WTD stick this content in the return {@code TextArea} * @returns a {@code TextArea} set with the appropriate number of rows and columns as well as the width and height in pixels. * <P> * To better measure the text * (see companion files {@code T0} and {@code T1} or {@code T0.pptx} * or {@code T1.pptx}, we will add this, at least temporarily to the * {@code Container} with which this is associated. That assume that this was * associated with one; we tell by seeing if {@code MC} is not {@code null}. */ public JTextArea CTA ( String WTD){ int NoRows; NoRows = 0; char c; int i; int W /* width */; // temps int LastPos=0; int maxLL = 0; // maximum length of a line based on the number of characters int maxLW = 0; // maximum length of a line based upon the font // (in a unit like pixels) int NumberChars; JTextArea RT; // text area to be returned. (This is an abbreviation for // Return This. RT = new JTextArea(); RT.setFont(SF); RT.setForeground(Color.black); Graphics C; if (MC !=null) { MC.add(RT); } C = RT.getGraphics(); for (i=0 ; i < WTD.length();i++) { c = WTD.charAt(i); if (c== 'n') { NoRows++; NumberChars = i-LastPos; if (NumberChars > maxLL) { maxLL = NumberChars; } String L; if (LastPos==0) { L = WTD.substring(0,i);
  • 64. } else { L = WTD.substring(LastPos+1,i); } C = RT.getGraphics(); Rectangle2D WR = SFM.getStringBounds(L,C); W = (int)WR.getWidth(); if (Dx) { } if (W > maxLW) { maxLW = W; } LastPos=i; if (Dx) { } } // we have a new line, separating actual lines in the text area. } // loop through all characters in the String to put in the text area. int height = SFM.getHeight(); int H = NoRows*height; // height that we will make our JTextArea to be RT.setSize(maxLW,H); RT.setText(WTD); return RT; } /** * Put this text area (or other component) at the bottom center of the frame * {@link F} to whom I belong. <P>Later versions of this class will give * more control over multiple components. * This is called whenever {@link F} has an event associated with * {@code ComponentListener} interface. */ private void Adjust (ComponentEvent e) { int eid=e.getID(); if (eid == ComponentEvent.COMPONENT_RESIZED || eid == ComponentEvent.COMPONENT_SHOWN){ Component w = e.getComponent(); int MyHeight=w.getHeight(); int MyWidth = w.getWidth(); Insets I; I = F.getInsets(); int height; int width; int ypos; int room = MyHeight-I.top-I.bottom; // how much room there is in the window; boolean []flag; flag = new boolean[CC]; int i; // position within arrays mc,position,mch,mcw; // tells which component is being adjusted for ( i = 0; i < CC; i++) { flag[i]=false;// if the component's size does not fit in the window, // if we set this true, so we change the size of the // textbox to fit.
  • 65. height = mch[i]; width = mcw[i]; if (room>height){ ypos = MyHeight - height - I.top-I.bottom; } else { ypos = I.top; height = room; flag[i]=true; } int myWidth; // my real width after subtracting any insets myWidth = MyWidth - I.left - I.right; int xpos; if (width <MyWidth) { xpos=0; if (position[i] ==0){ xpos = I.left+MyWidth/2 - width /2; } else if (position[i] > 0) { xpos = I.left + position[i]; } else if (position[i]<0) { xpos = -I.right + myWidth - width + position[i]; } } else { xpos = I.left; width = MyWidth; flag[i] = true; } mc[i].setLocation(xpos,ypos); if (flag[i]) { mc[i].setSize(width,height);} } // for each component to adjust } // this is one of the events for which we could move around the component } // end of Adjust method. public void componentResized (ComponentEvent e) { Adjust(e); } public void componentMoved (ComponentEvent e) { Adjust(e); } public void componentHidden(ComponentEvent e){ Adjust(e); } public void componentShown (ComponentEvent e){ Adjust(e); } } // end of SWA class, this is the class, we are trying to demonstrate.
  • 66. /** * For testing, the string to be put in the {@code JTextArea} on the screen. */ static String FT = "ONE True --- ONE ONE ----- ONE True ----- ONE True ---- ONE True"+'n'+ "TWO True --- TWO TWO ----- TWO True ----- TWO True ---- TWO True"+'n'+ "THREE True --- THREE THREE ----- THREE True ----- THREE True ---- THREE True"+'n'+ "FOUR True --- FOUR FOUR ----- FOUR True ----- FOUR True ---- FOUR True"; static String ST = "FIVE True n"+ "SIX True n"+ "SEVEN Truen"+ "EIGHT True"; public static void main (String [] args) throws IOException { Debug = new Debu(); f = new JFrame(); f.setSize(400,500); f.setLayout(null); SF = new Font ("Arial",Font.BOLD,24); SFM = f.getFontMetrics(SF); SWA wa = new SWA(); wa.Dx = true; wa.AM(f.getContentPane(),f); JTextArea JTA; JScrollPane J; JTA = wa.CTA(FT); J = wa.CSP(JTA,275,100); wa.addTextArea(J,0); JTA = wa.CTA(ST); J = wa.CSP(JTA,275,300); wa.addTextArea(J,-11); f.setVisible(true); f.repaint(); } // end of main } //end of program (class)
  • 67. T3 We now truly support having one SWA instance for each frame. We demonstrate having an array of Frames to show how this works. Also SWA will stack up the controls when there is not enough room at the bottom of the screen for all of them. (As we did in the T2 series, SWA has arrays to track all the controls added. Each control is entered in the mc array, along with its corresponding desired size in mcw and mcw, w ith its desired position relative to the left margin in position.) But here, SWA.Adjust implements the following pseudocode: for each control (i) try to place it based upon the position[i] specified when we added it to the frame with SWA.AddTextArea for each control previously placed (for j from 0 to i-1) see if the new control (i) conflicts with it. if so, find out how far up we have to move it so it doesn't overlap with any control. move it there T3A.java, T3T.java and T3AF.java exercises multiple SWA instances, one for each Frame or JFrame in the application program. I will focus on T3A.java and T3AF.java; these create an array of frames; A doubly-nested loop generates a set of text boxes on each frame. In T3AF, each frame uses a different font name and each text box on that frame is in a different sizes (12, 16, 24 and 32). (As I discussed in T0, one needs to get a FontMetrics for the font and frame that we are using. Thus, I modified CTA method calling sequence slightly--one passes the font that one is using along with the string. It sets the font for and gets the FontMetrics from the JTextArea that it creates.) import java.util.*; import java.awt.geom.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.awt.Color; public class T3{ /** * A simple debugging class I have been using for years.
  • 68. * I put a shortened version, so * this program is self-contained. */ static class Debu { /** * This is the debugging file; normally, one puts stuff in it * with {@link P(String} or {@link P(String,booolean)}; but, one * can write directly to it, if convenient. */ public PrintWriter D; /** * Create/open debugging file, {@link D}. */ Debu (){ try { D = new PrintWriter (new FileOutputStream("T3.out")); } catch (IOException e) { System.out.println ("cannot open debug file"); } } /** * output string to debugging file, with a new line. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s) { D.println (s);D.flush(); } /** * output string to debugging file, with a new line only if {@code b} * is true. * <BR> * Flushes output, * just in case program crashes afterward. */ public void P(String s,boolean b) { if (b) {D.println (s);}else { D.print(s);}D.flush(); } /** * Simply, get Hash code and then call {@code toString()} on the {@code Object} but shorten * overlong results -- also it protects from Null Exception if object is * null. * @param O - that which is to be output to debugging file * @returns {@code String} which will usually be sent to {@code P}. */ public String SS (Object O) { if (O != null) { String RT = O.hashCode()+": "+O.toString(); if (RT.length() > 57) { return RT.substring(0,57);
  • 69. } else { return RT; } } else { return "null"; } } // end of SS method } // end of Debug class static JFrame f; static Debu Debug; /** * We will use this font throughout this example. */ static Font SF; /** * The {@code FontMetrics} for the standard font {@link SF} * being used for text areas. */ static FontMetrics SFM; /** * see the discussion in the companion files {@code T1} and {@code T1.pptx}. */ static class SWA implements ComponentListener { /** * if on, then, we will write some stuff to the debugging file,using my * {@code Debug} class. */ boolean Dx=false; /** * To Whom I belong. If this is a {@code JFrame} or {@code Frame}, we will * call {@code getInsets} to get the proper width and height without the * "decorations". See the discussion at the beginning of the {@code AWT} * class {@code Frame}. Otherwise, {@code F} will be empty and we will * just have C set. If we are using a frame, the caller, will have to get * the component by calling {@code getContentPane()}. */ Frame F; /** * To Whom I belong. If it is a {@code JFrame} or {@code Frame}, the * caller will have to: * <BR> * call {@code getContentPane()}. * @see F */ Container MC;
  • 70. /** * This associates this with the frame or other thing containing the * components being adjusted. */ public void AM (Container WTA, JFrame F) { MC = WTA; this.F=F; F.addComponentListener(this); } /** * This array contains the component that we are * adjusting and displaying here . */ Component [] mc; /** * This tells how many components we have to which keep track. * Note, there are parallel arrays {@link mc}, {@link mcw}, {@link position}, * and {@link mch} **/ int CC; /** * This is the preferred width of the component added, assuming there is * enough room for it. */ int [] mcw; /** * This is the preferred height of the component added, assuming there is * enough room for it. */ int [] mch; /** * position to put {@link mc} relative to the containing window (@link MC} * <UL><LI> * If positive, will be the number of pixels of right of the left-hand side * of {@link MC} * <LI> * If negative, will give the number of pixels to the left of the right- hand * edge of the containing window (@link MC}. That is, the {@code Component} * will be kept with a certain right margin. * <LI> * If zero, will be centered like in {@code T1A.java}. * </UL> */ int []position; /** * maximum number of components we allow */
  • 71. final int MNC=1000; SWA () { mc = new Component[MNC]; mcw = new int[MNC]; mch = new int [MNC]; position = new int [ MNC]; } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. * @param position <UL><LI> position is positive, that is the number of pixels from the lower=left <LI>position is negative, then this will give the number of pixels from the right<LI>if position is zero, then it will be centered</UL>--note, it is impossible to align this precisely with the lower left hand corner. Simply have it one pixel just to the right of that. */ void addTextArea (Component JTA,int position){ this.position[CC] = position; this.mc[CC] = JTA; this.mcw[CC] = JTA.getWidth(); this.mch[CC] = JTA.getHeight(); CC++; if (MC!=null) { MC.add(JTA); } } /** * In spite of its name, will take any {@code Component} and associate it with the * frame to which this {@code SWA} is attached. * It is intended to be used by simply * passing {@code frame.getContentPane()} for the one argument, {@code JTA}. * @see AddScrollPane * @param JTA that which is to be added. */ void addTextArea(Component JTA) { addTextArea(JTA,0); } /** * Take the indicated {@code Component} and put it in a {@code JScrollPane}. * Note, programmer is responsible * for setting its location and actually adding it * to the frame to be seen to the unit. * Uses default size with which to show this for the user.