How to append to textarea immediately?

S

Sal

In the following test applet, I would like to have the "Begin counting
" display immediately, and the "End counting" to display when
finished, instead the applet waits until the end of the counting loop
and then displays the text all at once. How can I get it to work
properly?

public class Test extends JApplet {



JScrollPane scrollPane;

JTextArea textArea;



Color darkGreen = new Color( 0, 160, 0 ); //medium dark green



int nbrOfTimes = 0x7fffffff;



private void setNativeLookAndFeel() {

try {


UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch(Exception e) {

textArea.append("Error setting native LAF: " + e + "\n");

}

}



public void init() {

setNativeLookAndFeel();

Container cp = getContentPane();

cp.setBackground( darkGreen );

cp.setLayout( new FlowLayout() );


textArea = new JTextArea(30, 40);

scrollPane = new JScrollPane();

cp.add ( new JScrollPane( textArea ) );

textArea.setEditable( false );
textArea.append( "Begin counting " + nbrOfTimes +" \n" ); //
<------ look here
int ctr = 0;
while( ++ctr < nbrOfTimes );
textArea.append( "End counting " + ctr +" \n" );
// <------- look here
}

}
 
J

Joshua Cranmer

In the following test applet, I would like to have the "Begin counting
" display immediately, and the "End counting" to display when
finished, instead the applet waits until the end of the counting loop
and then displays the text all at once. How can I get it to work
properly?

Answer the following questions:
1. What are the methods called over the lifecycle of an applet, and in
what order?
2. On what thread or threads are these methods called?
3. When is the content of an applet actually displayed?

If you can correctly answer all three questions, you should realize why
the text displays all at once. Moving some of the code elsewhere will
ameliorate this problem; which code and where is left as an exercise to
the reader.
 
S

Sal

Answer the following questions:
1. What are the methods called over the lifecycle of an applet, and in
what order?
2. On what thread or threads are these methods called?
3. When is the content of an applet actually displayed?

If you can correctly answer all three questions, you should realize why
the text displays all at once. Moving some of the code elsewhere will
ameliorate this problem; which code and where is left as an exercise to
the reader.

Thanks for your reply. You are very lucky as it's obvious you were
never a beginner.
 
J

Jeff Higgins

Thanks for your reply. You are very lucky as it's obvious you were
never a beginner.

A good place for beginners is the Java Tutorials.
<http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/index.html>

Under the section "Trails Coverings the Basics",
"Deployment" includes a trail on Java Applets.

Under the section "Creating a GUI with Swing" you can learn about Text
Components and Events.

As always:
The Java SE 6 Documentation
<http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/> and
The Java SE 6 API Specification
<http://download-llnw.oracle.com/docs/cd/E17409_01/javase/6/docs/api/>
 
J

Jeff Higgins

Thanks for your reply. You are very lucky as it's obvious you were
never a beginner.

Many of the more experienced readers of this group began at the
beginning and worked through the basics by reading the documentation and
writing code and experimenting. A beginner following this path will
quickly become confident in their knowledge of the basics. See my other
post for pointers toward the beginning.
 
S

Sal

Many of the more experienced readers of this group began at the
beginning and worked through the basics by reading the documentation and
writing code and experimenting. A beginner following this path will
quickly become confident in their knowledge of the basics. See my other
post for pointers toward the beginning.

Thanks Jeff, but all I have to say was that learning C++ was a helluva
lot easier. And don't try to tell me that Java is more complicated.
BTW, I was always to get straightforward answers on comp.lang.c++.
 
J

Jeff Higgins

Thanks Jeff, but all I have to say was that learning C++ was a helluva
lot easier. And don't try to tell me that Java is more complicated.
BTW, I was always to get straightforward answers on comp.lang.c++.

Huh. It's been a long time, but I seem to remember getting a lot of RTFM
on the C/C++ groups. I bought the FMs; 0-470-84573-2, and 0-470-84674-7,
spent months reading them and moved to Java. :)

I still have them, in good condition, if you know someone who would like
to purchase them.
 
M

markspace

