🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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?
#221
Author: Tom Giammo
Date: Sun, 31 Dec 2006 18:35
33 lines
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?
#222
Author: Paul Nichols TeamB
Date: Sun, 31 Dec 2006 23:36
100 lines
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?
#223
Author: Paul Nichols TeamB
Date: Sun, 31 Dec 2006 23:37
100 lines
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?
#224
Author: Tom Giammo
Date: Mon, 01 Jan 2007 17:48
153 lines
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?
#225
Author: Paul Nichols TeamB
Date: Mon, 01 Jan 2007 23:21
27 lines
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?
#226
Author: Paul Furbacher [TeamB]
Date: Tue, 02 Jan 2007 04:00
75 lines
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?
#227
Author: Paul Furbacher [TeamB]
Date: Tue, 02 Jan 2007 04:09
48 lines
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