package com.plectix.simulator.gui.lib;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import javax.swing.Box;
import javax.swing.JPanel;
/**
* A JPanel subclass with some useful functionality for dealing
* with GridBagLayouts.
*
* @author ecemis
*/
@SuppressWarnings("serial")
public class GridBagPanel extends JPanel {
private boolean debug;
/**
* Create a panel with a GridBagLayout.
*/
protected GridBagPanel() {
super();
setLayout(new GridBagLayout());
// Opaque=true is the JPanel default, but Synth overrides this and
// makes it opaque=false by default. We want the default to remain
// the same.
setOpaque(true);
}
/**
* Turn on/off debug mode for this panel. In debug mode, the panel
* boundary is drawn in red, the cell boundaries are drawn in blue,
* and the component boundaries are drawn in green.
* @param debug
*/
void setDebug(boolean debug) {
this.debug = debug;
for (Component c : getComponents()) {
if (c instanceof GridBagPanel)
((GridBagPanel) c).setDebug(debug);
}
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
if (debug) {
// Draw component boundaries
g.setColor(Color.GREEN);
for (Component c : getComponents())
g.drawRect(c.getX(), c.getY(), c.getWidth() - 1,
c.getHeight() - 1);
GridBagLayout layout = (GridBagLayout) getLayout();
int[][] dim = layout.getLayoutDimensions();
int[] widths = dim[0];
int[] heights = dim[1];
Point origin = layout.getLayoutOrigin();
// Compute x locations
int sx = origin.x; // starting x
int ax[] = new int[widths.length + 1];
ax[0] = sx;
for (int i = 0; i < widths.length; i++)
ax[i + 1] = ax[i] + widths[i];
int ex = ax[ax.length - 1]; // ending x
// Compute y locations
int sy = origin.y; // starting y
int ay[] = new int[heights.length + 1];
ay[0] = sy;
for (int i = 0; i < heights.length; i++)
ay[i + 1] = ay[i] + heights[i];
int ey = ay[ay.length - 1]; // ending y
// Draw cell boundaries
g.setColor(Color.BLUE);
for (int x : ax)
g.drawLine(x, sy, x, ey);
for (int y : ay)
g.drawLine(sx, y, ex, y);
// Draw overall boundary
g.setColor(Color.RED);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}
}
/**
* Override the add() method so we can catch the common error when using
* GridBagLayout of forgetting to pass in the GridBagConstraints.
*
* @param comp Component to add
* @see java.awt.Container#add(java.awt.Component)
*/
@Override
public Component add(Component comp) {
throw new UnsupportedOperationException("Missing GridBagConstraints");
}
/**
* Override the add() method so we can catch the common error when using
* GridBagLayout of forgetting to set the layout of the container to
* GridBagLayout.
*
* @param comp Component to add
* @param data Layout data (GridBagConstraints)
* @see java.awt.Container#add(java.awt.Component,java.lang.Object)
*/
@Override
public void add(Component comp, Object data) {
if (data == null || !(data instanceof GridBagConstraints))
throw new UnsupportedOperationException(
"Missing GridBagConstraints");
super.add(comp, data);
if (debug && comp instanceof GridBagPanel)
((GridBagPanel) comp).setDebug(debug);
}
/**
* Shortcut for:
* <pre>
* add(Box.createGlue(), gc.incy().fillBoth());
* </pre>
* @param gc
*/
protected void addGlue(GridBagConstraintsEx gc, int direction) {
switch (direction) {
case GridBagConstraints.BOTH:
add(Box.createGlue(), gc.incy().fillBoth());
break;
case GridBagConstraints.VERTICAL:
add(Box.createVerticalGlue(), gc.incy().fillVertical());
break;
case GridBagConstraints.HORIZONTAL:
add(Box.createHorizontalGlue(), gc.incx().fillHorizontal());
break;
default:
break;
}
}
/**
* Create an "enhanced" GridBagConstraints object with some handy methods.
*
* @return enhanced GridBagConstraints
*/
protected GridBagConstraintsEx createNewConstraints() {
return new GridBagConstraintsEx();
}
public static class GridBagConstraintsEx extends GridBagConstraints {
public GridBagConstraintsEx() {
gridx = 0;
gridy = 0;
insets = new Insets(0, 0, 0, 0);
}
public GridBagConstraintsEx xy(int gridx, int gridy) {
this.gridx = gridx;
this.gridy = gridy;
return this;
}
public GridBagConstraintsEx size(int gridwidth, int gridheight) {
this.gridwidth = gridwidth;
this.gridheight = gridheight;
return this;
}
public GridBagConstraintsEx fill(int fill, float weightx, float weighty) {
this.fill = fill;
this.weightx = weightx;
this.weighty = weighty;
return this;
}
public GridBagConstraintsEx fillHorizontal() {
fill = HORIZONTAL;
weightx = 1;
weighty = 0;
return this;
}
public GridBagConstraintsEx fillVertical() {
fill = VERTICAL;
weightx = 0;
weighty = 1;
return this;
}
public GridBagConstraintsEx fillBoth() {
fill = BOTH;
weightx = 1;
weighty = 1;
return this;
}
public GridBagConstraintsEx fillNone() {
fill = NONE;
weightx = 0;
weighty = 0;
return this;
}
public GridBagConstraintsEx insets(int top, int left, int bottom,
int right) {
insets = new Insets(top, left, bottom, right);
return this;
}
public GridBagConstraintsEx anchor(int anchor) {
this.anchor = anchor;
return this;
}
public GridBagConstraintsEx anchorCenter() {
return anchor(CENTER);
}
public GridBagConstraintsEx anchorLeft() {
return anchor(LINE_START);
}
public GridBagConstraintsEx anchorRight() {
return anchor(LINE_END);
}
public GridBagConstraintsEx anchorTopLeft() {
return anchor(FIRST_LINE_START);
}
public GridBagConstraintsEx incx() {
gridx++;
return this;
}
public GridBagConstraintsEx incy() {
gridy++;
return this;
}
public GridBagConstraintsEx span(int width, int height) {
gridwidth = width;
gridheight = height;
return this;
}
public GridBagConstraintsEx row(int row) {
gridy = row;
return this;
}
public GridBagConstraintsEx col(int col) {
gridx = col;
return this;
}
}
}