Idiom Question - Finding Instances

R

Rhino

Can someone remind me of the idiom used to determine which instances of a
given class have been created? I can't think of it for the life of me.

In my particular case, one of my classes is creating a tabbed pane and, when
a file dialog is opened and a jar file is selected, it calls another class
that puts the file names from the jar in a panel, which then becomes the
body of a new tab in the tabbed pane.

I need to invoke the second class, the one that creates the panel, from
first class, the one that creates the tabbed pane, to tell the panel class
that it should paint its components in such-and-such colors. The tabbed pane
class knows what colors the panels should be painted and needs to pass those
colors to the panel class when invoking the panel class's setColors()
method.

However, I am having trouble figuring out how the tabbed pane can determine
the instances of the panels that exist. I am using
tabbedPane.getComponentAt(tab) to get each of the tabs in turn - there could
be any number of tabs in the tabbed pane and all of them contain the panels
created with my panel class - but I don't know how to get from the Component
to the instance of the panel that was put on the tab. I need that reference
so that I can set the colors for that panel.

Can anyone help me?
 
X

xarax

Rhino said:
Can someone remind me of the idiom used to determine which instances of a
given class have been created? I can't think of it for the life of me.

In my particular case, one of my classes is creating a tabbed pane and, when
a file dialog is opened and a jar file is selected, it calls another class
that puts the file names from the jar in a panel, which then becomes the
body of a new tab in the tabbed pane.

I need to invoke the second class, the one that creates the panel, from
first class, the one that creates the tabbed pane, to tell the panel class
that it should paint its components in such-and-such colors. The tabbed pane
class knows what colors the panels should be painted and needs to pass those
colors to the panel class when invoking the panel class's setColors()
method.

However, I am having trouble figuring out how the tabbed pane can determine
the instances of the panels that exist. I am using
tabbedPane.getComponentAt(tab) to get each of the tabs in turn - there could
be any number of tabs in the tabbed pane and all of them contain the panels
created with my panel class - but I don't know how to get from the Component
to the instance of the panel that was put on the tab. I need that reference
so that I can set the colors for that panel.

Can anyone help me?

If I understand your convoluted question, it seems
like you have a custom panel (e.g., class name "MyCustomPanel")
that you are adding to the tabbed pane. You are using
tabbedPane.getComponentAt(index) to get the Component at
the tab location.

Component theComponent;

theComponent = tabbedPane.getComponentAt(index);
if(theComponent instanceof MyCustomPanel)
{
MyCustomPanel myCustomPanel;

myCustomPanel = (MyCustomPanel) theComponent;
// work with the panel...
}


Is that what you want?
 
R

Rhino

Yes, that's right! Thank you very much!

Sorry for the poorly-worded question; I couldn't quite figure out how to say
it any more clearly.

Rhino
 
J

Jon A. Cruz

Rhino said:
Can someone remind me of the idiom used to determine which instances of a
given class have been created? I can't think of it for the life of me.

In Java, I don't know of one off-hand either.

In general, it's something that shouldn't be done.



....
However, I am having trouble figuring out how the tabbed pane can determine
the instances of the panels that exist. I am using
tabbedPane.getComponentAt(tab) to get each of the tabs in turn - there could
be any number of tabs in the tabbed pane and all of them contain the panels
created with my panel class - but I don't know how to get from the Component
to the instance of the panel that was put on the tab. I need that reference
so that I can set the colors for that panel.

Can anyone help me?

Ahhh... here we go.

I think it's more of a issue with moving away from a UI-centric
codebase. Instead of worrying about components talking to each other,
craft a set of data models that do the talking, and then just wire up a
UI component to a given instance of some data model. When other data
models change things, they trigger changes in data models that care
(registered via listeners). In turn, the UI class has registered with
it's own data model as a listener, so it will get notifications passed on.



One question would be 'what do your colors mean'? Are there some
standard meanings? Do they map per file type?, etc.

Does this perhaps shed a little light?

