/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.dlect.ui.layout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.LayoutManager2; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.TreeSet; /** * * @author lee */ public class TableLayout implements LayoutManager2 { private Map<Component, TableConstraints> elements = new HashMap<Component, TableConstraints>(); private int specifiedRowHeight; private int maxGridY; private Map<Integer, Boolean> fullHeightColumns; private Map<Integer, Integer> columnWidths; private Map<Integer, Integer> leftX; private int minWidth; private boolean needsValidating = true; @Override public void addLayoutComponent(Component comp, Object constraints) { TableConstraints cons = null; if (constraints instanceof GridBagConstraints) { cons = TableConstraints.convert((GridBagConstraints) constraints); } else if (constraints instanceof TableConstraints) { cons = (TableConstraints) constraints; } if (cons == null) { throw new IllegalArgumentException("Should pass only a GridBag or Table Constraints object."); } elements.put(comp, cons); } @Override public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } @Override public float getLayoutAlignmentX(Container target) { return 0; } @Override public float getLayoutAlignmentY(Container target) { return 0; } @Override public void invalidateLayout(Container target) { needsValidating = true; } @Override public void addLayoutComponent(String name, Component comp) { // Do Nothing as I need the layout stuff. } @Override public void removeLayoutComponent(Component comp) { elements.remove(comp); } @Override public Dimension preferredLayoutSize(Container parent) { updateComponents(true); // Force the update. Dimension d = new Dimension(minWidth, (maxGridY + 1) * specifiedRowHeight); return d; } @Override public Dimension minimumLayoutSize(Container parent) { return preferredLayoutSize(parent); } @Override public void layoutContainer(Container parent) { updateComponents(); // Force the update. for (Entry<Component, TableConstraints> entry : elements.entrySet()) { Component c = entry.getKey(); TableConstraints tc = entry.getValue(); int gridX = tc.getGridX(); int x = leftX.get(gridX); int width = columnWidths.get(gridX); int height; int y; if (tc.isFullHeight()) { y = 0; height = parent.getHeight(); } else { y = (tc.getGridY() * specifiedRowHeight); height = specifiedRowHeight; } c.setBounds(x, y, width, height); } } private void updateComponents() throws IllegalArgumentException { updateComponents(false); } private void updateComponents(boolean force) throws IllegalArgumentException { if (force || needsValidating) { specifiedRowHeight = 0; maxGridY = 0; columnWidths = new HashMap<Integer, Integer>(); fullHeightColumns = new HashMap<Integer, Boolean>(); for (Entry<Component, TableConstraints> entry : elements.entrySet()) { Component component = entry.getKey(); Dimension pref = component.getPreferredSize(); TableConstraints tableConstraints = entry.getValue(); final int x = tableConstraints.getGridX(); if (tableConstraints.isFullHeight()) { if (fullHeightColumns.containsKey(x)) { throw new IllegalArgumentException("The column " + x + " has an element in it AND it has a Full" + " Height Element in it."); } fullHeightColumns.put(x, Boolean.TRUE); } else { fullHeightColumns.put(x, Boolean.FALSE); specifiedRowHeight = Math.max(specifiedRowHeight, pref.height); maxGridY = Math.max(maxGridY, tableConstraints.getGridY()); } if (columnWidths.containsKey(x)) { columnWidths.put(x, Math.max(columnWidths.get(x), pref.width)); } else { columnWidths.put(x, pref.width); } } } leftX = new HashMap<Integer, Integer>(); TreeSet<Integer> xCords = new TreeSet<Integer>(columnWidths.keySet()); minWidth = 0; for (Integer xCord : xCords) { leftX.put(xCord, minWidth); minWidth += columnWidths.get(xCord); } } }