Sal said:
public void init() {
Container cp = getContentPane();
cp.setBackground( darkGreen );
cp.setLayout( new FlowLayout() );
textArea = new JTextArea(30, 40);
scrollPane = new JScrollPane();
cp.add ( new JScrollPane( textArea ) );
textArea.setEditable( false );
textArea.append( "Begin counting " + nbrOfTimes +" \n" ); //
<------ look here
int ctr = 0;
while( ++ctr < nbrOfTimes );
textArea.append( "End counting " + ctr +" \n" );


Swing code like that above must be executed on the EDT, or it ain't
going to work. Building on what Jeff Higgins wrote, here's a direct
link to an example which builds a very simple GUI on the EDT:

<http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/deployment/applet/getStarted.html>

You should study that, the rest of the section there on "Applets", and
read through the Concurrency in Swing tutorial:

<http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/concurrency/index.html>

It's a pain in the rear but there isn't any other way. You're totally
stuck until you understand this stuff; we can't write ALL your code for
you. Once you get through with that, here's what I think a basic plan
would be:

1. Construct the first part of your GUI on the EDT as shown in the
example, up to where you append "Begin Counting" to the text area.

2. Find the "long task" part of your GUI; in your example it's that
while loop. That needs to be done OFF the GUI thread or it's going to
block all updates, including displaying the part of the GUI you just
made in #1.

3. Then, when #2 is done, display your final update(s) on the EDT.

Use a SwingWorker for the long task, it's the easiest way. It'll
execute long tasks "in the background" more or less automatically for
you, then run a foreground process on the EDT when it's done. Something
like:

import javax.swing.JTextArea;
import javax.swing.SwingWorker;

public class MyWorker extends SwingWorker {
JTextArea textArea;
int ctr;
@Override
protected Object doInBackground()
throws Exception
{
// your long task here
while( ++ctr < 1000000 );
return null;
}

@Override
protected void done() {
textArea.append( "End counting " + ctr +" \n" );
}
}

That should give you enough to get something done on your own, although
you've got a fair amount of reading to do. Once you get that done and
write the improved version of you code, let us know how you are faring.

(I realize JTextArea.append() is thread safe, just in general you want
to know how to execute code on the EDT after completing some backgound
task.)
 
A

Arne Vajhøj

Thanks Jeff, but all I have to say was that learning C++ was a helluva
lot easier. And don't try to tell me that Java is more complicated.
BTW, I was always to get straightforward answers on comp.lang.c++.

In most cases you will also get straightforward answers here, but
sometimes someone conclude that you will learn more by a more
challenging answer.

I think the best way to handle that is to learn from it!

Arne
 
A

Arne Vajhøj

Huh. It's been a long time, but I seem to remember getting a lot of RTFM
on the C/C++ groups. I bought the FMs; 0-470-84573-2, and 0-470-84674-7,
spent months reading them and moved to Java. :)

I still have them, in good condition, if you know someone who would like
to purchase them.

I don't know about c.l.c++ but c.l.c is not newbie friendly (or at
least was not 15 years ago).

Arne
 
J

Joshua Cranmer

1. Construct the first part of your GUI on the EDT as shown in the
example, up to where you append "Begin Counting" to the text area.

