package boxrenderer; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Rectangle; import java.util.List; import com.google.common.collect.Lists; public class ContentBoxImpl extends AbstractBox implements ContentBox { private static class LayoutInfo { Rectangle position; Box box; public LayoutInfo(Rectangle position, Box box) { this.position = position; this.box = box; } } private List<Box> content = Lists.newArrayList(); private Align align = Align.LEFT; @Override public Dimension getContentDimension(Graphics2D g2) throws Exception { return getSize(layout(g2)); } @Override public void renderContent(Graphics2D g2) throws Exception { List<LayoutInfo> layout = layout(g2); for(LayoutInfo li : layout) { Rectangle pos = li.position; Graphics2D g0 = (Graphics2D)g2.create(pos.x, pos.y, pos.width, pos.height); try { li.box.render(g0); } finally { g0.dispose(); } } } public void addContent(Box content) { this.content.add(content); } private List<LayoutInfo> layout(Graphics2D g2) throws Exception { List<LayoutInfo> layout = Lists.newArrayList(); int x = 0; int y = 0; int lineHeight = 0; int maxWidth = 0; for(Box box : content) { if(!box.isInline()) { Dimension d = box.getDimension(g2); maxWidth = Math.max(maxWidth, d.width); } } for(Box box : content) { Dimension d = box.getDimension(g2); if(box.isInline()) { Rectangle pos = new Rectangle(x,y,d.width,d.height); lineHeight = Math.max(lineHeight, d.height); x+=d.width; layout.add(new LayoutInfo(pos, box)); } else { if(align == Align.LEFT) { x=0; } else if(align == Align.CENTER) { x=maxWidth / 2 - d.width / 2; } else if(align == Align.RIGHT) { throw new RuntimeException("Align right not implemented"); } y+=lineHeight; lineHeight = 0; Rectangle pos = new Rectangle(x,y,d.width,d.height); y+=d.height; layout.add(new LayoutInfo(pos, box)); } } return layout; } private Dimension getSize(List<LayoutInfo> layout) { Dimension result = new Dimension(); for(LayoutInfo li : layout) { result.width = Math.max(result.width, li.position.x+li.position.width); result.height= Math.max(result.height, li.position.y+li.position.height); } return result; } @Override public void setAlign(Align align) { this.align = align; } }