Discussion:
Elemente einer GUI ermitteln
(zu alt für eine Antwort)
Alexander
2011-01-07 16:40:51 UTC
Permalink
Hallo,

der Betreff ist sehr grob formuliert, leider fiel mir nichts anderes ein.
Ich habe folgendes Problem:

Ich habe ein JFrame, darin ein GridBagLayout mit 3 JPanel's. Ein Jpanel
enthält eine JTextArea, ein anderes Panel enthält Buttons (lokal
definiert). Das TextArea übergebe ich per Aufruf an eine andere Klasse,
die es "beschriftet".
Ich möchte aber aus dieser Klasse auch auf die Buttons zugreifen
(setEnabled usw). Die Buttons könnte ich natürlich auch übergeben, aber
das gefällt mir irgendwie nicht und würde vermutlich irgendwann den
Aufruf "sprengen".
Da gibt es doch bestimmt eine Funktion, die ich übersehe ...

Ich hatte jetzt schon probiert über das TextArea heranzukommen (
getParent().getComponent() ), aber das hilft mir doch irgenwie nicht weiter.

LG
Alexander
Patrick Roemer
2011-01-07 17:12:03 UTC
Permalink
Post by Alexander
Ich habe ein JFrame, darin ein GridBagLayout mit 3 JPanel's. Ein Jpanel
enthält eine JTextArea, ein anderes Panel enthält Buttons (lokal
definiert). Das TextArea übergebe ich per Aufruf an eine andere Klasse,
die es "beschriftet".
Da waere zu ueberlegen, ob man statt der Komponente selber nicht nur
deren Document weiterreicht, bzw. ob man die Logik nicht noch besser
komplett von den Komponenten trennt und die Verbindungen dazwischen
(zumindest in eine Richtung) nur abstrakt ueber Listenerbeziehungen
herstellt. Stichwoerter dafuer waeren MVC, MVP, Presentation Model,...

Lesetip: http://jgoodies.com/articles/patterns-and-binding.pdf
Post by Alexander
Ich möchte aber aus dieser Klasse auch auf die Buttons zugreifen
(setEnabled usw).
Same here. In diesem Fall boete sich auch ein Blick auf
javax.swing.Action an.
Post by Alexander
Ich hatte jetzt schon probiert über das TextArea heranzukommen (
getParent().getComponent() ), aber das hilft mir doch irgenwie nicht weiter.
Sowas waere auch ein sicheres Rezept fuer einen Verhau, bei dem man
binnen kurzer Zeit gar nichts mehr an der UI aendern kann, ohne dass
einem die komplette Logik um die Ohren fliegt.

Viele Gruesse,
Patrick
Alexander
2011-01-09 08:42:18 UTC
Permalink
Post by Patrick Roemer
Da waere zu ueberlegen, ob man statt der Komponente selber nicht nur
deren Document weiterreicht, bzw. ob man die Logik nicht noch besser
komplett von den Komponenten trennt und die Verbindungen dazwischen
(zumindest in eine Richtung) nur abstrakt ueber Listenerbeziehungen
herstellt. Stichwoerter dafuer waeren MVC, MVP, Presentation Model,...
Lesetip: http://jgoodies.com/articles/patterns-and-binding.pdf
Hm, damit sollte ich mich sicherlich mal beschäftigen ;)
Aber im Moment habe ich da nicht die Ruhe zu ...

Gibt es keine andere Lösung? Evtl wenn ich den Container oder den Frame
übergebe ... Kann ich dann alle darin enthaltenen Elemente ermitteln und
ansprechen?

LG
Alexander
Marco Hunsicker
2011-01-09 09:20:30 UTC
Permalink
Post by Alexander
Gibt es keine andere Lösung? Evtl wenn ich den Container oder den Frame
übergebe ... Kann ich dann alle darin enthaltenen Elemente ermitteln und
ansprechen?
Man kann die komplette Hierarchie durchlaufen. In beide Richtungen.
java.awt.Container liefert die notwendigen Mittel.