class FileListView extends JPanel implements ColorChangeoListener
{
....
public FileListView( MyFileList list, ColorManager colorSource )
{
colorSource.addColorChangeoListener( this );
...
}
--------------

Or

FileListView viewer = new FileListView(someList);
addColorChangeoListener( viewer );

or if it is constructed by a third-party...

FileListView viewer = new FileListView(someList);
colorManagerTabHolderWhatver.addColorChangeoListener( viewer );
 
R

Rhino

Jon A. Cruz said:
In Java, I don't know of one off-hand either.

In general, it's something that shouldn't be done.
"xarax" has given me a solution that seems to work - see his reply in the
newsgroup if you're interested - but I'm curious to know why it's a bad
idea. OO Design Theory is definitely not my strong suit so I really don't
know.
I think it's more of a issue with moving away from a UI-centric
codebase. Instead of worrying about components talking to each other,
craft a set of data models that do the talking, and then just wire up a
UI component to a given instance of some data model. When other data
models change things, they trigger changes in data models that care
(registered via listeners). In turn, the UI class has registered with
it's own data model as a listener, so it will get notifications passed on.
The concept of what you're saying makes sense to me - I think. My theory
isn't strong enough for me to be able to argue the pros and cons of your
idea, i.e. I can't say why your approach is "better" than the one "xarax"
supplied, but I like the sound of it.

If I understand you correctly, the code that changes the colors for the GUI
components should update a data model which contains the current palette;
listeners on that data model would trigger other data models to refresh
themselves. Then the changes in the latter data models would effectively
redraw the JarViewerPanels by virtue of having changed. Is that right?
One question would be 'what do your colors mean'? Are there some
standard meanings? Do they map per file type?, etc.
Essentially, my situation is that I have a Java application whose main
class, JarViewer, draws a tabbed pane. When the user clicks on the Open menu
in JarViewer, a file dialog comes up and lets the user select a jar file
somewhere on the file system. JarViewer examines the jar and builds a list
of file names and other attributes of the file, then passes them to class
called JarViewerPanel, which writes the info about the files in the jar to a
JTable, which is the key portion of the JarViewerPanel itself. The newly
created JarViewerPanel is put on a new Tab in JarViewer's tabbed pane.

To make the JarViewer more esthetically pleasing, I want to let the user
choose a palette of colors from a list of palettes, then assign individual
colors from that palette to the GUI components, particularly the JTables in
the different tabs. I could have any number of tabs but they all contain
JarViewerPanels so it would seem logical that JarViewerPanel should be
responsible for drawing its own components based on the palette chosen by
the user. Also, if the user chooses a new palette, JarViewerPanel should
redraw its components with the colors from the new palette.

Important note about palettes and colors: The user only selects a palette,
never individual colors. The palette consists of 8 colors, pre-selected by
me, that each fall into a different category: background color, text
foreground color, text background color, etc. My code will assign each color
in the palette to the appropriate GUI component, e.g. each piece of text is
written in the text foreground color from the palette against the text
background color of the palette.
Does this perhaps shed a little light?

class FileListView extends JPanel implements ColorChangeoListener
{
...
public FileListView( MyFileList list, ColorManager colorSource )
{
colorSource.addColorChangeoListener( this );
...
}
--------------

Or

FileListView viewer = new FileListView(someList);
addColorChangeoListener( viewer );

or if it is constructed by a third-party...

FileListView viewer = new FileListView(someList);
colorManagerTabHolderWhatver.addColorChangeoListener( viewer );
If I'm following you correctly so far - and if my reasoning about the design
is reasonable - I'm not quite sure how to do what you're suggesting. Here's
my best guess:

1. Every instance of my application has a default palette so the initial
painting of the components in JarViewer and JarViewerPanel should use the
default palette. This initial painting doesn't need any listeners; it simply
proceeds via the default palette, which is stored in a default Preference
node for that application.
2. Since the user is choosing the palette from a JList, I should use a
ListSelectionListener to detect whenever the user has chosen a new palette.
3. The ListSelectionListener needs to pass the newly selected palette to
refresh a data model which contains the palette.
4. ??

Here's where I get lost. Actually, I'm not even really clear on #3, mostly
because I'm unclear on precisely what you mean by a data model in this
context.

Every time a user chooses a palette that isn't the default palette from the
default preferences, I want to create a personal preference for that user
containing his/her desired preference of palette. Can this Preference node
serve as a data model in the sense that you are using that term? That would
save me having to store the same data again, which seems like a good thing,
but maybe that's not proper OO technique. I suspect that the user's
individual Preference node isn't a data model in the sense that you mean
because I can't put a listener on it to detect that it has changed (or at
least I'm not *aware* of any way to detect creation or changes of Preference
nodes via a listener). Do you mean data model in the sense of the existing
ListModel class in Java?

Is there an existing data model class that I can use to store my palette? Or
do I need to create my own data model class? I've created lots of classes
that hold data but I'm not sure how a 'data model' class is designed.

Okay, I'm just getting more and more confused as I mull this over so I'm
going to stop and ask you for clarification/correction on what I've said so
far. Then maybe this will all fall into place and I will fully understand
what you are proposing.

Rhino
 
J

Jon A. Cruz

Rhino said:
"xarax" has given me a solution that seems to work - see his reply in the
newsgroup if you're interested - but I'm curious to know why it's a bad
idea. OO Design Theory is definitely not my strong suit so I really don't
know.

Yes. Works ok for what you have at the moment, but it's very fragile.

It's a little akin to making all your methods take Object as parameters
and casting all over the place. Again, not too robust nor safe.




If I understand you correctly, the code that changes the colors for the GUI
components should update a data model which contains the current palette;
listeners on that data model would trigger other data models to refresh
themselves. Then the changes in the latter data models would effectively
redraw the JarViewerPanels by virtue of having changed. Is that right?

Sounds about right.




Essentially, my situation is that I have a Java application whose main
class, JarViewer, draws a tabbed pane. When the user clicks on the Open menu
in JarViewer, a file dialog comes up and lets the user select a jar file
somewhere on the file system. JarViewer examines the jar and builds a list
of file names and other attributes of the file, then passes them to class
called JarViewerPanel, which writes the info about the files in the jar to a
JTable, which is the key portion of the JarViewerPanel itself. The newly
created JarViewerPanel is put on a new Tab in JarViewer's tabbed pane.

But... what if you wanted to put one of these JarViewerPanels somewhere
else? Like in it's own window, like many mail programs do when you
double click (as opposed to single click) on a mail item.

That's where it should be clear that although you still have a
JarViewPanel and it's list of files, you no longer have access to it via
some UI widget (a tabbed pane, in your case).

Also... the details of 'writes the info' might be a place to look into
at some other point.
To make the JarViewer more esthetically pleasing, I want to let the user
choose a palette of colors from a list of palettes, then assign individual
colors from that palette to the GUI components, particularly the JTables in
the different tabs. I could have any number of tabs but they all contain
JarViewerPanels so it would seem logical that JarViewerPanel should be
responsible for drawing its own components based on the palette chosen by
the user. Also, if the user chooses a new palette, JarViewerPanel should
redraw its components with the colors from the new palette.

Yes. That seems reasonable. The JarViewerPanel, not a JarViewer itself,
though.




1. Every instance of my application has a default palette so the initial
painting of the components in JarViewer and JarViewerPanel should use the
default palette. This initial painting doesn't need any listeners; it simply
proceeds via the default palette, which is stored in a default Preference
node for that application.

Not quite.

Good, on the default palette, but then off in regards to the use.

Now, it appears that you have things hooked into a Preference API usage.
Time for some encapsulation.

The UI objects (JarViewerPanel, JarViewer, etc) should probably not be
made aware of the details of the Preferences API calls, or even that
they exist.

Instead, have a UIPreferences class (or something like that). It could
have constants for each of your 8 color type. Then a method to get a
Color given a type number.

So... for the initial *construction* (not 'painting'), your classes
still get the default preferences object and just pull colors out of that.

Also... since this is global to your application, you can just make it a
singleton

static public UIPreferences getPreferences()
{
return _instance;
}

Then you don't even need to pass it down


Also... for every UI thingie that might need it later, create a
ColorChaneListener and feed it to UIPreferences' addColorChangeListener
call.

2. Since the user is choosing the palette from a JList, I should use a
ListSelectionListener to detect whenever the user has chosen a new palette.

Only in the UI panel that's allowing the user to change things. For the
UIPreferences class itself, use different calls. Don't let javax.swing.*
contaminate it.

3. The ListSelectionListener needs to pass the newly selected palette to
refresh a data model which contains the palette.

So...

You'll either need to switch the UIPreferences singleton to a given
existing palette, or to a new custom palette.

public void setToPalette(int num)
public void setCustomPalette( Color[] palette )
(btw, inside that last method is where to hide actually storing the prefs)

4. ??

Here's where I get lost. Actually, I'm not even really clear on #3, mostly
because I'm unclear on precisely what you mean by a data model in this
context.

Every time a user chooses a palette that isn't the default palette from the
default preferences, I want to create a personal preference for that user
containing his/her desired preference of palette. Can this Preference node
serve as a data model in the sense that you are using that term?

I wouldn't expose that directly. Instead hide that inside the
UIPreferences class.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top