Complete ScrollPane Control (SSCCE)

Alright.. you can see my original ideas about how I want scrolling to happen in a real-time situation in my first post:

http://forum.java.sun.com/thread.jspa?threadID=5168056

I've since tried to move forward but immediately hit another snag.

Problem: Now I can keep the text from jumping as it is inserted and deleted, but when I resize the JFrame in the SSCCE below MyTextPane calculates the preferredSize based on if the text pane had word wrapping on. So this causes my scrollbar to be WAY off if you shorten the width of the JFrame. I've tried to changing up my "Dimension getPreferredSize()" method in MyTextPane, but for some reason I can't get it to work.

Example:

1. Open the program and "add" 10 lines. Everything is fine here.. I do not want the scrollbar to scroll with the text because this is trivial to program. Verify that the vertical scrollbar only goes down to 1 line past the last text in the MyTextPane.

2. Now take the left edge of the JFrame and shorten the width of the JFrame as much as it will allow you. Now verify that the vertical scrollbar is WAY too long for the text. This is because the overloaded getPreferredSize() in MyTextPane doesn't taken into account if the super.getPreferredSize() has sizes bigger than maxWidth or maxSize.

Now, I've experimented endlessly with the getPreferredSize() in MyTextPane and I cannot find a suitable answer to this problem.

If any of this seems insane, and there is an easier approach to all of this (if you even understand what I am aiming for) I am all ears. I will keep you all posted of any breakthroughs! :-)

Thanks guys,

Js

import java.awt.Dimension;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ComponentAdapter;

import java.awt.event.ComponentEvent;

import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;

import javax.swing.JLayeredPane;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JScrollPane;

import javax.swing.JTextPane;

import javax.swing.text.BadLocationException;

import javax.swing.text.Document;

publicclass DeleteTextResetExampleextends JFrame