Wenn man den gesuchten Elementen eindeutige Namen vergibt (mittels
java.awt.Component#setName), und ganz oben anfängt zu suchen, sollte
eine gewisse Flexibilität erhalten bleiben. Eine saubere Lösungen sieht
sicher anders aus.
Alexander
2011-01-09 13:19:43 UTC
Permalink
Post by Marco Hunsicker
Man kann die komplette Hierarchie durchlaufen. In beide Richtungen.
java.awt.Container liefert die notwendigen Mittel.
Hab es gefunden, danke!
Post by Marco Hunsicker
Eine saubere Lösungen sieht sicher anders aus.
Vorschlag?
Stefan Ram
2011-01-09 18:24:06 UTC
Permalink
Post by Alexander
Post by Marco Hunsicker
Eine saubere Lösungen sieht sicher anders aus.
Vorschlag?
Repost eines meiner Postings:

A component here is an object controlling an area of a
graphical user interface, like a command button or a window.
(A degenerate component might also be an »invisible«
component, i.e., a simple object.)

MVC or model-view-separation deals with the internal structure
of a single GUI component.

An application usually has multiple components, often nested in
the form of a tree.

Therefore, I would like to plan the relationship between
several components.

I write down some ideas here. Possibly someone already has
heard about similar schemas and can tell me if there already
is a name for the following plan.

A window (which is a component), for example, might have an
upper part with a list (which is a component) and a lower part
with a log console (which is a component).

window
component
/\
/ \
/ \
/ \
/ \
table console
component component

.---------------------------------.
| window component |
| .-----------------------------. |
| | table component | |
| | | |
| | | |
| | | |
| '-----------------------------' |
| .-----------------------------. |
| | console component | |
| | | |
| | | |
| | | |
| '-----------------------------' |
'---------------------------------'

How does the table component request some text to be logged?

I do not want the table component to be aware of the console
component. This would make it more difficult to reuse the
table component in other contexts without a console component
or to add or remove the table component or the console
component independently of other components. (If you do not
accept this reason, I also might refer to Demeter's law.)

So, instead of directly accessing the console component, the
table component "escalates" a log-report to the window
component, which is its container. The window component then
knows that it has a "log-report-handler" (i.e., the console
component), and then delegates the log-request to the console
component.

Thus, the application component structure I made up recently is
to build an application as a tree of components which obey
Demeter's law and therefore only communicate via the /edges/
of this component tree, i.e., each component communicates only
with its direct container or one of its direct containees.

A common special case are several components sharing a single
model. Then, I want a common container component of these two
components to be (or hold) the model. For example,


window (and model for "view 0" and "view 1")
/\
/ \
/ \
/ \
/ \
view 0 view 1

.---------------------------------.
| window |
| .-----------------------------. |
| | view 0 | |
| | | |
| | | |
| | | |
| '-----------------------------' |
| .-----------------------------. |
| | view 1 | |
| | | |
| | | |
| | | |
| '-----------------------------' |
'---------------------------------'

Here, the window doubles as the model for its subcomponents,
when they both need to refer to common data. (The observer
relation might hold between any two components of an application,
but has to be initiated via the edges of the tree.)

The layout of an application might be changed at runtime by
adding components to a container component. When this happens,
some requirements will be checked: A certain container might
only accept components implementing certain operations and the
components might require its container to implement certain
models for it.

The tree structure means that each component (except the root
component) has a single container component that represents
the rest of the application to the contained component.

Whenever a component needs something it can not do itself, it
will request this from its direct container.

When a container receives a request from one of its directly
contained subcomponents, it might handle it or it might
delegate it to another of its subcomponents.

When a container can not handle a request in one of these ways
(for example, a request of an unknown type), it will escalated
it to its own container.

When the root component receives a request it can not handle,
it might report this as an error or silently drop the request,
depending on what is most useful or appropriate in this
application.

For example, a component deep down in the tree might need to
know the »current directory« of the application, so it will
ask its container:

this.container.getEnv( "cd" );

If the container does not have an environment variable »cd«,
it will escalate the request to its own container:

Object getEnv( name )
{ if( this.env.contains( name ))return this.env.get( name );
else return this.container.getEnv( name ); }

Or, if a component does not have an own environment storage
itself, it will immediatly escalate:

Object getEnv( name )
{ return this.container.getEnv( name ); }

Lesen Sie weiter auf narkive:
Loading...