Scrollbalken erst nach manuellem resize sichtbar

Hi,

ich habe folgendes Problem:

Ich habe eine Komponente mit NullLayout (ich weiß, das ist unschön :wink:. Nun kann der Inhalt der Komponente sehr groß werden. Also habe ich eine JScrollPane hinzugefügt. Die Größe der Komponente kann aber erst zur Laufzeit ermittelt werden (je nach dem, was der Benutzer öffnet), so daß ich dann this.setPrefferedSize(breite, höhe) für diese Komponente aufrufe.

Jetzt besteht mein Problem darin, daß nach dem Öffnen der Datei keine ScrollBalken angezeigt werden. Erst wenn ich mit der Maus das Fenster ein Stückchen (oder mehr) vergrößere erscheinen die Balken und ich kann scrollen.

Hat jemand vielleicht eine Idee wie ich das lösen kann? Das benutzen eines Layoutmanagers ist leider keine Option…

Vielen Dank!
Robert

Moin, die ScrollBars sind darauf eingestellt, erst bei Bedarf zu erscheinen.

Du kannst ja mal versuchen die ScrollBarPolicies zu verändern,
dafür werden 2 Methoden gestellt:

setHorizontalScrollBarPolicy(int policy)

Parameter:

* ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
* ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
* ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS

setVerticalScrollBarPolicy(int policy)

Paramater:

* ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
* ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
* ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS

Gruss,
Puni

Hi,

danke für die Antwort. Das mit den Policies habe ich schon ausprobiert. Dann werden die Scrollbars zwar angezeigt, aber sie sind deaktiviert, d.h. ich kann nicht hoch und runter scrollen. Erst wenn ich das Gesamtfenster mit der Maus leicht in der Größe ändere kann ich das tun.

Gruß,
Robert

dann muss da sLayout erst noch angestoßen werden.
Das sollte mit doLayout() funktionieren. Ist in Swing immer etwas undurchsichtig, wann eine Oberfläche aktualisiert wird. Notfalls mit setSize(getSize()); [Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Neuzeichnen von Swing-Komponenten erzwingen
Hallo.

Erst wenn ich das Gesamtfenster mit der Maus leicht
in der Größe ändere kann ich das tun.

dann muss das Layout erst noch angestoßen werden.
Das sollte mit doLayout() funktionieren. Ist in Swing immer
etwas undurchsichtig, wann eine Oberfläche aktualisiert wird.
Notfalls mit setSize(getSize());

revalidate();
repaint();

aufrufen, um das Neuzeichnen einer Komponente zu erzwingen.

Das sollte immer funktionieren, allerdings eventuell
etwas zeitverzögert, da beide Aufrufe letzlich
eine Warteschlange mit Zeichenaufforderungen
füttern.

Schaut man sich den AWT/Swing-Quellcode etwas genauer
an, werden im groben die folgenden Methoden angestossen:

1 **comp.revalidate()**
 1.1 **comp.invalidate()** auf jeder Komponente der Container-Hierarchie
 1.1.1 Markiere die aktuelle Komponente als ungültig
 1.1.2 Ist die aktuelle Komponente ein Container, 
 markiere das Layout dieses Containers als 
 ungültig, falls dieser einen LayoutManager 
 besitzt: **layoutManager.invalidateLayout(comp)**
 1.2 **repaintManager.addInvalidComponent(comp)**
 1.2.1 Der RepaintManager übergibt dem 
 GUI-Ereignisverarbeitungs-Thread (=EDT) einen 
**ComponentWorkRequest** zur späteren Ausführung
 1.2.2 Sobald dieser Request an der Reihe ist, 
 wird **comp.validate()** und für leichtgewichtige
 (=Swing)-Komponenten zusätzlich ein 
**comp.paintImmediatly(...)** ausgeführt
2 **comp.repaint()**
 2.1 Für jede sichtbare schwergewichtige (=AWT-)Komponente 
 der aktuellen Komponentenhierarchie (also in einer 
 Swing-Applikation normalerweise die Wurzelkomponente 
 wie Frame oder Applet) übergebe dem EDT ein 
 AWT-Update-Ereignis.
 2.2 Sobald das Update-Ereignis an der Reihe ist, wird ein
**comp.update(g)** und dadurch das **comp.paint(g)** 
 ausgeführt.

Mit diesem Plan gewappnet lassen sich nun auch die anderen
Varianten verstehen, die man so sieht, um eine Komponente
zum Neuzeichnen zu überreden wie resizeAndRepaint(), updateUI()
oder nicht empfohlene Hacks wie invalidate() + validate() und
das obige setSize(getSize()). All diese Varianten stossen
nämlich indirekt mehr oder minder komplett den skizzierten Ablauf an.

Infos dazu unter:
http://java.sun.com/docs/books/tutorial/uiswing/14pa…
http://java.sun.com/products/jfc/tsc/articles/painti…

sowie der AWT- und Swing-Quellcode unter
http://developer.classpath.org/doc/

Gruß,
-Andreas.

2 Like

Hallo Andreas,

danke für die ausführliche Darstellung.

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Peter,

danke für die ausführliche Darstellung.

Gruß
Peter

Da die Frage sich mit meinem momentanen
Berufsfokus „Swing-Entwicklung“ überschneidet,
ist mir an Klarheit in diesen Dingen selbst
viel gelegen.

Wenn sich meine Antworten dann zudem für andere
als verständlich und hilfreich herausstellen, sehe
ich dieses „Klarheits-Ziel“ erreicht.

Gruß,
-Andreas.

Danke an alle für die Hilfe. Es funktioniert jetzt (habs jetzt mit invalidate()/validate() gemacht). :smile:
Gruß,
Robert

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Robert.

Danke an alle für die Hilfe. Es funktioniert jetzt (habs jetzt
mit invalidate()/validate() gemacht). :smile:

Ging revalidate/repaint nicht?

Gruß,
-Andreas.

Hi,

ich muß die Befehle in einer Klasse aufrufen die von JFrame erbt. Da sagt er mir, daß er die Methode „revalidate()“ nicht kennt. Die stammt nämlich aus JComponent, oder?

Naja, da du mir in diesen Dingen sehr kompetent erscheints vielleicht noch eine Frage :wink: : Ich habe ja jetzt diese Scrollpane. Ich hätte gerne, daß wenn der Benutzer es möchte der Bildausschnitt an einer bestimmten Stelle zentriert wird. Dazu gibt es bestimmte Elemente die der Benutzer auswählen kann und dann soll genau der Ausschnitt mit dem Element in der Mitte erscheinen. Das Programm soll also automatisch da hin scrollen. Ich kenne die Koordinate dieses Elements. Wie mache ich das am besten? Hab schon versucht mit „setViewPosition“ und ähnlichem am ViewPort herumzuspielen, es hat sich aber nichts getan. :frowning:

Gruß,
Robert

Hat sich erledigt. Habs geschafft. :smile:

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]