Ein sehr nützliches Dialogelement, das mit der Version 1.1 des JDK eingeführt wurde, ist ScrollPane, ein Container für automatisches horizontales und vertikales Scrolling. Ein ScrollPane ist von der Funktion her einem Panel ähnlich und kann wie jedes andere Dialogelement innerhalb eines Fensters verwendet werden. ScrollPane unterscheidet sich allerdings durch zwei wichtige Eigenschaften von einem gewöhnlichen Panel:
|
|
Die innerhalb von ScrollPane angezeigte Komponente arbeitet dabei immer mit der virtuellen Ausgabefläche und merkt nichts von eventuellen Größenbeschränkungen auf dem Bildschirm. Falls die benötigte Ausgabefläche größer ist als die anzeigbare, blendet ScrollPane automatisch die erforderlichen Schieberegler ein, um das Dialogelement horizontal und vertikal verschieben zu können. |
Zur Instanzierung eines ScrollPane stehen zwei Konstruktoren zur Verfügung:
public ScrollPane(); public ScrollPane(int scrollbarDisplayPolicy);
Der Parameter scrollbarDisplayPolicy definiert die Strategie zur Anzeige der Schieberegler entsprechend den in Tabelle 22.2 aufgelisteten Konstanten.
Tabelle 22.2: Konstanten zur Anzeige der Schieberegler in ScrollPane
Nach der Konstruktion des ScrollPane wird die aus Container geerbte Methode add aufgerufen, um eine Komponente hinzuzufügen. Im Gegensatz zu anderen Containern sollte add hier lediglich einmal aufgerufen werden, denn ScrollPane kann nur ein einziges Element aufnehmen. Soll ein komplexer Dialog mit vielen Elementen dargestellt werden, so müssen diese in ein Panel verpackt und dann gemeinsam an add übergeben werden.
Nach dem Einfügen einer Komponente kann die Methode setSize aufgerufen werden, um die sichtbare Größe des ScrollPane festzulegen. Die sichtbare Größe ist die Größe, in der das ScrollPane dem Fenster erscheint, in das es eingebettet wurde. Der dadurch definierte Ausschnitt aus dem virtuellen Ausgabebereich wird als Viewport bezeichnet.
Die Größe des virtuellen Ausgabebereichs wird dagegen durch das mit add eingefügte Element selbst festgelegt. Es überlagert dazu getPreferredSize und gibt so die gewünschten Abmessungen an den Aufrufer zurück. Die Methode getPreferredSize spielt eine wichtige Rolle bei der automatischen Anordnung von Dialogelementen mit Hilfe eines Layoutmanagers. Sie wird aufgerufen, wenn ein Container wissen will, wieviel Platz eine Komponente innerhalb eines Bildschirmlayouts belegt. Wir werden im nächsten Kapitel noch einmal auf getPreferredSize zurückkommen. Abbildung 22.11 faßt die bisherigen Ausführungen zusammen.
Abbildung 22.11: ViewPort und virtueller Ausgabebereich beim ScrollPane
Die Klasse ScrollPane stellt einige Methoden zur Verfügung, mit denen die Darstellung und Reaktion der Schieberegler beeinflußt werden kann:
public Adjustable getHAdjustable(); public Adjustable getVAdjustable();
Mit getHAdjustable wird ein Objekt beschafft, das den Zugriff auf den horizontalen Schieberegler ermöglicht, und mit getVAdjustable eines für den vertikalen Schieberegler. Das Interface Adjustable wurde bereits beim Scrollbar vorgestellt, es abstrahiert den Zugriff auf einen Schieberegler. Da die meisten Eigenschaften der Schieberegler bereits von ScrollPane voreingestellt werden, sollte sich das eigene Programm darauf beschränken, durch Aufruf von setUnitIncrement die Schrittweite der Schieberegler einzustellen.
Des weiteren gibt es einige Methoden für den Zugriff auf den Viewport und seine Position innerhalb des virtuellen Ausgabebereichs:
public Dimension getViewportSize(); public void setScrollPosition(int x, int y); public Point getScrollPosition();
getViewportSize liefert die aktuelle Größe des Viewports. Mit getScrollPosition kann die Position desjenigen Punktes der virtuellen Ausgabefläche ermittelt werden, der gerade in der linken oberen Ecke des Viewports angezeigt wird. Mit setScrollPosition kann der Viewport vom Programm verschoben werden. Die übergeben Werte müssen dabei zwischen 0,0 und der jeweils maximalen Größe des virtuellen Ausgabebereichs minus der Größe des Viewports liegen.
Wir wollen ein einfaches Bespiel konstruieren, das die Anwendung von ScrollPane demonstriert. Dazu soll ein Programm geschrieben werden, das eine Liste aller Systemfarben mit ihrer Bezeichnung und einer Farbprobe auf dem Bildschirm ausgibt. Da es insgesamt 26 verschiedene Systemfarben gibt, soll das Programm jeweils nur einen kleinen Ausschnitt darstellen, der vom Anwender verschoben werden kann.
Zur Erstellung des Programms gehen wir in drei Schritten vor:
import java.awt.*;
import java.awt.event.*;
class NamedSystemColors
{
String names[];
SystemColor colors[];
public NamedSystemColors()
{
names = new String[SystemColor.NUM_COLORS];
colors = new SystemColor[SystemColor.NUM_COLORS];
names [ 0] = "desktop";
colors[ 0] = SystemColor.desktop;
names [ 1]= "activeCaption";
colors[ 1] = SystemColor.activeCaption;
names [ 2] = "activeCaptionText";
colors[ 2] = SystemColor.activeCaptionText;
names [ 3] = "activeCaptionBorder";
colors[ 3] = SystemColor.activeCaptionBorder;
names [ 4] = "inactiveCaption";
colors[ 4] = SystemColor.inactiveCaption;
names [ 5] = "inactiveCaptionText";
colors[ 5] = SystemColor.inactiveCaptionText;
names [ 6] = "inactiveCaptionBorder";
colors[ 6] = SystemColor.inactiveCaptionBorder;
names [ 7] = "window";
colors[ 7] = SystemColor.window;
names [ 8] = "windowBorder";
colors[ 8] = SystemColor.windowBorder;
names [ 9] = "windowText";
colors[ 9] = SystemColor.windowText;
names [10] = "menu";
colors[10] = SystemColor.menu;
names [11] = "menuText";
colors[11] = SystemColor.menuText;
names [12] = "text";
colors[12] = SystemColor.text;
names [13] = "textText";
colors[13] = SystemColor.textText;
names [14] = "textHighlight";
colors[14] = SystemColor.textHighlight;
names [15] = "textHighlightText";
colors[15] = SystemColor.textHighlightText;
names [16] = "textInactiveText";
colors[16] = SystemColor.textInactiveText;
names [17] = "control";
colors[17] = SystemColor.control;
names [18] = "controlText";
colors[18] = SystemColor.controlText;
names [19] = "controlHighlight";
colors[19] = SystemColor.controlHighlight;
names [20] = "controlLtHighlight";
colors[20] = SystemColor.controlLtHighlight;
names [21] = "controlShadow";
colors[21] = SystemColor.controlShadow;
names [22] = "controlDkShadow";
colors[22] = SystemColor.controlDkShadow;
names [23] = "scrollbar";
colors[23] = SystemColor.scrollbar;
names [24] = "info";
colors[24] = SystemColor.info;
names [25] = "infoText";
colors[25] = SystemColor.infoText;
}
public int getSize()
{
return SystemColor.NUM_COLORS;
}
public String getName(int i)
{
return names[i];
}
public SystemColor getColor(int i)
{
return colors[i];
}
}
class SystemColorViewer
extends Canvas
{
NamedSystemColors colors;
public SystemColorViewer()
{
colors = new NamedSystemColors();
}
public Dimension getPreferredSize()
{
return new Dimension(150,16 + colors.getSize() * 20);
}
public void paint(Graphics g)
{
for (int i = 0; i < colors.getSize(); ++i) {
//Rahmen für Farbbox
g.setColor(Color.black);
g.drawRect(10,16+20*i,16,16);
//Farbbox
g.setColor(colors.getColor(i));
g.fillRect(11,17+20*i,15,15);
//Bezeichnung
g.setColor(Color.black);
g.drawString(colors.getName(i),30,30+20*i);
}
}
}
public class Example2210
extends Frame
{
public static void main(String[] args)
{
Example2210 wnd = new Example2210();
wnd.setLocation(200,100);
wnd.setVisible(true);
}
public Example2210()
{
super("Example2210");
setBackground(Color.lightGray);
//ScrollPane
ScrollPane sc = new ScrollPane(
ScrollPane.SCROLLBARS_AS_NEEDED
);
sc.add(new SystemColorViewer());
sc.getVAdjustable().setUnitIncrement(1);
sc.getHAdjustable().setUnitIncrement(1);
sc.setSize(200,200);
add(sc);
//Window-Listener
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent event)
{
setVisible(false);
dispose();
System.exit(0);
}
}
);
//Dialogelement anordnen
pack();
}
}
|
|
Die paint-Methode von SystemColorViewer ist etwas ineffizient, denn sie gibt bei jedem Aufruf den gesamten Inhalt der virtuellen Ausgabefläche komplett aus. Eine bessere Implementierung würde zuvor die Position und Größe der Clipping-Region abfragen und nur diesen Bereich aktualisieren. Die Clipping-Region enthält dabei einen Bereich, dessen Größe und Lage exakt dem aktuellen Viewport entspricht. |
Abbildung 22.12: Verwendung von ScrollPane