Applet::init should be called from the EDT, if I understand my applets
correctly (I don't play around enough with them to say for sure).
(I realize JTextArea.append() is thread safe, just in general you want
to know how to execute code on the EDT after completing some backgound
task.)

Mercifully, a lot of the document modelling stuff behind text areas is
actually thread-safe. Unfortunately, most of Swing is not so nice to you.
 
S

Sal

Swing code like that above must be executed on the EDT, or it ain't
going to work.  Building on what Jeff Higgins wrote, here's a direct
link to an example which builds a very simple GUI on the EDT:

<http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/deployme...>

You should study that, the rest of the section there on "Applets", and
read through the Concurrency in Swing tutorial:

<http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/...>

It's a pain in the rear but there isn't any other way.  You're totally
stuck until you understand this stuff;  we can't write ALL your code for
you.  Once you get through with that, here's what I think a basic plan
would be:

1. Construct the first part of your GUI on the EDT as shown in the
example, up to where you append "Begin Counting" to the text area.

2. Find the "long task" part of your GUI; in your example it's that
while loop.  That needs to be done OFF the GUI thread or it's going to
block all updates, including displaying the part of the GUI you just
made in #1.

3. Then, when #2 is done, display your final update(s) on the EDT.

Use a SwingWorker for the long task, it's the easiest way.  It'll
execute long tasks "in the background" more or less automatically for
you, then run a foreground process on the EDT when it's done.  Something
like:

import javax.swing.JTextArea;
import javax.swing.SwingWorker;

public class MyWorker extends SwingWorker {
    JTextArea textArea;
    int ctr;
    @Override
    protected Object doInBackground()
            throws Exception
    {
       // your long task here
       while( ++ctr < 1000000 );
       return null;
    }

    @Override
    protected void done() {
       textArea.append( "End counting " + ctr +" \n" );
    }

}

That should give you enough to get something done on your own, although
you've got a fair amount of reading to do.  Once you get that done and
write the improved version of you code, let us know how you are faring.

(I realize JTextArea.append() is thread safe, just in general you want
to know how to execute code on the EDT after completing some backgound
task.)

Thank you markspace for pointing me in the right direction. That's
what I needed to know to get going.
 
M

markspace

Joshua said:
Applet::init should be called from the EDT, if I understand my applets
correctly (I don't play around enough with them to say for sure).


I think it's the opposite, although I could be wrong about that.
init(), start() etc. are likely to be called on the thread used by the
browser itself, not the EDT. That's way a bad applet could halt
rendering and make a browser unresponsive. init() is declared in
java.awt.Applet, not JApplet, and so should be thread safe. There's no
reason to call its methods on the EDT.

If you do something that's not thread safe in init() (like constructing
Swing components), it's up to you to make it thread safe.

Mercifully, a lot of the document modelling stuff behind text areas is
actually thread-safe. Unfortunately, most of Swing is not so nice to you.


I was pretty sure that only setText() and append() are thread safe for
JTextArea. Everything else, even getText() is not.
 
L

Lew

markspace said:
import javax.swing.JTextArea;
import javax.swing.SwingWorker;

public class MyWorker extends SwingWorker {
JTextArea textArea;
int ctr;
@Override
protected Object doInBackground()
throws Exception
{
// your long task here
while( ++ctr < 1000000 );
return null;
}

@Override
protected void done() {
textArea.append( "End counting " + ctr +" \n" );
}
}

Shouldn't 'ctr' be at least 'volatile'?
 
A

Arved Sandstrom

Sal said:
Thanks Jeff, but all I have to say was that learning C++ was a helluva
lot easier. And don't try to tell me that Java is more complicated.
BTW, I was always to get straightforward answers on comp.lang.c++.

I'm not taking the piss or anything, but are you sure that you're
clearly separating learning the _language_ (and nothing but the
language) from learning libraries and everything else? Because very few
people think it's easier to learn C++ than Java. :)

I've been programming in Java as my main work language for over a
decade. OTOH I haven't ever used applets in my work; the only time I've
even dabbled with them was back in 1997 or 1998. I don't think it's fair
to extrapolate from difficulties with a Java API that most Java
developers don't even use and say that the language is harder to learn
than C++. It's not.

AHS
 
M

markspace

Lew said:
Shouldn't 'ctr' be at least 'volatile'?


Yes, I believe so. I thought that SwingWorker made some memory
consistency guarantees regarding its methods, but I don't see anything
like that documented.

As a practical matter, I don't see how an object could execute on two
different threads without synchronization. doInBackground() uses
Executor.execute(), and that definitely creates a happens-before
relationship. done() uses a Future object's done() method, and submits
the SwingWorker's to the EDT via invokeLater. This is more murky to me,
I don't see any explicit happens-before synchronization point on that
code path.

And of course if it's not documented in the API, it could change at any
time. It still would be useful imo to make an explicit happens-before
relationship there. Any real code is going to need one, why make the
end-user implement that part each time?
 
J

Joshua Cranmer

I was pretty sure that only setText() and append() are thread safe for
JTextArea. Everything else, even getText() is not.

Most of JTextArea itself is not thread-safe, but
javax.swing.text.Document and related functionality is (for the most part).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top