setVisible() problem after button click

S

samuel.cheadle

Hello,

I am having a big problem with the setVisible() method. It seems not
to work when an event such as a button click is involved in calling
it.

///// Pseudocode /////
display_messeges() {
loop {
add components to JFrame....
setVisible(true);
Sleep for a few seconds
}
}

The confusing thing is this will work when called from main, but does
not update the screen when called from actionPerformed method.

Am I doing somthing stupid here?...... it is driving me crazy
the test code is below...
Thanks
Sam


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.Random;

public class set_visible_test extends JFrame implements ActionListener
{

private static set_visible_test demo;
private JLabel test_label;
private JButton button;
private JPanel test_panel;
Container window;
private int button_pressed=0;

public static void main(String[] args) {
demo = new set_visible_test();
demo.setSize(500,500);
demo.createGUI();
}

private void createGUI() {

// CREATE AND ADD A BUTTON TO THE FRAME
if (button_pressed ==0){
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
window.setLayout(new BoxLayout(window, BoxLayout.PAGE_AXIS));


test_panel = new JPanel(new FlowLayout());

button = new JButton("CLICK HERE");

button.addActionListener(this);
test_panel.add(button);
window.add(test_panel);
demo.setVisible(true);

}
else {

////// WHEN THE BUTTON IS CLICKED DISPLAY A MESSEGE
////// AND SLEEP FOR 5 SECONDS
////// THEN DISPLAY SECOND MESSEGE
System.out.println("button clicked");
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
window.setLayout(new BoxLayout(window, BoxLayout.PAGE_AXIS));


test_panel = new JPanel(new FlowLayout());

test_label = new JLabel("FIRST STAGE");
test_panel.add(test_label);
window.add(test_panel);

demo.setVisible(true);
/////////////////// this setVisible(true) command is not
working !!!!!!!!!!!!!!!

try {Thread.sleep(5000);} catch (InterruptedException e){}

setDefaultCloseOperation(EXIT_ON_CLOSE);
window.removeAll();
window = getContentPane();
window.setLayout(new BoxLayout(window, BoxLayout.PAGE_AXIS));


test_panel = new JPanel(new FlowLayout());
test_label = new JLabel("SECOND STAGE");
test_panel.add(test_label);
window.add(test_panel);
demo.setVisible(true);
}

}

public void actionPerformed(ActionEvent event) {
button_pressed=1;
demo.createGUI();

}
}
 
A

Andrew Thompson

On Feb 12, 9:59 pm, (e-mail address removed) wrote:
....
Am I doing somthing stupid here?...... it is driving me crazy
the test code is below...

Probably a variety of things, but since
I do not understand what your code is
supposed to be doing, and the current
behaviour is easily explained, I am not
sure how to best advise.

The reason the .setVisible() call that
was highlighted (with that extremely
verbose line that wrapped and spoiled
a clean compilation) has no effect is
that the GUI is already visible, and
cannot become any *more* visible.

A couple of println() statements can
show that the code evaluates true at
the first if of the createGUI() method.

That is the code path that sets the GUI
visible. Any further calls are redundant.

Perhaps you should explain how this is
supposed to look to the end user.
What happens, and why?

Andrew T.
 
M

Michael Rauscher

Hello,

I am having a big problem with the setVisible() method. It seems not
to work when an event such as a button click is involved in calling
it.

///// Pseudocode /////
display_messeges() {
loop {
add components to JFrame....
setVisible(true);
Sleep for a few seconds
}
}

The confusing thing is this will work when called from main, but does
not update the screen when called from actionPerformed method.

Am I doing somthing stupid here?...... it is driving me crazy

Yes, you do :)

In Swing there's a thread, called Event Dispatch(ing) Thread, EDT for
short. Most work is done on this thread - painting, platform independend
event handling (notifying listeners) and so on.

Therefore, if a button notifies it's listeners, this code also runs on
the EDT.

Q: So, what is the consequence if your program waits for a
few seconds within a listener like ActionListener?
A: Right, it forces the current thread to wait for a few seconds.

Q: And what's the current thread?
A: Right, the EDT.

Q: And since the EDT is responsible for painting (in Swing),
what happens?
A: Right, nothing gets painted until the listener's method returns.
The GUI is "blocked".

Q: Hmm. But how can you wait for a few seconds if one clicks
on a button without blocking the GUI?
A: Move the waiting procedure into a new thread. But be careful:
Only one thread may manipulate the GUI: the EDT. This leads
us to the last question:

Q: How do I manipulate the GUI from a non-EDT thread?
A: Short: Never :)
Long: You have to ensure that the UI manipulating code runs
on the EDT. Either your code runs on the EDT already
(like the actionPerformed method) or you put your
code into the event dispatching queue which is processed
by the EDT. This can be done via
java.awt.EventQueue.invokeLater or
javax.swing.Utilities.invokeLater
(the latter just calls java.awt.EventQueue.invokeLater).

