/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.works.editor.grammar.syndiag; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Rectangle; import javax.swing.JPanel; public class Alt extends JPanel implements Element { public static final int ELEMENT_SEP = 20; public static final int EMPTY_ALT_HEIGHT = 10; public Alt() { super(new GridBagLayout()); setOpaque(false); } @Override public Dimension getPreferredSize() { if (getComponentCount() == 0) { return new Dimension(ELEMENT_SEP, EMPTY_ALT_HEIGHT); } return super.getPreferredSize(); } @Override public Component add(Component comp) { GridBagConstraints constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.NORTHWEST; if (comp instanceof Block) { constraints.insets = new Insets(Block.ALT_SEP / 2, 0, Block.ALT_SEP / 2, 0); } else { constraints.insets = new Insets(Block.ALT_SEP / 2, ELEMENT_SEP / 2, Block.ALT_SEP / 2, ELEMENT_SEP / 2); } add(comp, constraints); return comp; } @Override public void updatePositions() { for (Component child : getComponents()) { if (child instanceof Element) { ((Element)child).updatePositions(); } } GridBagLayout layout = (GridBagLayout)getLayout(); int connectionPoint = getConnectionPointY() - getY(); for (Component child : getComponents()) { if (!(child instanceof Element)) { continue; } int childConnectionPoint = ((Element)child).getConnectionPointY(); if (childConnectionPoint == connectionPoint) { continue; } GridBagConstraints childConstraints = layout.getConstraints(child); childConstraints.insets.top -= (childConnectionPoint - connectionPoint); layout.setConstraints(child, childConstraints); invalidate(); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (Rule.OUTLINE_ELEMENTS) { Color oldColor = g.getColor(); g.setColor(new Color(Color.red.getRed(), Color.red.getGreen(), Color.red.getBlue(), 0xFF >> 2)); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); g.setColor(oldColor); } if (getComponentCount() > 0) { Component[] elems = getComponents(); Element prev = null; for (Component elem : elems) { Element n = (Element)elem; if (prev != null) { connect(prev, n, g); } prev = n; } } else { g.drawLine(0, getHeight() / 2, getWidth() - 1, getHeight() / 2); } } public void connect(Element a, Element b, Graphics g) { Rectangle aBounds = a.getBounds(); Rectangle bBounds = b.getBounds(); int y1 = a.getConnectionPointY(); int y2 = b.getConnectionPointY(); g.drawLine((int)(aBounds.x + aBounds.getWidth()), y1, bBounds.x, y2); } public int getLeftEdge() { Graphics g = getGraphics(); Component[] elems = getComponents(); return elems[0].getBounds().x; } @Override public int getConnectionPointY() { if (getComponentCount() == 0) { return (int)getBounds().getCenterY(); } int connectionPoint = 0; for (Component child : getComponents()) { connectionPoint = Math.max(connectionPoint, getY() + ((Element)child).getConnectionPointY()); } return connectionPoint; } }