insertString() not get displayed right away in some situation
There are two java files.
1.TestPane.java
2.TestPaneDemo.java
The first one works fine. The strings are displayed one by one.
The second one, the insertString() are called by click on Button Report. The messages came out all together. Why is that? What is not doing correctly? Please help.
Testpane.java
import java.awt.*;
import java.text.SimpleDateFormat;
import java.text.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.text.*;
public class TestPane extends JTextPane
{
public TestPane()
{
super();
}
public TestPane(StyledDocument doc) {
super(doc);
}
public void append( String s )// this is the simple one
{
try
{
Document doc = getDocument();
int len = doc.getLength();
doc.insertString( len, s, null );
// Scroll so that the new text is visible
Rectangle r = modelToView(doc.getLength());
if ( r != null )
{
scrollRectToVisible(r);
}
}
catch ( BadLocationException e ) {
System.out.println("Failed to append text: " + e );
e.printStackTrace();
}
}
public void append( Color c, String s )// this is the one I need
{
try
{
Document doc = getDocument();
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,StyleConstants.Foreground, c);
int len = doc.getLength();
doc.insertString( len, s, aset );
// Scroll so that the new text is visible
Rectangle r = modelToView(doc.getLength());
if ( r != null )
{
scrollRectToVisible(r);
}
}
catch ( BadLocationException e ) {
System.out.println("Failed to append text: " + e );
}
}
// Testing method
public static void main(String[] args)
{
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Test JTextPane with append");
//
TestPane tp = new TestPane();
tp.setText( "" );
tp.setEditable( false );
JScrollPane sp = new JScrollPane( tp );
sp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
Label msg = new Label( "Messages" );
msg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) );
msg.setForeground( Color.red );
JPanel p_msg = new JPanel( new BorderLayout() );
p_msg.add( "North", msg );
p_msg.add( "Center", sp );
//
f.add( "Center", p_msg );
f.add( "West", new Label("") );
f.add( "East", new Label("") );
int wid = 400;
int hei = 600;
f.setSize( wid, hei );
f.setVisible(true);
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
for ( int i=0; i<50; i++ )
{
String timeString = fmt.format(new Date());
tp.append( "Time=" + timeString + "\n" );
tp.append( Color.red, timeString + "\n" );
tp.append( Color.blue, "abcdefg" );
tp.append( " ..............\n" );
}
tp.setCaretPosition(tp.getDocument().getLength());
}
}// class TestPane
TestPaneDemo.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;
//import java.io.*;
import java.text.*;
import javax.swing.*;
import javax.swing.text.*;
//import javax.swing.event.*;
public class TestPaneDemo extends JFrame
implements ActionListener
{
// Action Buttons
JButton b_report = null;
JButton b_reset = null;
JButton b_exit = null;
TestPane ta = null;// Was TextArea, message area,
public TestPaneDemo()// construtor
{
JFrame f = new JFrame("Test JTextPane with append");
ta = new TestPane();
ta.setText( "" );
ta.setFont( new Font("Monospaced", Font.PLAIN, 12) );
ta.setEditable( false );
JScrollPane sp = new JScrollPane( ta );
sp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
Label msg = new Label( "Messages" );
msg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) );
msg.setForeground( Color.red );
JPanel p_msg = new JPanel( new BorderLayout() );
p_msg.add( "North", msg );
p_msg.add( "Center", sp );
// Button panel
JPanel button_p = new JPanel();
b_exit = new JButton( "Exit" );
b_report = new JButton( "Report" );
b_reset = new JButton( "Reset" );
button_p.setLayout( new FlowLayout( FlowLayout.RIGHT, 15, 15 ) );
button_p.add( b_report );
button_p.add( b_reset );
button_p.add( b_exit );
b_reset.addActionListener(this);
b_report.addActionListener(this);
b_exit.addActionListener(this);
button_p.setFont( new Font( "SansSerif", Font.BOLD, 16 ) );
//
f.add( "Center", p_msg );
f.add( "West", new Label("") );
f.add( "East", new Label("") );
f.add( "South", button_p);
int wid = 400;
int hei = 300;
f.setSize( wid, hei );
f.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource();
if ( obj instanceof JButton )
{
JButton b = (JButton) obj;
if ( b == b_exit ) {System.exit(0);}
else if ( b == b_reset ) {ta.setText( "" );}
else if ( b == b_report ) {
ta.setText( "" );
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
for ( int i=0; i<50; i++ )
{
String timeString = fmt.format(new Date());
ta.append( "Time=" + timeString + "\n" );
ta.append( Color.red, timeString + "\n" );
ta.append( Color.blue, "abcefg" );
ta.append( " ..............\n" );
}
return;
}
}
}
// Testing method
public static void main(String[] args)
{
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
TestPaneDemo demo = new TestPaneDemo();
}
} // class TestPaneDemo
[6245 byte] By [
chouannaa] at [2007-11-26 16:40:54]

