Swing Zeichenfläche ermitteln
Zeichenfläche einer Komponente ermitteln
Einer Swing -Komponente ist zu einem bestimmten Zeitpunkt eine bestimmte rechteckige Komponentenfläche zugeordnet, die durch eine Breite und eine Höhe gekennzeichnet ist. Man beachte, daß es hier zunächst um eine Swing -Komponentenfläche geht, die nicht mit einer Zeichenfläche gleichzusetzen ist, weil nicht immer alle Teile einer Swing -Komponentenfläche als Zeichenfläche zur Verfügung stehen. Wenn in eine Swing -Komponenten gezeichnet werden soll, muß die Größe ihrer Zeichenfläche vielmehr zunächst ermittelt werden.
- Komponentenfläche und Zeichenfläche
.---------------------------------------------------.
| Komponentenflaeche |
| |
| .---------------------------------------------. |
| | verwendbare Zeichenflaeche | |
| | | |
| | | |
| | | |
| | | |
| | | |
| '---------------------------------------------' |
| |
'---------------------------------------------------'
Die Größe einer Zeichenfläche kann nicht direkt aus einem Graphik-Objekt entnommen werden. Beim Zeichnen in eine Swing -Komponente ist vielmehr in der Regel zunächst die Größe der Swing-Komponente der Zeichenfläche zu verwenden. Allerdings kann die Fläche einer Komponente auch noch einen Rahmen enthalten, der von einer Zeichnung nicht gestört werden soll. Daher muß eine Zeichnung in der Komponentenfläche so weit nach rechts unten verschoben werden, daß sie die linken und oberen Rahmenteile nicht verdeckt und sie muß so weit verkleinert werden, daß sie die rechten und unteren Rahmenteile verdeckt. Bei einem Fenster gehört eine eventuell vorhandene obere Titelleiste beispielsweise zu dem Rahmen.
Zur Ermittlung der Größe einer Zeichenfläche ist ihre Komponentenfläche zu bestimmen, von der die Rahmenfläche noch ausgenommen werden muß.
Zunächst soll die Ermittlung des waagerechten x-Bereichs der Zeichenfläche behandelt werden: Für die Komponentenfläche ist das Minimum und die Breite bekannt. Das Minimum ist nämlich immer gleich 0 und für die Komponente "t" ist die Breite ihrer Fläche der Ausdruck "t.getWidth()". Der Deckel (also das um Eins vermehrte Maximum) der x-Werte der Komponentenfläche ist durch diese Breite gegeben, alle x-Werte der Komponentenfläche müssen also kleiner sein, als dieser Deckel.
Mit der Methode "javax.swing.JComponent#getInsets()" kann nun ein Beschreibungsobjekt für den Rahmen (engl. “inset ” = Einfügung, Einsatz) um die Zeichenfläche erhalten werden. Dieses Objekt enthält die Breite der vier Ränder um die Zeichenfläche. Durch die Addition bzw. Subtraktion dieser Breiten von den Werten der Komponentenfläche, erhält man die entsprechenden Werte der Zeichenfläche. So ergibt sich also das x-Minimum "drawMinX" der Zeichenfläche aus der Summe des x-Minimums der Komponentenfläche (gleich 0) und der Breite des linken Rahmens "javax.swing.JComponent#getInsets().left". Der x-Deckel der Zeichenfläche "drawTopX" ergibt sich entsprechend durch Subtraktion der Breite des rechten Rahmens "javax.swing.JComponent#getInsets().right" vom x-Deckel "javax.swing.JComponent#getWidth" der Komponentenfläche.
Die richtigen Werte für die Rahmengröße einer Komponente können erst ermittelt werden, falls diese Komponte schon anzeigbar gemacht wurde. Dies liegt daran, daß die Breite des Rahmens von der Plattform abhängt. Um die Anzeigbarkeit der Komponente zu gewährleisten, kann die Operation "#pack" oder "#show" der Komponente aktiviert werden, falls es nicht sichergestellt ist, daß dies schon geschehen ist.
- Komponentenflaeche, Rahmen und Zeichenfläche
insets.left = 3 insets.right = 3
(Breite) (Breite)
drawMinX = drawTopX = component.getWidth()
insets.left = - insets.right
3 = 22 - 3 = 19
v v 01234567890123456789012345678901
################################
################################
###::::::::::::::::::::::::::###
###::::::::::::::::::::::::::###
################################
################################
^ ^
compMinX = compTopX =
0 this.getWidth() = 22 012345678900123456789012345
numX = 26 = widthX
Das Maximum der Zeichenfläche ergibt sich aus dem um Eins verminderten Deckel.
- Komponentenfläche, Rahmen und Zeichenfläche
drawTopX= this.getWidth()
- insets.right
= 22 - 3 = 19
v 01234567890123456789012345678901
################################
################################
###.------------------------.###
###| |###
###| |###
###| |###
###'------------------------'###
################################
################################
^ ^
drawMinX = drawMaxX
insets.left = drawTopX - 1
Falls eine Komponente keinen Rahmen hat, dann stimmt die Größe der Zeichenfläche mit der Größe der Komponentenfläche überein.
Das Programm "drawingArea.java" zeigt, wie die Größe der verfügbaren Zeichenfläche ermittelt wird. Es wird dann ein Rechteck gezeichnet, dessen Pixel sich gerade noch innerhalb der verfügbaren Zeichenfläche befindet, das also die Zeichenfläche bestmöglich ausnutzt. Das Rechteck wird hier mit vier einzelnen Linien gezeichnet, da die Verwendung der Swing-Operation zum Zeichnen eines Rechtecks hier die richtigen Koordinatenwerte nicht so gut verständlich machen würde.
drawingArea.java
public class drawingArea { public static void main( final String[] args ) { javax.swing.JFrame.setDefaultLookAndFeelDecorated( true );
final javax.swing.JFrame frame = new javax.swing.JFrame( "JFrame" );
frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( new DrawPanel1() );
frame.pack(); frame.setVisible( true ); }} class DrawPanel1 extends javax.swing.JPanel { public DrawPanel1() { this.setBorder( javax.swing.BorderFactory.createCompoundBorder
( javax.swing.BorderFactory.createRaisedBevelBorder(),
javax.swing.BorderFactory.createLoweredBevelBorder() )); } public void paintComponent( final java.awt.Graphics g1 )
{ super.paintComponent( g1 ); final java.awt.Graphics2D g =( java.awt.Graphics2D )g1; final java.awt.Insets insets = this.getInsets(); final int compTopX = this.getWidth() ;
final int compTopY = this.getHeight(); final int drawTopX = compTopX - insets.right;
final int drawTopY = compTopY - insets.bottom; final int drawMinX = insets.left;
final int drawMinY = insets.top; final int drawMaxX = drawTopX - 1;
final int drawMaxY = drawTopY - 1; g.drawLine( drawMinX, drawMinY, drawMaxX, drawMinY );
g.drawLine( drawMaxX, drawMinY, drawMaxX, drawMaxY );
g.drawLine( drawMaxX, drawMaxY, drawMinX, drawMaxY );
g.drawLine( drawMinX, drawMaxY, drawMinX, drawMinY ); }}
Man beachte, daß es etwas uneinheitlich ist, daß die Werte des "JComponent"-Objekts durch get -Methoden-Aufrufe erhalten werden und die Werte des "Insets"-Objekts durch Feldzugriffe.
Nun ist klar, wie die Größe der Zeichenfläche aus der Größe der Komponentenfläche ermittelt werden kann.
Bei Zeichnen in einen Komponente soll nur in die Zeichenfläche gezeichnet werden und nicht in die möglicherweise größere Komponentenfläche.
- / Methode zum Ermitteln der Zeichenfläche
- Schreiben Sie eine Methode, welche für ein Objekt der Klasse "java.awt.Container" die nach Abzug eines Rahmens verfügbare Zeichenfläche ermittelt. Als Ergebnis soll diese Methode ein Objekt der Klasse "java.awt.Rectangle" liefern, das ein Rechteck mit den sich ergebenden Koordinaten darstellt. Schreiben Sie die Übersetzungseinheit "drawingArea.java" dann so um, daß sie diese Methode verwendet.