/** * Calculate the minimum or preferred size of every row or column. * * @param dim the minimum or preferred size of every child * @param row true if row sizes should be calculated, false if column sizes should be calculated * @return the size required for every row or column */ private int[] calculateRequiredSizes(Dimension dim[], boolean row) { // Build a linked list of size requirements of every child. LinkedList<int[]> requiredList = new LinkedList<int[]>(); for (int i = 0; i < dim.length; i++) { ChildInfo info = child.get(i); if (row) requiredList.addLast(new int[] {info.y, info.height, dim[i].height}); else requiredList.addLast(new int[] {info.x, info.width, dim[i].width}); } // Find the required size for each row or column. int width[] = new int[row ? rowWeight.length : colWeight.length]; double weight[] = (row ? rowWeight : colWeight); for (int currentWidth = 1; requiredList.size() > 0; currentWidth++) { // Apply constraints for all children which occupy currentWidth rows or columns. Iterator<int[]> iter = requiredList.iterator(); while (iter.hasNext()) { int req[] = iter.next(); if (req[1] != currentWidth) continue; iter.remove(); if (currentWidth == 1) { width[req[0]] = Math.max(width[req[0]], req[2]); continue; } // Find how much space is currently available. int total = 0; for (int i = 0; i < currentWidth; i++) total += width[req[0] + i]; if (total >= req[2]) continue; // It is already wide enough. // Allocate additional space to the rows or columns, based on their weights. double totalWeight = 0.0; for (int i = 0; i < currentWidth; i++) totalWeight += weight[req[0] + i]; int extra[] = new int[currentWidth]; int totalExtra = 0; for (int i = 0; i < currentWidth - 1; i++) { double w = (totalWeight > 0.0 ? weight[req[0] + i] / totalWeight : 1.0 / currentWidth); extra[i] += w * (req[2] - total); totalExtra += extra[i]; } extra[extra.length - 1] = req[2] - total - totalExtra; for (int i = 0; i < currentWidth; i++) width[req[0] + i] += extra[i]; } } return width; }