Thread View: borland.public.jbuilder.java.swing
7 messages
7 total messages
Started by Tom Giammo
Sun, 31 Dec 2006 18:35
Accessing Components of top-level Frame?
Author: Tom Giammo
Date: Sun, 31 Dec 2006 18:35
Date: Sun, 31 Dec 2006 18:35
33 lines
2715 bytes
2715 bytes
After a six year hiatus, I'm back into Java and have been using JBuilder Foundation to relearn what I once knew and to learn some new things that weren't around back when. I'm stuck on trying to alter the text of a "statusBar" JLabel component that was set up for me on the top-level frame when I started a new application. From looking at the generated source code, it appears that when the main() method of my application constructs itself, its creates an instance (which it names "frame") of my designated top-level extension to JFrame. The constructor for that top-level JFrame extension lists among its components a JLabel named "statusBar". I would like to alter the text of "stausBar" from within another component that I've added to "frame", the instance of the top-level JFrame extension. I've tried several approaches to getting at "statusBar". Simply using its name (i.e. "frame.statusBar") doesn't work - presumably because "frame" is only a property of the generated application class (named, in this case, "hexGame"). The instance of hexGame, however, has not been given a name by JBuilder - it is simply generated in the main() method by "new hexGame()" without any assignment - and so I can't prefix its name to "frame.statusBar". I've tried using the "parentFrame" property of the component on the same "frame" from which I am trying to alter "statusBar". With the right castings, this compiles without a problem but causes an uncaught exception in the system's event queue. Everything else in my application works like a charm - as long as I don't try to access "statusBar". I'm obviously missing something. I'd appreciate what ever help anyone gan give. Tom Giammo
Re: Accessing Components of top-level Frame?
Author: Paul Nichols TeamB
Date: Sun, 31 Dec 2006 23:36
Date: Sun, 31 Dec 2006 23:36
100 lines
4263 bytes
4263 bytes
Tom Giammo wrote:
> I would like to alter the text of "stausBar" from within another component
> that I've added to "frame", the instance of the top-level JFrame extension.
>
Easy enough if statusBar is the name of your JLabel:
statusBar.setText("Some new text.");
> I've tried several approaches to getting at "statusBar". Simply using its
> name (i.e. "frame.statusBar") doesn't work - presumably because "frame" is
> only a property of the generated application class (named, in this case,
> "hexGame").
Unless the implementation of frame is static, that would be correct.
Children or child objects of the parent class are only accessible within
that class if they are declared private, only accessible by derived
classes within the same package if declared protected, and accessible by
all if declared "public".
The instance of hexGame, however, has not been given a name by
> JBuilder - it is simply generated in the main() method by "new hexGame()"
> without any assignment - and so I can't prefix its name to
> "frame.statusBar".
And that is totally within the context of the rules concerning
encapsulation. Since the public static void main(String args[]) is
declaring this as a new variable for HexGame (presumably), then the
hexGame instance is only accessible within this method, static void main().
I've tried using the "parentFrame" property of the
> component on the same "frame" from which I am trying to alter "statusBar".
> With the right castings, this compiles without a problem but causes an
> uncaught exception in the system's event queue.
>
Will not work, you are attempting to bypass encapsulation rules.
> Everything else in my application works like a charm - as long as I don't
> try to access "statusBar".
>
> I'm obviously missing something. I'd appreciate what ever help anyone gan
> give.
>
You are. Here are several suggestions:
/* (1) Make main a static member of the Main class and hexGame a member
of the Main Class */
public class Main{
private HexGame hexGame;
private static Main main;
//in the Main Class' public static void method
//add the main=New Main();
public static void main(String args[]) {
main= new Main();
main.hexGame = new HexGame();
//set any other attributes or run time methods
}
//add a method to get main
public static Main getMainClass(){
if(main==null) {
main=new Main();
}
return main;
}
//Add a method to get HexGame
public HexGame getHexGame(){
return hexGame();
}
//Now in your HexGame class, add a public method for settingText for
StatusBar
public class HexGame implements JFrame{
.....
public void setStatusBarText(String newText){
statusBar.setText(""); //make sure to clear text up
//to this point
statusBar.setText(newText);
}
.........
}
//Now in your other classes
private void someClassMethod(){
Main.getMainClass().getHexGame().setStatusBarText("Some new Text");
}
That should do it for you!
Re: Accessing Components of top-level Frame?
Author: Paul Nichols TeamB
Date: Sun, 31 Dec 2006 23:37
Date: Sun, 31 Dec 2006 23:37
100 lines
4382 bytes
4382 bytes
>Tom Giammo wrote:
> I would like to alter the text of "stausBar" from within another component
> that I've added to "frame", the instance of the top-level JFrame extension.
>
Easy enough if statusBar is the name of your JLabel:
statusBar.setText("Some new text.");
> I've tried several approaches to getting at "statusBar". Simply using its
> name (i.e. "frame.statusBar") doesn't work - presumably because "frame" is
> only a property of the generated application class (named, in this case,
> "hexGame").
Unless the implementation of frame is static, that would be correct.
Children or child objects of the parent class are only accessible within
that class if they are declared private, only accessible by derived
classes within the same package if declared protected, and accessible by
all if declared "public".
The instance of hexGame, however, has not been given a name by
> JBuilder - it is simply generated in the main() method by "new hexGame()"
> without any assignment - and so I can't prefix its name to
> "frame.statusBar".
And that is totally within the context of the rules concerning
encapsulation. Since the public static void main(String args[]) is
declaring this as a new variable for HexGame (presumably), then the
hexGame instance is only accessible within this method, static void main().
I've tried using the "parentFrame" property of the
> component on the same "frame" from which I am trying to alter "statusBar".
> With the right castings, this compiles without a problem but causes an
> uncaught exception in the system's event queue.
>
Will not work, you are attempting to bypass encapsulation rules.
> Everything else in my application works like a charm - as long as I don't
> try to access "statusBar".
>
> I'm obviously missing something. I'd appreciate what ever help anyone gan
> give.
>
You are. Here are several suggestions:
/* (1) Make main a static member of the Main class and hexGame a member
of the Main Class */
public class Main{
private HexGame hexGame;
private static Main main;
//in the Main Class' public static void method
//add the main=New Main();
public static void main(String args[]) {
main= new Main();
main.hexGame = new HexGame();
//set any other attributes or run time methods
}
//add a method to get main
public static Main getMainClass(){
if(main==null) {
main=new Main();
}
return main;
}
//Add a method to get HexGame
public HexGame getHexGame(){
return hexGame();
}
//Now in your HexGame class, add a public method for settingText for
StatusBar
public class HexGame implements JFrame{
.....
public void setStatusBarText(String newText){
statusBar.setText(""); //make sure to clear text up
//to this point
statusBar.setText(newText);
}
.........
}
//Now in your other classes
private void someClassMethod(){
Main.getMainClass().getHexGame().setStatusBarText("Some new Text");
}
That should do it for you!
Re: Accessing Components of top-level Frame?
Author: Tom Giammo
Date: Mon, 01 Jan 2007 17:48
Date: Mon, 01 Jan 2007 17:48
153 lines
6586 bytes
6586 bytes
Paul:
Thanks for responding.
Your approach is ingenious and no doubt would work. I had begun to explore
along those lines myself, but couldn't keep straight in my mind which
variables would be visible to the components within the top-level frame. I
ultimately gave up on the basis that something so simple as accessing a
sibling component of the same top-level couldn't possibly be so complex. I
also found the necessity of modifying the JBuilder generated code so
significantly a bit distasteful.
Upon much reflection <pun intended>, I think that I've come up with a
simpler way that is less disruptive of the JBuilder code. I was on the
right track when I tried to find the top-level frame containing my component
using the component's "getParent()" method. In this regard, I think that
your comment on this approach ("Will not work, you are attempting to bypass
encapsulation rules") is not correct. The real problem lies in the fact
that the immediate parent of my component was not the top-level frame
itself, but rather was that frame's contentPane. The frame object itself
could only be reached by chaining up through the parents of its contentPane,
JLayeredPane, and JRootPane containers.
Once I realized this, I wrote the following general method to fetch the
top-level frame of any component:
public Frame getEnclosingFrame(Component c) throws NoSuchMethodException
{
Component p = c;
Class fClass = java.awt.Frame.class;
while (!fClass.isInstance(p)) {
String pName = p.getClass().getName();
p.getClass().getMethod("getParent", null); // throws exception
if appropriate
p = ((Component) p).getParent();
}
return (Frame) p;
}
This method worked without any problem to get me to my statusBar component,
i.e. :
frameMain myFrame = (frameMain)getEnclosingFrame(this);
myFrame.statusBar.setText(statusMessage);
Tom Giammo
"Paul Nichols [TeamB]" <"Paul Nichols [TeamB]"> wrote in message
news:45984988$1@newsgroups.borland.com...
> >Tom Giammo wrote:
>
>
>> I would like to alter the text of "stausBar" from within another
>> component that I've added to "frame", the instance of the top-level
>> JFrame extension.
>>
>
> Easy enough if statusBar is the name of your JLabel:
>
> statusBar.setText("Some new text.");
>
>> I've tried several approaches to getting at "statusBar". Simply using
>> its name (i.e. "frame.statusBar") doesn't work - presumably because
>> "frame" is only a property of the generated application class (named, in
>> this case, "hexGame").
>
> Unless the implementation of frame is static, that would be correct.
> Children or child objects of the parent class are only accessible within
> that class if they are declared private, only accessible by derived
> classes within the same package if declared protected, and accessible by
> all if declared "public".
>
>
> The instance of hexGame, however, has not been given a name by
>> JBuilder - it is simply generated in the main() method by "new
>> hexGame()" without any assignment - and so I can't prefix its name to
>> "frame.statusBar".
>
> And that is totally within the context of the rules concerning
> encapsulation. Since the public static void main(String args[]) is
> declaring this as a new variable for HexGame (presumably), then the
> hexGame instance is only accessible within this method, static void
> main().
>
>
> I've tried using the "parentFrame" property of the
>> component on the same "frame" from which I am trying to alter
>> "statusBar". With the right castings, this compiles without a problem but
>> causes an uncaught exception in the system's event queue.
>>
> Will not work, you are attempting to bypass encapsulation rules.
>> Everything else in my application works like a charm - as long as I
>> don't try to access "statusBar".
>>
>> I'm obviously missing something. I'd appreciate what ever help anyone
>> gan give.
>>
> You are. Here are several suggestions:
>
> /* (1) Make main a static member of the Main class and hexGame a member of
> the Main Class */
>
> public class Main{
> private HexGame hexGame;
> private static Main main;
>
> //in the Main Class' public static void method
> //add the main=New Main();
>
> public static void main(String args[]) {
> main= new Main();
> main.hexGame = new HexGame();
> //set any other attributes or run time methods
>
> }
>
> //add a method to get main
> public static Main getMainClass(){
> if(main==null) {
> main=new Main();
> }
> return main;
> }
> //Add a method to get HexGame
> public HexGame getHexGame(){
> return hexGame();
> }
>
> //Now in your HexGame class, add a public method for settingText for
> StatusBar
>
> public class HexGame implements JFrame{
>
> .....
>
>
> public void setStatusBarText(String newText){
> statusBar.setText(""); //make sure to clear text up
> //to this point
> statusBar.setText(newText);
>
> }
> .........
> }
>
> //Now in your other classes
> private void someClassMethod(){
> Main.getMainClass().getHexGame().setStatusBarText("Some new Text");
> }
>
> That should do it for you!
Re: Accessing Components of top-level Frame?
Author: Paul Nichols TeamB
Date: Mon, 01 Jan 2007 23:21
Date: Mon, 01 Jan 2007 23:21
27 lines
2420 bytes
2420 bytes
Tom Giammo wrote:
> Paul:
>
> Thanks for responding.
>
> Your approach is ingenious and no doubt would work. I had begun to explore
> along those lines myself, but couldn't keep straight in my mind which
> variables would be visible to the components within the top-level frame. I
> ultimately gave up on the basis that something so simple as accessing a
> sibling component of the same top-level couldn't possibly be so complex. I
> also found the necessity of modifying the JBuilder generated code so
> significantly a bit distasteful.
>
> Upon much reflection <pun intended>, I think that I've come up with a
> simpler way that is less disruptive of the JBuilder code. I was on the
> right track when I tried to find the top-level frame containing my component
> using the component's "getParent()" method. In this regard, I think that
> your comment on this approach ("Will not work, you are attempting to bypass
> encapsulation rules") is not correct.
Could be. I was under the assumption that you were using a class called
Main that contained a reference to the class HexGame, which was not part
of the Main class itself, therefore, you were attempting to access it
out of scope. But if this was incorrect, then of course my assumption
would be incorrect.
Of course without possessing the actual code, all one can do is guess :)
Re: Accessing Components of top-level Frame?
Author: Paul Furbacher [TeamB]
Date: Tue, 02 Jan 2007 04:00
Date: Tue, 02 Jan 2007 04:00
75 lines
4161 bytes
4161 bytes
Tom Giammo wrote:
> [...]
>
> I'm stuck on trying to alter the text of a "statusBar" JLabel component that
> was set up for me on the top-level frame when I started a new application.
> [...]
> I would like to alter the text of "stausBar" from within another component
> that I've added to "frame", the instance of the top-level JFrame extension.
>
> I've tried several approaches to getting at "statusBar". Simply using its
> name (i.e. "frame.statusBar") doesn't work - presumably because "frame" is
> only a property of the generated application class (named, in this case,
> "hexGame").
This approach, even if you give the "statusBar" member variable public
access, or create a getter method for it in the frame, is too tightly
coupled. This "other component" has to know too much about its
context -- the frame and its status bar -- such that if you wanted
to use it in another context, one without a status bar but may be
some kind of text display object in a panel in a panel in a frame,
you'd have to do some rewriting. [See below for a general approach
to solving this very common problem.]
> The instance of hexGame, however, has not been given a name by
> JBuilder - it is simply generated in the main() method by "new hexGame()"
> without any assignment - and so I can't prefix its name to
> "frame.statusBar".
What JBuilder generates for you is just a starting point.
You modify that to suit your purposes. In this case, there's
absolutely nothing preventing you from naming that variable,
hoisting its declaration, changing it to a member variable, and
even changing its scope. It's up to you, not the IDE.
> I've tried [...]
I think you'd do better to look into "listeners", an
implementation of the "observer" pattern, which Sun
uses extensively in the Swing framework. Based on
the concept, you'd develop a event-listener model for
updating your status bar.
Beside Googling
+listener +tutorial +sun +java
you could start here
http://java.sun.com/docs/books/tutorial/uiswing/events/index.html
You would add to your component the ability to register (add)
listeners for update events, and when the status of your component
changed, you'd broadcast to those listeners the display text.
Your frame would implement your custom listener interface, and the
method which is called would, in this particular case, update the
status bar. Your application object, when it creates both the
frame and the "other component", would add the frame as a listener
to that component.
--
Paul Furbacher (TeamB)
Save time, search the archives:
http://info.borland.com/newsgroups/ngsearch.html
Is it in Joi Ellis's Faq-O-Matic?
http://www.visi.com/~gyles19/fom-serve/cache/1.html
Finally, please send responses to the newsgroup only.
That means, do not send email directly to me.
Thank you.
Re: Accessing Components of top-level Frame?
Author: Paul Furbacher [TeamB]
Date: Tue, 02 Jan 2007 04:09
Date: Tue, 02 Jan 2007 04:09
48 lines
2489 bytes
2489 bytes
Tom Giammo wrote:
> [...]
>
> Once I realized this, I wrote the following general method to fetch the
> top-level frame of any component:
>
> public Frame getEnclosingFrame(Component c) throws NoSuchMethodException
> {
> Component p = c;
> Class fClass = java.awt.Frame.class;
> while (!fClass.isInstance(p)) {
> String pName = p.getClass().getName();
> p.getClass().getMethod("getParent", null); // throws exception
> if appropriate
> p = ((Component) p).getParent();
> }
> return (Frame) p;
> }
>
> This method worked without any problem to get me to my statusBar component,
> i.e. :
>
> frameMain myFrame = (frameMain)getEnclosingFrame(this);
> myFrame.statusBar.setText(statusMessage);
> [...]
It may work, but it's far too clever.
The observer pattern suggested in a sibling post is far
more common an approach to this very common problem.
Reflection is the wrong tool here.
--
Paul Furbacher (TeamB)
Save time, search the archives:
http://info.borland.com/newsgroups/ngsearch.html
Is it in Joi Ellis's Faq-O-Matic?
http://www.visi.com/~gyles19/fom-serve/cache/1.html
Finally, please send responses to the newsgroup only.
That means, do not send email directly to me.
Thank you.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads