|
|
Java LayoutManager like IB
|
|
|
|
Professional Poster
Join Date: Dec 2000
Location: Chicago, Illinois
Status:
Offline
|
|
Maybe this already exists, but for as long as I've programmed in both pure Java and Cocoa separately, I wanted a Java LayoutManager that worked just like with Cocoa GUI components. So, I threw together the following 2 classes (never done a LayoutManager before, so I'm sure I'm breaking some conventions) and I kind of like how it works.
FahrenbacherLayout
Code:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class FahrenbacherLayout implements LayoutManager2, HierarchyBoundsListener {
private Container parent;
private HashMap<Component,FahrenbacherConstraint> constraintsMap;
private Dimension lastSize;
public FahrenbacherLayout(Container c) {
parent = c;
parent.addHierarchyBoundsListener(this);
constraintsMap = new HashMap<Component,FahrenbacherConstraint>();
}
public void addLayoutComponent(String name, Component comp){}
public void addLayoutComponent(Component comp, Object constraints) {
constraintsMap.put(comp, (FahrenbacherConstraint)constraints);
}
public void removeLayoutComponent(Component comp) {
constraintsMap.remove(comp);
}
public Dimension minimumLayoutSize(Container parent) {
return parent.getMinimumSize();
}
public Dimension preferredLayoutSize(Container parent) {
return parent.getPreferredSize();
}
public Dimension maximumLayoutSize(Container target) {
return parent.getMaximumSize();
}
public float getLayoutAlignmentX(Container target){ return 0.0f; }
public float getLayoutAlignmentY(Container target){ return 0.0f; }
public void layoutContainer(Container parent) {
if(parent.getWidth() == 0 || parent.getHeight() == 0)
return;
else if(lastSize == null)
lastSize = parent.getSize();
int count = parent.getComponentCount();
for(int i = count-1; i>=0; i--) {
Component c = parent.getComponent(i);
FahrenbacherConstraint constr = constraintsMap.get(c);
if(constr != null) {
if(constr.propertyIsOn(FahrenbacherConstraint.STRETCH_HORIZONTALLY))
{
if( constr.propertyIsOn(FahrenbacherConstraint.LEFT_FIXED_DISTANCE) &&
constr.propertyIsOn(FahrenbacherConstraint.RIGHT_FIXED_DISTANCE))
{
c.setSize(parent.getWidth() - c.getX() - (lastSize.width - (c.getX() + c.getWidth())), c.getHeight());
}
else if(constr.propertyIsOn(FahrenbacherConstraint.LEFT_FIXED_DISTANCE))
{
double oldProp = c.getWidth() / (lastSize.getWidth() - c.getX());
c.setSize((int)Math.round((parent.getWidth() - c.getX()) * oldProp), c.getHeight());
}
else if(constr.propertyIsOn(FahrenbacherConstraint.RIGHT_FIXED_DISTANCE))
{
int fromRight = lastSize.width - (c.getX() + c.getWidth());
double oldProp = c.getWidth() / (lastSize.getWidth() - fromRight);
int newWidth = (int)Math.round((parent.getWidth() - fromRight)*oldProp);
int newX = parent.getWidth() - fromRight - newWidth;
c.setSize(newWidth, c.getHeight());
c.setLocation(newX, c.getY());
}
else
{
double midPercentFromLeft = (c.getX() + c.getWidth()/2) / lastSize.getWidth();
double oldProp = c.getWidth() / lastSize.getWidth();
int newWidth = (int)Math.round(parent.getWidth() * oldProp);
int newX = (int)Math.round(parent.getWidth() * midPercentFromLeft - newWidth/2);
c.setSize(newWidth, c.getHeight());
c.setLocation(newX, c.getY());
}
}
else
{
if(constr.propertyIsOn(FahrenbacherConstraint.LEFT_FIXED_DISTANCE)) //ignore right
{
//do nothing! by default, that's how things will orient
}
else if(constr.propertyIsOn(FahrenbacherConstraint.RIGHT_FIXED_DISTANCE))
{
int fromRight = lastSize.width - (c.getX() + c.getWidth());
c.setLocation(parent.getWidth() - fromRight - c.getWidth(), c.getY());
}
else //actually, more work to do in this case!
{
double midPercentFromLeft = (c.getX() + c.getWidth()/2) / lastSize.getWidth();
int newX = (int)Math.round(parent.getWidth() * midPercentFromLeft - c.getWidth()/2);
c.setLocation(newX, c.getY());
}
}
if(constr.propertyIsOn(FahrenbacherConstraint.STRETCH_VERTICALLY)) {
if( constr.propertyIsOn(FahrenbacherConstraint.TOP_FIXED_DISTANCE) &&
constr.propertyIsOn(FahrenbacherConstraint.BOTTOM_FIXED_DISTANCE))
{
c.setSize(c.getWidth(), parent.getHeight() - c.getY() - (lastSize.height - (c.getY() + c.getHeight())));
}
else if(constr.propertyIsOn(FahrenbacherConstraint.TOP_FIXED_DISTANCE))
{
double oldProp = c.getHeight() / (lastSize.getHeight() - c.getY());
c.setSize(c.getWidth(), (int)Math.round((parent.getHeight() - c.getY()) * oldProp));
}
else if(constr.propertyIsOn(FahrenbacherConstraint.BOTTOM_FIXED_DISTANCE))
{
int fromBottom = lastSize.height - (c.getY() + c.getHeight());
double oldProp = c.getHeight() / (lastSize.getHeight() - fromBottom);
int newHeight = (int)Math.round((parent.getHeight() - fromBottom)*oldProp);
int newY = parent.getHeight() - fromBottom - newHeight;
c.setSize(c.getWidth(), newHeight);
c.setLocation(c.getX(), newY);
}
else
{
double midPercentFromTop = (c.getY() + c.getHeight()/2) / lastSize.getHeight();
double oldProp = c.getHeight() / lastSize.getHeight();
int newHeight = (int)Math.round(parent.getHeight() * oldProp);
int newY = (int)Math.round(parent.getHeight() * midPercentFromTop - newHeight/2);
c.setSize(c.getWidth(), newHeight);
c.setLocation(c.getX(), newY);
}
}
else
{
if(constr.propertyIsOn(FahrenbacherConstraint.TOP_FIXED_DISTANCE)) //ignore bottom
{
//do nothing! by default, that's how things will orient
}
else if(constr.propertyIsOn(FahrenbacherConstraint.BOTTOM_FIXED_DISTANCE))
{
int fromBottom = lastSize.height - (c.getY() + c.getHeight());
c.setLocation(c.getX(), parent.getHeight() - fromBottom - c.getHeight());
}
else //actually, more work to do in this case!
{
double midPercentFromTop = (c.getY() + c.getHeight()/2) / lastSize.getHeight();
int newY = (int)Math.round(parent.getHeight() * midPercentFromTop - c.getHeight()/2);
c.setLocation(c.getX(), newY);
}
}
}
}
lastSize = parent.getSize();
}
public void invalidateLayout(Container target){}
public void ancestorMoved(HierarchyEvent e){}
public void ancestorResized(HierarchyEvent e)
{
layoutContainer(parent);
parent.repaint();
}
}
FahrenbacherConstraint
Code:
public class FahrenbacherConstraint {
private int properties;
public static final int NONE = 0;
public static final int STRETCH_VERTICALLY = 1;
public static final int STRETCH_HORIZONTALLY = 2;
public static final int LEFT_FIXED_DISTANCE = 4;
public static final int RIGHT_FIXED_DISTANCE = 8;
public static final int TOP_FIXED_DISTANCE = 16;
public static final int BOTTOM_FIXED_DISTANCE = 32;
public FahrenbacherConstraint(int prop) {
properties = prop;
}
public boolean propertyIsOn(int type) {
return (properties & type) != 0;
}
public void setProperty(int type, boolean on) {
if(on)
properties = (properties | type);
else if(propertyIsOn(type))
properties -= type;
}
}
Example usage:
Code:
JFrame frame = new JFrame();
frame.setSize(300,400);
Container c = getContentPane();
c.setLayout(new FahrenbacherLayout(c));
JButton butt = new JButton("Hi");
butt.setBounds(20,20,100,50);
c.add(butt, FahrenbacherConstraints.LEFT_FIXED_DISTANCE |
FahrenbacherConstraints.RIGHT_FIXED_DISTANCE |
FahrenbacherConstraints.STRETCH_HORIZONTALLY);
|
|
|
|
|
|
|
|
|
Dedicated MacNNer
Join Date: Oct 2003
Location: Round Rock, TX
Status:
Offline
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Forum Rules
|
|
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
|
|
|
|
|
|