# 1
First of all, next time you post code please use the code tags so that it is formatted properly. It makes it much easier to read.
Secondly, your code didn't compile correctly because you cannot add components directly to a JFrame, you have to add them to the contentPane of a JFrame.
Third, your code DID run correctly!
Your computer is just so fast that the time appears to be the same for all append calls. I purposely ran a resource intensive process on my computer and THEN ran your program to find that the time updated itself between iterations.
Other than the compile errors that were easily fixed, your code is fine.
# 2
Quit cluttering the forum with multiple postings. Thats a definite way not to get help in the future.You've been told multiple times how to use the "Code Formatting Tags" and you still refuse to use them. Again, a good way not to get help in the future.
# 3
Thanks for the help. Though I did not get compile error on direct adding components to JFrame.
Now I have modified the two files with getContentPane();
Run TestPane, you can visually see the messages come out line by line.
Run TestPaneDemo you see the messages coming out all together. It is still not working. In my real application, the reporting messages should be out one by one.
Following is the code
TestPane.java
import java.awt.*;
import java.text.SimpleDateFormat;
import java.text.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.text.*;
public class TestPane extends JTextPane
{
public TestPane()
{
super();
}
public TestPane(StyledDocument doc) {
super(doc);
}
public void append( String s )// this is the simple one
{
try
{
Document doc = getDocument();
int len = doc.getLength();
doc.insertString( len, s, null );
// Scroll so that the new text is visible
Rectangle r = modelToView(doc.getLength());
if ( r != null )
{
scrollRectToVisible(r);
}
}
catch ( BadLocationException e ) {
System.out.println("Failed to append text: " + e );
e.printStackTrace();
}
}
public void append( Color c, String s )// this is the one I need
{
try
{
Document doc = getDocument();
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,StyleConstants.Foreground, c);
int len = doc.getLength();
doc.insertString( len, s, aset );
// Scroll so that the new text is visible
Rectangle r = modelToView(doc.getLength());
if ( r != null )
{
scrollRectToVisible(r);
}
}
catch ( BadLocationException e ) {
System.out.println("Failed to append text: " + e );
}
}
// Testing method
public static void main(String[] args)
{
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Test JTextPane with append");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//
TestPane tp = new TestPane();
tp.setText( "" );
tp.setEditable( false );
JScrollPane sp = new JScrollPane( tp );
sp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
Label msg = new Label( "Messages" );
msg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) );
msg.setForeground( Color.red );
JPanel p_msg = new JPanel( new BorderLayout() );
p_msg.add( "North", msg );
p_msg.add( "Center", sp );
// Do not add components direct to JFrame!
Container content = f.getContentPane();
content.add( "Center", p_msg );
content.add( "West", new Label("") );
content.add( "East", new Label("") );
int wid = 400;
int hei = 600;
f.setSize( wid, hei );
f.setVisible(true);
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
for ( int i=0; i<50; i++ )
{
String timeString = fmt.format(new Date());
tp.append( "Time=" + timeString + "\n" );
tp.append( Color.red, timeString + "\n" );
tp.append( Color.blue, "abcdefg" );
tp.append( " ..............\n" );
}
tp.setCaretPosition(tp.getDocument().getLength());
}
}// class TestPane
TestPaneDemo.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import javax.swing.*;
import javax.swing.text.*;
public class TestPaneDemo extends JFrame
implements ActionListener
{
// Action Buttons
JButton b_report = null;
JButton b_reset = null;
TestPane ta = null;// Was TextArea, message area,
public TestPaneDemo()// construtor
{
ta = new TestPane();
ta.setText( "" );
ta.setFont( new Font("Monospaced", Font.PLAIN, 12) );
ta.setEditable( false );
JScrollPane sp = new JScrollPane( ta );
sp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
Label msg = new Label( "Messages" );
msg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) );
msg.setForeground( Color.red );
JPanel p_msg = new JPanel( new BorderLayout() );
p_msg.add( "North", msg );
p_msg.add( "Center", sp );
// Button panel
JPanel button_p = new JPanel();
b_report = new JButton( "Report" );
b_reset = new JButton( "Reset" );
button_p.setLayout( new FlowLayout( FlowLayout.RIGHT, 15, 15 ) );
button_p.add( b_report );
button_p.add( b_reset );
b_reset.addActionListener(this);
b_report.addActionListener(this);
button_p.setFont( new Font( "SansSerif", Font.BOLD, 16 ) );
/*
your code didn't compile correctly because you cannot add components directly to a JFrame,
you have to add them to the contentPane of a JFrame.
*/
JFrame f = new JFrame("Test JTextPane with append");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
content.add( "Center", p_msg );
content.add( "West", new Label("") );
content.add( "East", new Label("") );
content.add( "South", button_p);
int wid = 400;
int hei = 300;
f.setSize( wid, hei );
f.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource();
if ( obj instanceof JButton )
{
JButton b = (JButton) obj;
if ( b == b_reset ) {ta.setText( "" );}
else if ( b == b_report ) {
ta.setText( "" );
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
for ( int i=0; i<50; i++ )
{
String timeString = fmt.format(new Date());
ta.append( "Time=" + timeString + "\n" );
ta.append( Color.red, timeString + "\n" );
ta.append( Color.blue, "abcefg" );
ta.append( " ..............\n" );
}
return;
}
}
}
// Testing method
public static void main(String[] args)
{
TestPaneDemo demo = new TestPaneDemo();
}
} // class TestPaneDemo
# 4
> Secondly, your code didn't compile correctly because> you cannot add components directly to a JFrame, you> have to add them to the contentPane of a JFrame.FYI, that's only true on JDK < 1.5
# 5
I am using JDK 1.4.2 . No wonder I did not get the compile error.Thanks a lot.
# 6
> Run TestPane, you can visually see the messages come out line by line.
On my computer they come out at the same time. As was explained to you earlier. When you add text to the text pane in a loop, then the messages will be painted as they are added, but since the computer is so fast at painting it looks like they come out together.
> Run TestPaneDemo you see the messages coming out all together.
Same comment as above.
If you want messages to come out one at a time then you need to delay the time the messages are added to the text pane. This posting show how this might work:
http://forum.java.sun.com/thread.jspa?forumID=57&threadID=689486
# 7
Your computer is just so fast that the time appears to be the same for all append calls.
The messages are appearing very fast, though you can tell they do not come out all together for TestPane. I can see the vertical scroll bar moving down as the messages are being displayed.Do you see this?
For TestPaneDemo, the scroll bar just came out at the end. They act differently in this sense.
In my real application, the coding is similar to TestPaneDemo, It processes several files. Each one takes about one second. Message is issued after every file was processed. I expect them came out one by one. I was using TextArea before, it was fine. Then I changed to JTextPane, because I need color. Then the behavior changed. I need to wait for sevral seconds to see the messages. They came out all together. It is annoying.
# 8
> It processes several files. Each one takes about one second
And I told you a week ago that you need to be running this code in a separate Thread. I even gave you a working example that simulated a one second delay.
> It is annoying.
Yes it is annoying when you don't listen to the advice given and you keep wasting our time.