/* * @(#)ColumnLayout.java * * $Log: V:/PvcsSwf/Architektur/A1G/Framework/Client/src/cheops/gui/columnLayout/ColumnLayout.java_v $ * * Rev 1.4 Jan 21 2004 13:00:32 RE03277 * ATL: dynamische Höhenausnutzung * * Rev 1.3 May 12 2003 16:48:10 RE03277 * ATL: * Nullabfrage auf getPreferredSize * * Rev 1.2 Nov 30 2001 13:25:14 RE03277 * ATL * wieder revalidate * * Rev 1.0 Aug 29 2001 15:47:02 RE03592 * Initial revision. * * Rev 1.0 Aug 29 2001 15:33:10 RE03592 * Initial revision. * * Rev 1.0 Aug 28 2001 18:05:04 RE03592 * Initial revision. * * Rev 1.0 Jan 26 2001 16:59:56 RE03088 * Initial revision. * * Rev 1.2 May 24 2000 15:31:54 re03277 * ATL: rausgenommen wegen Notebooks * * Rev 1.1 May 19 2000 16:17:18 re03277 * ATL: Höhe der Componenten nur dann berechnen, * wenn die Breite sich geändert hat * * Rev 1.0 May 09 2000 12:47:52 re03590 * Initial revision. * * Rev 1.31 May 03 2000 14:02:52 re03277 * ATL: alle Zeilen (nicht nur die letzte) * werden richtig ausgerichtet * * Rev 1.30 Apr 25 2000 16:12:10 re04749 * FG: Hinweis bei deprecated Konstruktor * ColumnLayout( int, int, int, int ) * eingefügt. * * Rev 1.29 Mar 23 2000 14:42:34 re03277 * ATL: * alternative Layouts * * Rev 1.28 Mar 15 2000 15:08:12 re03277 * ATL: GUI Performance Optimierung * * Rev 1.27 Feb 24 2000 17:47:20 re03277 * ATL: ResizeHeightInterface geändert * * Rev 1.26 Dec 22 1999 13:19:26 re02698 * MT: Workaround für Spacer. * * Rev 1.25 Dec 15 1999 11:00:20 re03277 * ATL: * Ausrichtung innerhalb einer Gruppe eingeführt * * Rev 1.24 Nov 12 1999 10:31:26 re03277 * ATL * */ package cheops.gui.columnLayout; /** * Das ColumnLayout ist ein Standard-Java-Layoutmanager. * Es wird (ueber das LayoutManager3 Interface) das LayoutManager2 * Interface aus java.awt implementiert. * Damit handelt es sich um einen LayoutManager, der Komponenten * durch LayoutConstraints in einem Container arragiert. * * Die Constraints werden fuer den ColumnLayoutManager durch * die Klasse CLC (kurz fuer ColumnLayoutConstraints) angegeben. * */ public class ColumnLayout implements cheops.gui.LayoutManager3 { // Konstanten private static final boolean DEBUG = false; // Default ColumnLayoutDefinition Klassenname private static final String DFT_INIT_CLASS = "cheops.gui.columnLayout.CHEOPS"; // Array mit Spaltendefinitionen private static ColumnData[] columnDefs; // Default Spalte private static int defaultColumn; // Array mit den Breitendefinitionen private static ColumnWidthData[] columnWidthDefs; // Default Spaltenbreite private static int defaultColumnWidth; // Abstand zwischen zwei Zeilen private static int lineSpacing; // Minimale Zeilenhöhe private static int minLineHeight; // Gesamtbreite der fixen Spalten private static int fixwidth; // minimale Gesamtbreite private static int minwidth; // Minimale proportionale Spaltenbreite private static int minColumnWidth; // Index der letzten proportionalen Spalte, oder <0 wenn alle Spalten fix sind private static int lastpropcol; /** * @deprecated Use {@link #ColumnLayout()} instead. */ public ColumnLayout( int a, int b, int c, int d ) { this(); } /** Default Konstruktor */ public ColumnLayout() { this( DFT_INIT_CLASS ); } /** Konstruktor mit ColumnLayoutDefinition Klassenname */ public ColumnLayout( String className ) { if( columnDefs == null ) { // Static Inicializierung ColumnLayoutDefinition lDef = null; try { lDef = ( ColumnLayoutDefinition ) Class.forName( className ).newInstance(); } catch( Exception e ) { throw new cheops.gui.GuiException( 18280, "Could not initialize columnLayout with class: " + className ); } // Speichern der ColumnLayoutDefinition Daten columnDefs = lDef.getColumnDefs(); defaultColumn = lDef.getDefaultColumn(); columnWidthDefs = lDef.getColumnWidthDefs(); defaultColumnWidth = lDef.getDefaultColumnWidth(); lineSpacing = lDef.getLineSpacing(); minLineHeight = lDef.getMinLineHeight(); minColumnWidth = lDef.getMinColumnWidth(); // Konsistenzprüfung fixwidth = 0; float minprop = 1.0f; // kleinste Proportion lastpropcol = -1; float sumprop = 0.0f; // Summe der Proportionen for( int i = 0; i < columnDefs.length; i++ ) { ColumnData column = columnDefs[i]; if( column.proportion != 0.0f ) { // proprotionale Spalte lastpropcol = i; sumprop += column.proportion; minprop = Math.min( minprop, column.proportion ); } else { fixwidth += column.width; } fixwidth += column.leftMargin; } minwidth = fixwidth; if( lastpropcol >= 0 ) { // proportionale Spalten existieren if( sumprop != 1.0 ) { throw new cheops.gui.GuiException( 18281, "ColumnDataTable.computeColumnData: Proportional set columns do not add up to 1 or zero." ); } minwidth += ( int ) ( minColumnWidth / minprop ); } } } // Komponenten der Layout in der umgekehrten Reihenfolge anhand von Zeilennummern private java.util.Vector children = new java.util.Vector( 1 ); // CLC Constraints der Layout in der umgekehrten Reihenfolge anhand von Zeilennummern private java.util.Vector constraints = new java.util.Vector( 1 ); // Performance???: Komponente - Constraints Daten private java.util.HashMap childrenmap = new java.util.HashMap( 11 ); private CLC alternatives; //Größe der Alternativen /** * Adds the specified component to the layout, using the specified constraint object. * @param comp the component to be added * @param constraints where/how the component is added to the layout. */ public void addLayoutComponent( java.awt.Component pComp, Object pConstraints ) { if( ! ( pConstraints instanceof CLC ) ) { throw new cheops.gui.GuiException( 18291, getClass().getName() + "#addLayoutComponent: Constraints are not of type CLC." ); } CLC lCLC = ( CLC ) pConstraints; if( lCLC.startcolumn == CLC.DFT_COLUMN ) { lCLC.startcolumn = defaultColumn; // Ausrechnen der Endspalte } if( lCLC.endcolumn == CLC.LAST_COLUMN ) { // lCLC.endcolumn = columnDefs.length-1; } else if( lCLC.endcolumn == CLC.DFT_COLUMN ) { lCLC.endcolumn = defaultColumn; } else if( lCLC.endcolumn < 0 ) { // Dekodieren von Breiteinformation int width = 0; if( lCLC.endcolumn == CLC.DFT_WIDTH ) { width = defaultColumnWidth; } else { width = - ( lCLC.endcolumn - CLC.WIDTH_OFFSET ); } lCLC.endcolumn = columnWidthDefs[width].endColumns[lCLC.startcolumn]; } CLC oldclc = ( CLC ) childrenmap.get( pComp ); // erste Komponente if( alternatives == null ) { alternatives = new CLC2( lCLC.startcolumn, 0, lCLC.endcolumn ); } CLC alternative = alternatives; if( oldclc == null ) { //neue Komponente childrenmap.put( pComp, lCLC ); int i = constraints.size() - 1; // einfügen der Reihenfolge nach (anhand von Zeilennummern) if( lCLC.row == CLC.AUTO_ROW || lCLC.row == CLC.NEXT_ROW ) { i = -1; } else { while( i >= 0 ) { if( ( ( CLC ) constraints.elementAt( i ) ).row > lCLC.row ) { break; } i--; } } i++; children.insertElementAt( pComp, i ); constraints.insertElementAt( lCLC, i ); } else { // neue Alternative hizufügen while( oldclc.next != null ) { alternative = alternative.next; oldclc = oldclc.next; } if( alternative.next == null ) { alternative.next = new CLC2( columnDefs.length - 1, 0, 0 ); //neue Alternative } alternative = alternative.next; oldclc.next = lCLC; } //Breite der Alternative berechnen alternative.startcolumn = Math.min( alternative.startcolumn, lCLC.startcolumn ); alternative.endcolumn = Math.max( alternative.endcolumn, lCLC.endcolumn ); } /** * Adds the specified component with the specified name to the layout. * @param name the component name * @param comp the component to be added */ public void addLayoutComponent( String pName, java.awt.Component pComp ) { addLayoutComponent( pComp, pName ); //Exception } /** * Removes the specified component from the layout. * @param comp the component ot be removed */ public void removeLayoutComponent( java.awt.Component pComp ) { CLC oldclc = ( CLC ) childrenmap.remove( pComp ); int oldindex = children.indexOf( pComp ); children.removeElementAt( oldindex ); constraints.removeElementAt( oldindex ); while( oldclc.next != null ) { //alternative Layouts löschen CLC prevclc = oldclc; oldclc = prevclc.next; prevclc.next = null; } } /** Gibt die LayoutConstraints der Komponente zurück */ public Object getLayoutConstraints( java.awt.Component pComponent ) { return childrenmap.get( pComponent ); } /** * Returns the alignment along the x axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentX( java.awt.Container pTarget ) { return 0; } /** * Returns the alignment along the y axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentY( java.awt.Container pTarget ) { return 0; } /** * Calculates the minimum size dimensions for the specified * panel given the components in the specified parent container. * @param parent the component to be laid out * @see #preferredLayoutSize */ public java.awt.Dimension minimumLayoutSize( java.awt.Container pParent ) { return preferredLayoutSize( pParent ); } /** * Returns the maximum size of this component. * @see java.awt.Component#getMinimumSize() * @see java.awt.Component#getPreferredSize() * @see LayoutManager */ public java.awt.Dimension maximumLayoutSize( java.awt.Container pTarget ) { return new java.awt.Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE ); } private java.awt.Dimension preferredsize = new java.awt.Dimension(); /** * Calculates the preferred size dimensions for the specified * panel given the components in the specified parent container. * @param parent the component to be laid out * * @see #minimumLayoutSize */ public java.awt.Dimension preferredLayoutSize( java.awt.Container pParent ) { layoutContainer( pParent, false ); java.awt.Dimension dim = new java.awt.Dimension( preferredsize ); java.awt.Insets insets = pParent.getInsets(); dim.width += insets.left + insets.right + topborder * 2; dim.height += insets.top + insets.bottom; return dim; } // Aktuelle Größe // private int width; // private int height; private int lastheight = -1; private static java.awt.Container topcontainer; // Oberste Container aller Komponenten private static int topwidth; // Breite des ColumnLayouts private static int topborder; // Anfangsposition(X) des ColumnLayouts /** Setzt den Obersten Container und die ColumnLayout Parameter @param cont Oberster Container @param width Breite des ColumnLayouts @param offset Anfangsposition(X) des ColumnLayouts innerhalb von cont */ public static void adjust( java.awt.Container cont, int width, int border ) { width = Math.max( width, minwidth ); // Kann nicht schmaler als minwidth sein... if( topcontainer == cont && topborder == border && topwidth == width ) return; topcontainer = cont; topborder = border; topwidth = width; int start = border; // Anfangsposition der Spalten int propwidth = width - fixwidth; // Gesamtbreite der proportionalen Spalten int lastpropwidth = propwidth; // Breite der letzten porportionalen Spalte for( int i = 0; i < columnDefs.length; i++ ) { ColumnData column = columnDefs[i]; start += column.leftMargin; column.start = start; if( column.proportion != 0.0f ) { // proportionale Spalte if( i == lastpropcol ) { column.width = lastpropwidth; // letzte solche Spalte } else { column.width = ( int ) ( propwidth * column.proportion ); lastpropwidth -= column.width; // damit keine Pixels übrig beleiben. } } start += column.width; column.end = start; } } /** * Lays out the container in the specified panel. * @param parent the component which needs to be laid out */ public void layoutContainer( java.awt.Container pParent ) { layoutContainer( pParent, true ); } private final void layoutContainer( java.awt.Container pParent, boolean dolayout ) { boolean widthsok = topwidth == preferredsize.width; if( widthsok && !dolayout || !pParent.isVisible() || alternatives == null ) { return; // bereits gelayoutet } preferredsize.width = topwidth; int visibleheight = -1; if( dolayout && widthsok ) { visibleheight = getVisibleHeight( pParent ); if( visibleheight == lastheight || visibleheight <= 0 ) return; lastheight = visibleheight; } java.util.HashMap bounds = new java.util.HashMap( children.size() * 2 + 1 ); //Component->Rectangle // Nutzbare Spaltenbereich int startColumn = 0; int endColumn = columnDefs.length - 1; preferredsize.height = 0; int startx = 0; // Anfangs X-Position innerhalb des obersten Containers mit ColumnLayout // Suche nach dem ersten schachtelnden ColumnLayout java.awt.Container oldcont = pParent; java.awt.Container cont = oldcont.getParent(); while( cont != null && cont != topcontainer ) { java.awt.LayoutManager lm = cont.getLayout(); if( lm instanceof ColumnLayout ) { // mit ColumnLayout CLC oldclc; CLC lCLC = oldclc = ( CLC ) ( ( ColumnLayout ) lm ).childrenmap.get( oldcont ); // zu propagierende Konstante while( lCLC != null && lCLC.notused ) { lCLC = lCLC.next; // die benutzte Alternative raussuchen } if( lCLC == null ) { lCLC = oldclc; // innerhalb einer unsichtbaren Notebookseite } startColumn = lCLC.startcolumn; if( lCLC.endcolumn >= 0 ) { endColumn = lCLC.endcolumn; } startx = javax.swing.SwingUtilities.convertPoint( pParent, 0, 0, oldcont ).x + columnDefs[startColumn].start; break; } oldcont = cont; cont = cont.getParent(); } boolean used[] = new boolean[columnDefs.length]; // Ist die Spalte schon besetzt? int firstIndexInLine = children.size(); // Index der ersten Komponente in der Zeile int row = 0; // Aktuelle Zeile for( ; --firstIndexInLine >= 0; ) { // Berechnen von row und firstIndexInLine java.awt.Component child = ( java.awt.Component ) children.elementAt( firstIndexInLine ); row = Math.max( row, ( ( CLC ) constraints.elementAt( firstIndexInLine ) ).row ); if( child.isVisible() ) { break; // Komponente sichtbar? } } int y = 0; // Verticale Anfangsposition der Zeile int rowheight = 0; // Höhe der aktuellen Zeile int groupheights[] = new int[CLC.GROUPMASK >> CLC.GROUPBITPOSITION]; // Höhe der Komponentengruppen int alternative = -1; CLC altclc = alternatives; // alternatives Layout aussuchen while( altclc != null ) { alternative++; if( altclc.startcolumn >= startColumn && altclc.endcolumn <= endColumn ) { break; // passt rein } altclc = altclc.next; } if( altclc == null ) { // throw new cheops.gui.GuiException(18291,getClass().getName() + " : "+ System.out.println( "Container has no fitting layout between " + startColumn + " - " + endColumn + " : " + pParent.getClass().getName() + ", nesting container is " + cont.getClass().getName() ); System.out.print( "layout alternatives are: " ); altclc = alternatives; for( int ai = 0; ai <= alternative; ai++, altclc = altclc.next ) { System.out.print( altclc.startcolumn + "-" + altclc.endcolumn + ", " ); } System.out.println(); alternative = -1; altclc = alternatives; } if( alternatives.next == null ) { alternative = -1; //keine Alternativen } java.util.HashMap additionalHeightComponents = new java.util.HashMap( 3 ); float ahwTotal = 0; java.awt.Component child = null; java.awt.Rectangle boundrec = null; for( int i = firstIndexInLine; i >= 0; i-- ) { child = ( java.awt.Component ) children.elementAt( i ); if( !child.isVisible() ) { continue; // Komponente sichtbar? } boundrec = new java.awt.Rectangle(); bounds.put( child, boundrec ); // passende CLC suchen CLC lCLC = ( CLC ) constraints.elementAt( i ); for( int ai = alternative; --ai >= 0; ) { // berechnete Layout verwenden lCLC.notused = true; lCLC = lCLC.next; } if( lCLC.endcolumn < 0 ) { lCLC.endcolumn = altclc.endcolumn = endColumn; } boolean newrow = lCLC.row > row; // neue Zeile nötig? if( newrow || lCLC.row == CLC.NEXT_ROW ) // immer neue Zeile anfangen { newrow = true; } else { boolean overlapped = false; for( int j = lCLC.startcolumn; j <= lCLC.endcolumn; j++ ) { if( used[j] ) { overlapped = true; break; } } if( overlapped ) { if( lCLC.row == CLC.AUTO_ROW ) // neue Zeile anfangen { newrow = true; } else if( alternative == -1 ) { // keine passende CLC gefunden! // throw new cheops.gui.GuiException(18292,getClass().getName() + " : "+ System.out.println( "Component has no fitting constraints: " + child.getClass().getName() + ( child.getName() == null ? "" : "(" + child.getName() + ")" ) + " in container " + pParent.getClass().getName() + ", row=" + row + ", clc.startcolumn=" + lCLC.startcolumn + ", clc.endcolumn=" + lCLC.endcolumn ); System.out.print( "Already used columns are: " ); for( int j = lCLC.startcolumn; j <= lCLC.endcolumn; j++ ) { if( used[j] ) { System.out.print( j + ", " ); } } System.out.println(); } } } lCLC.notused = false; // die benutzte Alternative kennzeichnen for( CLC clc = lCLC.next; clc != null; clc = clc.next ) { clc.notused = true; } if( newrow ) { // neue Zeile anfangen row = Math.max( alignLine( firstIndexInLine, i + 1, rowheight, groupheights, bounds, row ), lCLC.row ); // Aktuelle Zeilennummer = Zeile der ersten Komonente firstIndexInLine = i; for( int j = startColumn; j <= endColumn; j++ ) { used[j] = false; // löschen der Spaltennutzung-flags } for( int j = groupheights.length; --j >= 0; ) { groupheights[j] = 0; // Höhen der Gruppen löschen } y += rowheight + lineSpacing; preferredsize.height += rowheight + lineSpacing; rowheight = 0; } for( int j = lCLC.startcolumn; j <= lCLC.endcolumn; j++ ) { used[j] = true; // eintragen der genutzten Spalten } int x = columnDefs[lCLC.startcolumn].start + lCLC.offset; // Horizontale Position bestimmen int dx = columnDefs[lCLC.endcolumn].end - x; // Positionierung der Komponente boundrec.x = x - startx; boundrec.y = y; java.awt.Point oldlocation = null; if( !dolayout ) oldlocation = child.getLocation(); child.setLocation( boundrec.x, boundrec.y ); // muß noch vor getPreferredSize gemacht werden! // Vertikale Ausdehnung bestimmen int dy = 0; if( child instanceof ResizeHeightInterface ) { float ahw = ( ( ResizeHeightInterface ) child ).getAdditionalHeightWeight(); if( ahw > 0 ) { ahwTotal += ahw; additionalHeightComponents.put( child, new Float( ahw ) ); } dy = ( ( ResizeHeightInterface ) child ).getPreferredHeight( dx ); if( dy < 0 ) { dy = -dy; // Minimumüberprüfung der Zeilenhöhe ausgeschaltet } else { dy = Math.max( dy, minLineHeight ); } } else { java.awt.Dimension dim = child.getPreferredSize(); if( dim == null ) { dy = minLineHeight; } else { dy = Math.max( dim.height, minLineHeight ); } } if( oldlocation != null ) child.setLocation( oldlocation ); // Layouten der Komponente boundrec.height = dy; boundrec.width = dx; //child.setSize( dx, dy ); rowheight = Math.max( dy, rowheight ); // Zeilenhöhe anpassen if( lCLC.groupid > 0 ) // Gruppenhöhe anpassen { groupheights[lCLC.groupid] = Math.max( dy, groupheights[lCLC.groupid] ); } } alignLine( firstIndexInLine, 0, rowheight, groupheights, bounds, row ); // letzte Zeile ausrichten preferredsize.height += rowheight; // Gesamthöhe ausgerechnet if( dolayout ) { if( ahwTotal > 0 ) { if( visibleheight < 0 ) visibleheight = getVisibleHeight( pParent ); lastheight = visibleheight; if( visibleheight > preferredsize.height ) { int free = visibleheight - preferredsize.height; int stillFree = free; int dy = 0; int yrow = 0; int ds = 0; for( int i = children.size(); --i >= 0; ) { child = ( java.awt.Component ) children.elementAt( i ); boundrec = ( java.awt.Rectangle ) bounds.get( child ); if( boundrec == null ) continue; CLC clc = ( CLC ) constraints.elementAt( i ); if( clc.row > yrow ) { dy += ds; ds = 0; } boundrec.y += dy; Float F = ( Float ) additionalHeightComponents.remove( child ); if( F == null ) continue; ds = ( int ) ( F.floatValue() * free / ahwTotal ); if( additionalHeightComponents.size() == 0 ) ds = stillFree; else stillFree -= ds; boundrec.height += ds; preferredsize.height += ds; yrow = clc.row; } } } for( int i = children.size(); --i >= 0; ) { child = ( java.awt.Component ) children.elementAt( i ); boundrec = ( java.awt.Rectangle ) bounds.get( child ); if( boundrec == null ) continue; child.setBounds( boundrec ); } } } //oldstyle private void alignLine(int from, int to, int rowheight, int groupheights[]) { // Ausrichtung for (int i = from; i >= to; i-- ) { java.awt.Component child = (java.awt.Component)children.elementAt(i); if (!child.isVisible()) continue; // nur sichtbare Komponenten CLC lCLC = (CLC)constraints.elementAt(i); java.awt.Rectangle bounds = child.getBounds(); if (lCLC.groupid>0) { int height = groupheights[lCLC.groupid]; // Ausrichtung innerhalb der Gruppe if (lCLC.alignToBaseline == CLC.MIDDLE) bounds.y += (height - bounds.height) / 2; // Zentriert else if (lCLC.alignToBaseline == CLC.BOTTOM) bounds.y += (height - bounds.height); // nach Unten else if (lCLC.alignToBaseline == CLC.RESIZE) bounds.height = height; // Höhe anpassen if (lCLC.groupid>=CLC.BOTTOMGROUP1 >> CLC.GROUPBITPOSITION) { // Ausrichtung der Gruppe innerhalb der Zeile bounds.y += (rowheight - height); // nach Unten } else if (lCLC.groupid>=CLC.CENTERGROUP1 >> CLC.GROUPBITPOSITION) { // zentriert bounds.y += (rowheight - height) / 2; } } else { // Ausrichtung innerhalb der Zeile if (lCLC.alignToBaseline == CLC.MIDDLE) bounds.y += (rowheight - bounds.height) / 2; // Zentriert else if (lCLC.alignToBaseline == CLC.BOTTOM) bounds.y += (rowheight - bounds.height); // nach Unten else if (lCLC.alignToBaseline == CLC.RESIZE) bounds.height = rowheight; // Höhe anpassen } child.setBounds(bounds); } } private static int getVisibleHeight(java.awt.Component pComponent) { int result = 0; // if(pComponent instanceof javax.swing.JComponent) // return (int) ((javax.swing.JComponent) pComponent).getVisibleRect().getHeight(); // else // return pComponent.getHeight(); if( pComponent.getParent() instanceof javax.swing.JViewport) { result = ((javax.swing.JViewport) pComponent.getParent()).getHeight(); } else result = pComponent.getHeight(); return result; } private int alignLine( int from, int to, int rowheight, int groupheights[], java.util.HashMap allbounds, int row ) { // Ausrichtung for( int i = from; i >= to; i-- ) { java.awt.Component child = ( java.awt.Component ) children.elementAt( i ); java.awt.Rectangle bounds = (java.awt.Rectangle)allbounds.get(child); if( bounds==null ) { continue; // nur sichtbare Komponenten } CLC lCLC = ( CLC ) constraints.elementAt( i ); if( lCLC.groupid > 0 ) { int height = groupheights[lCLC.groupid]; // Ausrichtung innerhalb der Gruppe if( lCLC.alignToBaseline == CLC.MIDDLE ) { bounds.y += ( height - bounds.height ) / 2; // Zentriert } else if( lCLC.alignToBaseline == CLC.BOTTOM ) { bounds.y += ( height - bounds.height ); // nach Unten } else if( lCLC.alignToBaseline == CLC.RESIZE ) { bounds.height = height; // Höhe anpassen } if( lCLC.groupid >= CLC.BOTTOMGROUP1 >> CLC.GROUPBITPOSITION ) { // Ausrichtung der Gruppe innerhalb der Zeile bounds.y += ( rowheight - height ); // nach Unten } else if( lCLC.groupid >= CLC.CENTERGROUP1 >> CLC.GROUPBITPOSITION ) { // zentriert bounds.y += ( rowheight - height ) / 2; } } else { // Ausrichtung innerhalb der Zeile if( lCLC.alignToBaseline == CLC.MIDDLE ) { bounds.y += ( rowheight - bounds.height ) / 2; // Zentriert } else if( lCLC.alignToBaseline == CLC.BOTTOM ) { bounds.y += ( rowheight - bounds.height ); // nach Unten } else if( lCLC.alignToBaseline == CLC.RESIZE ) { bounds.height = rowheight; // Höhe anpassen } } row = Math.max(lCLC.row, row); //child.setBounds( bounds ); } for( int i = from; i >= to; i-- ) { java.awt.Component child = ( java.awt.Component ) children.elementAt( i ); java.awt.Rectangle bounds = (java.awt.Rectangle)allbounds.get(child); if( bounds==null ) continue; // nur sichtbare Komponenten CLC lCLC = ( CLC ) constraints.elementAt( i ); lCLC.row = row; } return row+1; } /** * Invalidates the layout, indicating that if the layout manager * has cached information it should be discarded. */ public void invalidateLayout( java.awt.Container target ) { preferredsize.width = 0; // sonst Probleme mit Notebookseiten... lastheight = -1; } //Test************************************************************************************************** public static void show() { show( DFT_INIT_CLASS ); } public static void show( String classname ) { javax.swing.JFrame lFrame = new javax.swing.JFrame( "Column Layout Info" ); lFrame.addWindowListener( new java.awt.event.WindowAdapter() { public void windowClosing( java.awt.event.WindowEvent we ) { System.exit( 0 ); } } ); javax.swing.JScrollPane sp = new javax.swing.JScrollPane( new ColumnLayoutDisplay( classname ) ); lFrame.getContentPane().add( sp ); lFrame.pack(); lFrame.show(); } public static void main( String argv[] ) { if( argv.length == 0 ) { show(); } else { show( argv[0] ); } } private static class ColumnLayoutDisplay extends javax.swing.JComponent { private int START = 60; // Anfangszeile der Balken private int ROWHEIGHT = 15; // Höhe der Balken private int WIDTHSPACING = 2; // Platz zwischen verschiedenen Breiten private int COLSPACING = 5; // Platz zwischen verschiedenen Anfangsspalten public ColumnLayoutDisplay( String classname ) { setLayout( new ColumnLayout( classname ) ); setPreferredSize( new java.awt.Dimension( minwidth, START + ( ( columnWidthDefs.length + 1 ) * ( ROWHEIGHT + WIDTHSPACING ) + COLSPACING ) * columnDefs.length ) ); ; } public void setBounds( int x, int y, int w, int h ) { ColumnLayout.adjust( this, w, 0 ); super.setBounds( x, y, w, h ); revalidate(); } public void paint( java.awt.Graphics g ) { // Spalten zeichnen int c = 0; int y = START; int dy = ROWHEIGHT; java.awt.Color[] COLORS = {java.awt.Color.blue, java.awt.Color.yellow, java.awt.Color.magenta, java.awt.Color.pink, java.awt.Color.orange}; g.setColor( java.awt.Color.white ); g.fillRect( 0, 0, getWidth(), getHeight() ); g.setColor( java.awt.Color.blue ); for( int i = 0; i < columnDefs.length; i++ ) { ColumnData data = columnDefs[i]; g.drawLine( data.start, 0, data.start, getHeight() ); } for( int i = 0; i < columnDefs.length; i++ ) { ColumnData data = columnDefs[i]; g.setColor( java.awt.Color.black ); c++; int xoff = 0; if( i == columnDefs.length - 1 ) { xoff = -g.getFontMetrics().stringWidth( data.name ) + data.width; } if( c % 3 == 0 ) { g.drawString( data.name, xoff + data.start, 50 ); } else if( c % 2 == 0 ) { g.drawString( data.name, xoff + data.start, 35 ); } else { g.drawString( data.name, xoff + data.start, 20 ); } int wc = 0; for( int w = 0; w <= columnWidthDefs.length; w++ ) { int x = columnDefs[i].start; // Horizontale Position bestimmen int dx; if( w < columnWidthDefs.length ) { dx = columnDefs[columnWidthDefs[w].endColumns[i]].end - x; } else { dx = columnDefs[columnDefs.length - 1].end - x; } g.setColor( COLORS[wc++ % COLORS.length] ); g.fillRect( x, y, dx, dy ); g.setColor( java.awt.Color.black ); String s; if( w < columnWidthDefs.length ) { s = columnWidthDefs[w].name; } else { s = "COMPLETE"; } if( i == columnDefs.length - 1 ) { xoff = -g.getFontMetrics().stringWidth( s ); } else { xoff = 0; } g.drawString( s, xoff + x + 2, y + dy - 2 ); y = y + dy + WIDTHSPACING; } y += COLSPACING; } } } }