I've attached some (untested - even not compiled) code.

You may also want to use SwingWorker instead of the horrible
Runnable-cascades.

Bye
Michael

public class Test {

private JButton button;

private void initComponents() {
button = new JButton("Hide");
button.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
// first: make the button invisible
button.setVisible(false);

// now we have to return quickly so we
// don't block the EDT.
// Therefore create another Thread.
Thread t = new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch ( InterruptedException ie ) {
}
// after the two seconds we want
// to show the button again.
// since we're not on the EDT,
// let's put the setVisible-code
// into the Event Dispatching Queue
SwingUtilities.invokeLater( new Runnable() {
public void run() {
button.setVisible(true);
}
});
}
});

// and start it:
t.setPriority( Thread.NORM_PRIORITY );
t.start();
}
});
}

public void createAndShowGUI() {
initComponents();

JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.add( button );
frame.pack();
frame.setVisible(true);
}

public static final void main( String args[] ) {

// we're on the main thread, so we ensure that
// GUI creation is done on the EDT

SwingUtilities.invokeLater( new Runnable() {
public void run() {
new Test().createAndShowGUI();
}
});
}
}
 
S

samuel.cheadle

(e-mail address removed) schrieb:


I am having a big problem with the setVisible() method. It seems not
to work when an event such as a button click is involved in calling
it.
///// Pseudocode /////
display_messeges() {
loop {
add components to JFrame....
setVisible(true);
Sleep for a few seconds
}
}
The confusing thing is this will work when called from main, but does
not update the screen when called from actionPerformed method.
Am I doing somthing stupid here?...... it is driving me crazy

Yes, you do :)

In Swing there's a thread, called Event Dispatch(ing) Thread, EDT for
short. Most work is done on this thread - painting, platform independend
event handling (notifying listeners) and so on.

Therefore, if a button notifies it's listeners, this code also runs on
the EDT.

Q: So, what is the consequence if your program waits for a
few seconds within a listener like ActionListener?
A: Right, it forces the current thread to wait for a few seconds.

Q: And what's the current thread?
A: Right, the EDT.

Q: And since the EDT is responsible for painting (in Swing),
what happens?
A: Right, nothing gets painted until the listener's method returns.
The GUI is "blocked".

Q: Hmm. But how can you wait for a few seconds if one clicks
on a button without blocking the GUI?
A: Move the waiting procedure into a new thread. But be careful:
Only one thread may manipulate the GUI: the EDT. This leads
us to the last question:

Q: How do I manipulate the GUI from a non-EDT thread?
A: Short: Never :)
Long: You have to ensure that the UI manipulating code runs
on the EDT. Either your code runs on the EDT already
(like the actionPerformed method) or you put your
code into the event dispatching queue which is processed
by the EDT. This can be done via
java.awt.EventQueue.invokeLater or
javax.swing.Utilities.invokeLater
(the latter just calls java.awt.EventQueue.invokeLater).

I've attached some (untested - even not compiled) code.

You may also want to use SwingWorker instead of the horrible
Runnable-cascades.

Bye
Michael

public class Test {

private JButton button;

private void initComponents() {
button = new JButton("Hide");
button.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
// first: make the button invisible
button.setVisible(false);

// now we have to return quickly so we
// don't block the EDT.
// Therefore create another Thread.
Thread t = new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch ( InterruptedException ie ) {
}
// after the two seconds we want
// to show the button again.
// since we're not on the EDT,
// let's put the setVisible-code
// into the Event Dispatching Queue
SwingUtilities.invokeLater( new Runnable() {
public void run() {
button.setVisible(true);
}
});
}
});

// and start it:
t.setPriority( Thread.NORM_PRIORITY );
t.start();
}
});
}

public void createAndShowGUI() {
initComponents();

JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.add( button );
frame.pack();
frame.setVisible(true);
}

public static final void main( String args[] ) {

// we're on the main thread, so we ensure that
// GUI creation is done on the EDT

SwingUtilities.invokeLater( new Runnable() {
public void run() {
new Test().createAndShowGUI();
}
});
}

}



Ahhh "Theads".... I suspected they may have something to do with
it.

Many thanks for the excellent explanation.

Sam
 
M

Michael Rauscher

Ahhh "Theads".... I suspected they may have something to do with
it.
LOL.


Many thanks for the excellent explanation.

As Andrew Thompson would probably say: Future lack of full-quoting will
be thanks enough ;)

Bye
Michael
 
A

Andrew Thompson

(e-mail address removed) wrote: ...

As Andrew Thompson would probably say: Future lack of full-quoting will
be thanks enough ;)