{

//STATICS

privatestaticfinal String LINE_STR ="This is a new line and is amazing for me to see!\n";

//DATA

privateint lineCount;

privateint maxLineWidth;

//GUI

private JLayeredPane myLayeredPane;

private JScrollPane scrollPane;

private MyTextPane textPane;

//MENU

private JMenuBar mainMenuBar;

private JMenu actionMenu;

private JMenuItem addLineMenuItem;

private JMenuItem delLineMenuItem;

public DeleteTextResetExample()

{

this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

this.setContentPane(getMyLayeredPane());

this.setJMenuBar(getMainMenuBar());

this.pack();

this.setVisible(true);

}

//GUI

private JLayeredPane getMyLayeredPane()

{

if(myLayeredPane ==null)

{

myLayeredPane =new JLayeredPane();

myLayeredPane.setPreferredSize(new Dimension(200,100));

myLayeredPane.add(getScrollPane(),new Integer(0));

myLayeredPane.addComponentListener(new ComponentAdapter()

{

publicvoid componentResized(ComponentEvent e)

{

System.out.println("LAYERED PANE RESIZED");

//First make sure the objects inside the layered pane are in the correct spot

getScrollPane().setBounds(0,0,myLayeredPane.getWidth(),myLayeredPane.getHeight());

//Force the size of the Non-Shrinking Text Pane to either the size of the text or the size of

//the layered pane depending on who is bigger.

int newHeight = lineCount*getTextPane().getFontMetrics(getTextPane().getFont()).getHeight();

int newWidth = maxLineWidth;

System.out.println("TEXT HEIGHT: " + newHeight);

System.out.println("PANE HEIGHT: " + myLayeredPane.getHeight());

System.out.println("TEXT WIDTH: " + newWidth);

System.out.println("PANE WIDTH: " + myLayeredPane.getWidth());

if(myLayeredPane.getHeight() > newHeight)

{

System.out.println("\tHEIGHT: FRAME IS BIGGER THAN TEXT");

newHeight = myLayeredPane.getHeight();

}

else

{

System.out.println("\tHEIGHT: TEXT IS BIGGER THAN FRAME");

}

if(myLayeredPane.getWidth() > newWidth)

{

System.out.println("\tWIDTH: FRAME IS BIGGER THAN TEXT");

newWidth = myLayeredPane.getWidth();

}

else

{

System.out.println("\tWIDTH: TEXT IS BIGGER THAN FRAME");

}

System.out.println();

//Now force the size to the correct size

getTextPane().forceSize(new Dimension(newWidth,newHeight));

}

});

}

return myLayeredPane;

}

private JScrollPane getScrollPane()

{

if(scrollPane ==null)

{

scrollPane =new JScrollPane(getTextPane());

}

return scrollPane;

}

private MyTextPane getTextPane()

{

if(textPane ==null)

{

textPane =new MyTextPane();

textPane.setEditable(false);

}

return textPane;

}

//MENU

private JMenuBar getMainMenuBar()

{

if(mainMenuBar ==null)

{

mainMenuBar =new JMenuBar();

mainMenuBar.add(getActionMenu());

}

return mainMenuBar;

}

private JMenu getActionMenu()

{

if(actionMenu ==null)

{

actionMenu =new JMenu("Action");

actionMenu.add(getAddLineMenuItem());

actionMenu.add(getDelLineMenuItem());

}

return actionMenu;

}

private JMenuItem getAddLineMenuItem()

{

if(addLineMenuItem ==null)

{

addLineMenuItem =new JMenuItem("Add Line");

addLineMenuItem.addActionListener(new ActionListener()

{

publicvoid actionPerformed(ActionEvent e)

{

Thread t =new Thread()

{

publicvoid run()

{

Document d = getTextPane().getDocument();

try

{

//Insert the string

d.insertString(d.getLength(), LINE_STR,null);

//Up our line count

lineCount++;

//Update our max line width if necessary

Rectangle2D strBounds = getTextPane().getFontMetrics(getTextPane().getFont()).getStringBounds(LINE_STR,getTextPane().getGraphics());

int strWidth = (int)strBounds.getWidth();

if(strWidth > maxLineWidth)

{

maxLineWidth = strWidth;

}

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return addLineMenuItem;

}

private JMenuItem getDelLineMenuItem()

{

if(delLineMenuItem ==null)

{

delLineMenuItem =new JMenuItem("Delete Line");

delLineMenuItem.addActionListener(new ActionListener()

{

publicvoid actionPerformed(ActionEvent e)

{

Thread t =new Thread()

{

publicvoid run()

{

Document d = getTextPane().getDocument();

try

{

d.remove(d.getLength()-LINE_STR.length(),LINE_STR.length());

lineCount--;

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return delLineMenuItem;

}

//MAIN

publicstaticvoid main(String args[])

{

new DeleteTextResetExample();

}

privateclass MyTextPaneextends JTextPane

{

//DATA

privateint maxHeight;

privateint maxWidth;

//This keeps the pane from resizing the width to the viewport(stops word wrapping)

publicboolean getScrollableTracksViewportWidth()

{

returnfalse;

}

//This keeps the size of the text pane from ever getting smaller

publicvoid setSize(Dimension d)

{

if(d.width > maxWidth)

{

maxWidth = d.width;

}

if(d.height > maxHeight)

{

maxHeight = d.height;

}

System.out.println("SETTING SIZE: " + maxWidth +"," + maxHeight);

System.out.println();

super.setSize(new Dimension(maxWidth,maxHeight));

}

//This tells the viewport and others that we want to have a preferred size at least as big as our

//text pane, but we cannot set d.width = maxWidth or d.height = maxHeight for some reason.

public Dimension getPreferredSize()

{

Dimension d =new Dimension(super.getPreferredSize());

if(d.width < maxWidth)

{

d.width = maxWidth;

}

if(d.height < maxHeight)

{

d.height = maxHeight;

}

System.out.println("GETTING PREFERRED SIZE: " + d.width +"," + d.height);

System.out.println();

return d;

}

//This forces the text pane to any size decided. This is the only way to make the text pane smaller.

publicvoid forceSize(Dimension d)

{

System.out.println("FORCING SIZE: " + d.width +"," + d.height);

System.out.println();

maxWidth = d.width;

maxHeight = d.height;

super.setSize(d);

}

}

}

[17026 byte] By [JSnakea] at [2007-11-27 3:38:03]
# 1
Has anyone figured out why when the document gets updated, the java people don't use setPreferredSize(Dimension) ? This is confusing me to no end.-Js
JSnakea at 2007-7-12 8:41:21 > top of Java-index,Desktop,Core GUI APIs...
# 2

this seems to fix the 'extra linespace'

public Dimension getPreferredSize()

{

Dimension d = new Dimension(super.getPreferredSize());

if(d.width < maxWidth)

{

//d.width = maxWidth;

maxWidth = d.width;

}

if(d.height < maxHeight)

{

//d.height = maxHeight;

maxHeight = d.height;

}

System.out.println("GETTING PREFERRED SIZE: " + d.width + "," + d.height);

System.out.println();

return d;

}

but it produces other problems which you'll see when the program opens

Michael_Dunna at 2007-7-12 8:41:21 > top of Java-index,Desktop,Core GUI APIs...
# 3

Ty Michael_Dunn, you are right. But you are also right about the problems that the fix causes.

I've actually gotten one giant step closer. See... I was not taking into account the insets of my text pane and THAT was what was causing the "word wrapped" preferred size even when there was no word wrap. I was setting the size so that when the fixed width text pane tried to calculate its preferred size... it thought it should have wrapped text. Even though in the end I was denying it from actually wrapping the text.

Take a look at this code... it is much cleaner and almost works 100 percent.

The problem I have now:

1. Open program and "add" 10 lines. Verify that both the scrollbars are behaving correctly.

2. Move the JFrame so its left edge is located near the left edge of your screen.

3. Resize the JFrame by dragging its right edge all the way over to the right edge of your screen. Verify that you see the gray background near the right side of the text pane.

This is unwanted. I added some System.out.println()'s in there to show how the scrollpane is not being updated to the correct size, and therefore my forced resize does not work as expected.

Also verify that the old problem that started this post has been resolved as well.

Thanks!!

-Js

import java.awt.Dimension;

import java.awt.Insets;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ComponentAdapter;

import java.awt.event.ComponentEvent;

import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;

import javax.swing.JLayeredPane;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JScrollPane;

import javax.swing.JTextPane;

import javax.swing.SwingUtilities;

import javax.swing.text.BadLocationException;

import javax.swing.text.Document;

public class DeleteTextResetExample extends JFrame

{

//STATICS

private static final String LINE_STR = "This is a new line and is amazing for me to see!\n";

//DATA

private int lineCount;

private int maxLineWidth;

//GUI

private JLayeredPane myLayeredPane;

private JScrollPane scrollPane;

private MyTextPane textPane;

//MENU

private JMenuBar mainMenuBar;

private JMenu actionMenu;

private JMenuItem addLineMenuItem;

private JMenuItem delLineMenuItem;

public DeleteTextResetExample()

{

this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

this.setContentPane(getMyLayeredPane());

this.setJMenuBar(getMainMenuBar());

this.pack();

this.setVisible(true);

}

//GUI

private JLayeredPane getMyLayeredPane()

{

if(myLayeredPane == null)

{

myLayeredPane = new JLayeredPane();

myLayeredPane.setPreferredSize(new Dimension(200,100));

myLayeredPane.add(getScrollPane(), new Integer(0));

myLayeredPane.addComponentListener(new ComponentAdapter()

{

public void componentResized(ComponentEvent e)

{

SwingUtilities.invokeLater(new Runnable()

{

public void run()

{

//First make sure the objects inside the layered pane are in the correct spot

getScrollPane().setBounds(0,0,myLayeredPane.getWidth(),myLayeredPane.getHeight());

//Force the size of the Non-Shrinking Text Pane to either the size of the text or the size of

//the scrollPane

Insets insets = getTextPane().getInsets();

//Figure out the new heights for both the text and the scrollPane

int newHeight = lineCount*getTextPane().getFontMetrics(getTextPane().getFont()).getHeight() + insets.top + insets.bottom;

int newWidth = maxLineWidth + insets.left + insets.right;

int scrollPaneHeight = getScrollPane().getHeight();

if(getScrollPane().getHorizontalScrollBar().isShowing())

{

scrollPaneHeight -= getScrollPane().getHorizontalScrollBar().getHeight();

}

int scrollPaneWidth = getScrollPane().getWidth();

if(getScrollPane().getVerticalScrollBar().isShowing())

{

scrollPaneWidth -= getScrollPane().getVerticalScrollBar().getHeight();

}

System.out.println("LAYERED PANE: " + myLayeredPane.getWidth() + "," + myLayeredPane.getHeight());

System.out.println("TEXT BOUNDS: " + newWidth + "," + newHeight);

System.out.println("SCROLL PANE: " + scrollPaneWidth + "," + scrollPaneHeight);

System.out.println();

//Now compare the text bounds and the scrollpane bounds and choose to set

if(scrollPaneHeight > newHeight)

{

newHeight = scrollPaneHeight;

}

if(scrollPaneWidth > newWidth)

{

newWidth = scrollPaneWidth;

}

//Now force the size to the correct size

getTextPane().forceSize(new Dimension(newWidth,newHeight));

}

});

}

});

}

return myLayeredPane;

}

private JScrollPane getScrollPane()

{

if(scrollPane == null)

{

scrollPane = new JScrollPane(getTextPane());

}

return scrollPane;

}

private MyTextPane getTextPane()

{

if(textPane == null)

{

textPane = new MyTextPane();

textPane.setEditable(false);

}

return textPane;

}

//MENU

private JMenuBar getMainMenuBar()

{

if(mainMenuBar == null)

{

mainMenuBar = new JMenuBar();

mainMenuBar.add(getActionMenu());

}

return mainMenuBar;

}

private JMenu getActionMenu()

{

if(actionMenu == null)

{

actionMenu = new JMenu("Action");

actionMenu.add(getAddLineMenuItem());

actionMenu.add(getDelLineMenuItem());

}

return actionMenu;

}

private JMenuItem getAddLineMenuItem()

{

if(addLineMenuItem == null)

{

addLineMenuItem = new JMenuItem("Add Line");

addLineMenuItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

Thread t = new Thread()

{

public void run()

{

Document d = getTextPane().getDocument();

try

{

//Insert the string

d.insertString(d.getLength(), LINE_STR, null);

//Up our line count

lineCount++;

//Update our max line width if necessary

Rectangle2D strBounds = getTextPane().getFontMetrics(getTextPane().getFont()).getStringBounds(LINE_STR,getTextPane().getGraphics());

int strWidth = (int)strBounds.getWidth();

if(strWidth > maxLineWidth)

{

maxLineWidth = strWidth;

}

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return addLineMenuItem;

}

private JMenuItem getDelLineMenuItem()

{

if(delLineMenuItem == null)

{

delLineMenuItem = new JMenuItem("Delete Line");

delLineMenuItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

Thread t = new Thread()

{

public void run()

{

Document d = getTextPane().getDocument();

try

{

d.remove(d.getLength()-LINE_STR.length(),LINE_STR.length());

lineCount--;

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return delLineMenuItem;

}

//MAIN

public static void main(String args[])

{

new DeleteTextResetExample();

}

private class MyTextPane extends JTextPane

{

//DATA

private int maxHeight;

private int maxWidth;

//This keeps the pane from resizing the width to the viewport(stops word wrapping)

public boolean getScrollableTracksViewportWidth()

{

return false;

}

//This keeps the size of the text pane from ever getting smaller

public void setSize(Dimension d)

{

if(d.width > maxWidth)

{

maxWidth = d.width;

}

if(d.height > maxHeight)

{

maxHeight = d.height;

}

super.setSize(new Dimension(maxWidth,maxHeight));

}

//This tells the viewport and others that we want to have a preferred size at least as big as our

//text pane, but we cannot set d.width = maxWidth or d.height = maxHeight for some reason.

public Dimension getPreferredSize()

{

Dimension d = super.getPreferredSize();

if(d.width < maxWidth)

{

d.width = maxWidth;

}

if(d.height < maxHeight)

{

d.height = maxHeight;

}

return d;

}

//This forces the text pane to any size decided. This is the only way to make the text pane smaller.

public void forceSize(Dimension d)

{

maxWidth = d.width;

maxHeight = d.height;

super.setSize(d);

}

}

}

JSnakea at 2007-7-12 8:41:21 > top of Java-index,Desktop,Core GUI APIs...
# 4
I accidently left the SwingUtilities.InvokeLater() call in the component resized method.. that should not be there... it was just a test to see if it would run my code in order the way I thought it should run.. but it does not help.-Js
JSnakea at 2007-7-12 8:41:21 > top of Java-index,Desktop,Core GUI APIs...
# 5

Ok. I have solved the problem. In case anyone EVER needs to have this kind of control over their scrolling of a TextComponent.

From the last SSCCE I have made the following changes:

1. Removed the unwanted SwingUtilities.InvokeLater() call in the overloaded componentResized(ComponentEvent e) method of the JLayeredPane.

2. The problem with the gray rectangle was because I was mis-calculating the scrollPaneWidth in the overloaded componentResized(ComponentEvent e) method of the JLayeredPane.

3. I added the insets into the scrollPaneWidth and scrollPaneHeight calculations and this makes the scrollbars behave correctly.

Ok all! I think that's it. Thanks!

-Js

import java.awt.Dimension;

import java.awt.Insets;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ComponentAdapter;

import java.awt.event.ComponentEvent;

import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;

import javax.swing.JLayeredPane;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JScrollPane;

import javax.swing.JTextPane;

import javax.swing.text.BadLocationException;

import javax.swing.text.Document;

public class DeleteTextResetExample extends JFrame

{

//STATICS

private static final String LINE_STR = "This is a new line and is amazing for me to see!\n";

//DATA

private int lineCount;

private int maxLineWidth;

//GUI

private JLayeredPane myLayeredPane;

private JScrollPane scrollPane;

private MyTextPane textPane;

//MENU

private JMenuBar mainMenuBar;

private JMenu actionMenu;

private JMenuItem addLineMenuItem;

private JMenuItem delLineMenuItem;

public DeleteTextResetExample()

{

this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

this.setContentPane(getMyLayeredPane());

this.setJMenuBar(getMainMenuBar());

this.pack();

this.setVisible(true);

}

//GUI

private JLayeredPane getMyLayeredPane()

{

if(myLayeredPane == null)

{

myLayeredPane = new JLayeredPane();

myLayeredPane.setPreferredSize(new Dimension(200,100));

myLayeredPane.add(getScrollPane(), new Integer(0));

myLayeredPane.addComponentListener(new ComponentAdapter()

{

public void componentResized(ComponentEvent e)

{

//First make sure the objects inside the layered pane are in the correct spot

getScrollPane().setBounds(0,0,myLayeredPane.getWidth(),myLayeredPane.getHeight());

//Force the size of the Non-Shrinking Text Pane to either the size of the text or the size of

//the scrollPane

Insets textInsets = getTextPane().getInsets();

Insets scrollInsets = getScrollPane().getInsets();

//Figure out the new heights for both the text and the scrollPane

int newHeight = lineCount*getTextPane().getFontMetrics(getTextPane().getFont()).getHeight() + textInsets.top + textInsets.bottom;

int newWidth = maxLineWidth + textInsets.left + textInsets.right;

int scrollPaneHeight = getScrollPane().getHeight() - scrollInsets.top - scrollInsets.bottom;

if(getScrollPane().getHorizontalScrollBar().isShowing())

{

scrollPaneHeight -= getScrollPane().getHorizontalScrollBar().getHeight();

}

int scrollPaneWidth = getScrollPane().getWidth() - scrollInsets.left - scrollInsets.right;

if(getScrollPane().getVerticalScrollBar().isShowing())

{

scrollPaneWidth -= getScrollPane().getVerticalScrollBar().getWidth();

}

//Now compare the text bounds and the scrollpane bounds and choose to set

if(scrollPaneHeight > newHeight)

{

newHeight = scrollPaneHeight;

}

if(scrollPaneWidth > newWidth)

{

newWidth = scrollPaneWidth;

}

//Now force the size to the correct size

getTextPane().forceSize(new Dimension(newWidth,newHeight));

}

});

}

return myLayeredPane;

}

private JScrollPane getScrollPane()

{

if(scrollPane == null)

{

scrollPane = new JScrollPane(getTextPane());

}

return scrollPane;

}

private MyTextPane getTextPane()

{

if(textPane == null)

{

textPane = new MyTextPane();

textPane.setEditable(false);

}

return textPane;

}

//MENU

private JMenuBar getMainMenuBar()

{

if(mainMenuBar == null)

{

mainMenuBar = new JMenuBar();

mainMenuBar.add(getActionMenu());

}

return mainMenuBar;

}

private JMenu getActionMenu()

{

if(actionMenu == null)

{

actionMenu = new JMenu("Action");

actionMenu.add(getAddLineMenuItem());

actionMenu.add(getDelLineMenuItem());

}

return actionMenu;

}

private JMenuItem getAddLineMenuItem()

{

if(addLineMenuItem == null)

{

addLineMenuItem = new JMenuItem("Add Line");

addLineMenuItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

Thread t = new Thread()

{

public void run()

{

Document d = getTextPane().getDocument();

try

{

//Insert the string

d.insertString(d.getLength(), LINE_STR, null);

//Up our line count

lineCount++;

//Update our max line width if necessary

Rectangle2D strBounds = getTextPane().getFontMetrics(getTextPane().getFont()).getStringBounds(LINE_STR,getTextPane().getGraphics());

int strWidth = (int)strBounds.getWidth();

if(strWidth > maxLineWidth)

{

maxLineWidth = strWidth;

}

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return addLineMenuItem;

}

private JMenuItem getDelLineMenuItem()

{

if(delLineMenuItem == null)

{

delLineMenuItem = new JMenuItem("Delete Line");

delLineMenuItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

Thread t = new Thread()

{

public void run()

{

Document d = getTextPane().getDocument();

try

{

d.remove(d.getLength()-LINE_STR.length(),LINE_STR.length());

lineCount--;

}

catch(BadLocationException ble)

{

ble.printStackTrace();

}

}

};

t.start();

}

});

}

return delLineMenuItem;

}

//MAIN

public static void main(String args[])

{

new DeleteTextResetExample();

}

private class MyTextPane extends JTextPane

{

//DATA

private int maxHeight;

private int maxWidth;

//This keeps the pane from resizing the width to the viewport(stops word wrapping)

public boolean getScrollableTracksViewportWidth()

{

return false;

}

//This keeps the size of the text pane from ever getting smaller

public void setSize(Dimension d)

{

if(d.width > maxWidth)

{

maxWidth = d.width;

}

if(d.height > maxHeight)

{

maxHeight = d.height;

}

super.setSize(new Dimension(maxWidth,maxHeight));

}

//This tells the viewport and others that we want to have a preferred size at least as big as our

//text pane, but we cannot set d.width = maxWidth or d.height = maxHeight for some reason.

public Dimension getPreferredSize()

{

Dimension d = super.getPreferredSize();

if(d.width < maxWidth)

{

d.width = maxWidth;

}

if(d.height < maxHeight)

{

d.height = maxHeight;

}

return d;

}

//This forces the text pane to any size decided. This is the only way to make the text pane smaller.

public void forceSize(Dimension d)

{

maxWidth = d.width;

maxHeight = d.height;

super.setSize(d);

}

}

}

JSnakea at 2007-7-12 8:41:21 > top of Java-index,Desktop,Core GUI APIs...