 |
AppletTalk.com Java discussions newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
grasshopper Guest
|
Posted: Thu Jun 17, 2004 11:13 am Post subject: Strange behaviour from recursive function |
|
|
Hi,
I am trying to write a method that toggles the display of a Swing
component(e.g. a JButton) inside a container (e.g. a JPanel).
The method below essentially does a depth-first search until it
reaches a
container with no child components (since e.g. a JButton is actually a
java.awt.Container this was the only way I could think of to
differentiate it
from e.g. a JPanel) and is supposed to remove the child component from
the parent container and place it in a holder vector, or if it is not
found in
the container, remove it from the holder and place it in the
container.
If the component is present in the container, the method presently
succeeds in placing it in the holder and then removing it from the
container.
The problem occurs when the component is not present in the container
and it
is added to the container from the holder. The next step, removing the
component from the holder, is executed twice despite the presence of a
return
statement which I assumed would terminate the method. I can't figure
out what
is causing the problem. I've included a log of the console output,
hopefully
someone may be able to shed some light on this, I'm stumped.
Thanks,
Brian
public void toggleComponent(String id, Container c) {
System.out.println("toggleComponent("+id+","+c+")");
Component[] children = c.getComponents();
Component cur; // current component
for (int i = 0; i < children.length; i++) {
System.out.println("inside for, i="+i);
cur = children[i];
if ((cur instanceof Container) &&
( ((Container) cur).getComponentCount() > 0 ) ) {
// current component is a non-empty container
toggleComponent(id, (Container)cur);
} else {
// current component is either
// a) an empty container, or
// b) not a container
// in any case, we want to compare it to the specified
// component specified by the 'id' argument
if (pruneXY(cur.toString()).compareTo(id) == 0) {
// the current component matches the supplied argument
// so add current componentto holder & remove from container
found = true;
Container parent = cur.getParent();
//System.out.println("Add to holdernid =t"+cur.toString());
componentHolder.add(cur);
parent.remove(cur);
// redraw
//parent.repaint();
//parent.validate();
// exit method
//System.out.println("about to return from method");
//System.out.println(found);
return;
}
}
}
System.out.println(found);
if (!found) {
// after iterating thru all child components of container c,
// target component not found. Therefore remove from holder
// and add to container c.
System.out.println("Remove from holdernid =t"+id);
c.add(componentHolder.get(id));
//c.repaint();
//c.validate();
System.out.println("about to return from method");
return;
}
System.out.println("after return statement");
}
-------
Output:
toggleComponent(javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER],javax.swing.JPanel[,86,40,606x426,alignmentX=null,alignmentY=null,border=,flags=9,maximumSize=,minimumSize=,preferredSize=])
inside for, i=0
toggleComponent(javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER],SimplePanel[,0,0,300x200,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=9,maximumSize=,minimumSize=,preferredSize=])
inside for, i=0
true
after return statement
toggleComponent(javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER],javax.swing.JPanel[,86,40,606x426,invalid,alignmentX=null,alignmentY=null,border=,flags=9,maximumSize=,minimumSize=,preferredSize=])
inside for, i=0
toggleComponent(javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER],SimplePanel[,0,0,300x200,invalid,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=9,maximumSize=,minimumSize=,preferredSize=])
inside for, i=0
inside for, i=1
false
Remove from holder
id = javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER]
about to return from method
false
Remove from holder
id = javax.swing.JLabel[,50x16,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=My
Label,verticalAlignment=CENTER,verticalTextPosition=CENTER]
java.lang.NullPointerException
|
|
| Back to top |
|
 |
Andrew Hobbs Guest
|
Posted: Tue Jun 22, 2004 1:05 am Post subject: Re: Strange behaviour from recursive function |
|
|
"grasshopper" <googleN0SPAM (AT) eyeonik (DOT) com> wrote
| Quote: | Hi,
I am trying to write a method that toggles the display of a Swing
component(e.g. a JButton) inside a container (e.g. a JPanel).
The method below essentially does a depth-first search until it
reaches a
container with no child components (since e.g. a JButton is actually a
java.awt.Container this was the only way I could think of to
differentiate it
from e.g. a JPanel) and is supposed to remove the child component from
the parent container and place it in a holder vector, or if it is not
found in
the container, remove it from the holder and place it in the
container.
If the component is present in the container, the method presently
succeeds in placing it in the holder and then removing it from the
container.
The problem occurs when the component is not present in the container
and it
is added to the container from the holder. The next step, removing the
component from the holder, is executed twice despite the presence of a
return
statement which I assumed would terminate the method. I can't figure
out what
is causing the problem. I've included a log of the console output,
hopefully
someone may be able to shed some light on this, I'm stumped.
Thanks,
Brian
|
Generally it is not a good idea to toggle a button by removing and adding
back. Swing isn't really designed for it. Plus it causes confusion for the
user.
If you want to 'remove' it from view I would suggest calling its
setVisible(boolean) method. However, note that removing it from view
whichever you do it, will result in the LayoutManager re-layingout the rest
of the components, possibly causing confusion if it occurs while the user
can see it and all the rest of the components jump around and resize.
A better way would be to inactivate the button. Use a boolean to determine
whether the button should respond and if not replace its icon with an
'inactive' icon or gray out the text by changing its color. That way the
components don't jump about, the user knows where they are but the button
still cannot be used.
This still leaves the problem of identifying the button. You need to work
out a better way. You are testing the String obtained using the toString()
method which as you have found is a string representation of the button's
state. Not only is this a very long string it also may change as the button
changes state, so that you never find the correct button. Also since you
are testing for identity and not its lexicographical order you should use
equals() or equalsIgnoreCase().
Surely a better way would be to test to see if it is a JButton and then test
identity against the button text perhaps.
Alternatively if you are writing the program yourself why not simply write
it so that you do not need to search through all the components in the first
place.
Cheers
Andrew
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|