No I have not been saying that,
but I've sure been thinking it.

Beyond my battle to minimise
top-posting, the next stage was
to help people understand the
value of 'in-line with trim
(but retaining the attributions)'
posting.

Unfortunately, with such a torrent of
t-p's, I never manage to get round to
explaining the latter (+ it does not
quite 'roll off the tongue' like
'top-post/bottom-post'!)

Any suggestions welcome, since people
sure don't seem to soak these things up,
just by seeing them repeatedly.

Andrew T.
 
A

Andrew Thompson

No I have not been saying that,
but I've sure been thinking it. ....
value of 'in-line with trim
(but retaining the attributions)'
posting. ...
... (+ it does not
quite 'roll off the tongue' like
'top-post/bottom-post'!)

Any suggestions welcome,

Your verion of the statement works well
in the right situation, whereas a simple
"Please refrain from full-quoting"
is enough for others - I can get into
that tongue twister of the best way to
post, if they should ask.

Consider it something I *will* be
suggesting in future.

( Well Duhh.. it only occured to my
after I made that second post. )

Andrew T.
 
M

Michael Rauscher

Andrew said:
to help people understand the
value of 'in-line with trim
(but retaining the attributions)'
posting.

Unfortunately, with such a torrent of
t-p's, I never manage to get round to
explaining the latter (+ it does not
quite 'roll off the tongue' like
'top-post/bottom-post'!)

Any suggestions welcome, since people
sure don't seem to soak these things up,
just by seeing them repeatedly.

In German there's a an expression "den roten Faden verlieren" (to lose
the red thread). Google lead me to an article published by
seattleweekly.com that told me that in English it means "losing one's
train of thought".

I think it's all about two things:

a) capture information while
b) not to lose the train of thought.

Position is just a kind of information. If I resign it, there are two
possibilities: Either I provide it in another way, usually by using
words or I don't provide the information at all. In any case: the reader
gets sidetracked and loses his train of thought.

The same applies to unnecessary full-quotes: the reader has to read lots
of text and could not concentrate on capturing the important things.

Another idea:

If Google would stop to show the relevant sections of the matching
pages, would Google then be as valuable as it is right now?

And if Google would show the whole text (and not just the relevant parts
of it), would you use it?

Bye
Michael
 
S

Stefan Ram

Michael Rauscher said:
In German there's a an expression "den roten Faden verlieren" (to lose
the red thread). Google lead me to an article published by
seattleweekly.com that told me that in English it means "losing one's
train of thought".

In English, when you want to make someone to »den roten Faden
verlieren«, you offer him a »red herring« instead, which in
German would be an »Ablenkungsmanöver«.

http://www.nizkor.org/features/fallacies/red-herring.html
 
N

Nigel Wade

Andrew said:
No I have not been saying that,

Michael didn't actually say you had, only that you probably would...
but I've sure been thinking it.

Beyond my battle to minimise
top-posting, the next stage was
to help people understand the
value of 'in-line with trim
(but retaining the attributions)'
posting.

Unfortunately, with such a torrent of
t-p's, I never manage to get round to
explaining the latter (+ it does not
quite 'roll off the tongue' like
'top-post/bottom-post'!)

I'm sure that one generally leads to (or is a direct result of) the other.
Top-posting and not trimming are related, probably due to Outlook and its
default action of placing the cursor at the top of the text when replying. This
naturally leads the respondent to enter their reply at the top, and then just
hit the send button. No need to worry about all that bothersome text which is
now below their response (out of sight, and out of mind).
Any suggestions welcome, since people
sure don't seem to soak these things up,
just by seeing them repeatedly.

A very large, remotely operated, clue-stick would be ideal...
Could it be driven by a servlet?
 
A

Andrew Thompson

I'm sure that one generally leads to (or is a direct result of) the other.
Top-posting and not trimming are related,

That is not my perception. Some people
will bottom post and trim, but there are
a swathe of people who do not really
understand *why* it makes sense to trim,
and simply believe that 'bottom-post'
will not get them shouted at - and that
is as far as they think about it.
now below their response (out of sight, and out of mind).

Some web-interfaces to usenet (notably GG)
offer to 'show quoted text', automatically
hiding earlier text. When the user goes to
reply, the entire text is whown in the reply
area, but I suspect many people simply hold
the 'page down' key till at 'the end', before
typing.
A very large,

...I'm thinking a cluster of servers,
with load balancing, to handle the
traffic.
..remotely operated, clue-stick would be ideal...
Could it be driven by a servlet?

Oh I wish..* ;-)

* Well, OK, if I had just *one* wish, I
would not be spending it on clueful usenet
posters, but maybe by the 8th or 9th wish..

Andrew T.
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top