Custom Layout Manager in Java (XYLayout)
Java
This year in my Advanced Java Programming class, I put an additional 'Ludo' game as semester project (it is suppose to use RMI).
My students who took the project wanted an easier layout manager to place the components (as I was quite against using null layout manager). So, they ask me whether there exists any XYLayout. It turns out there are some implementations out there, but I was not happy with their licenses. So, I ended up writing my own XYLayoutManager. It will be a good showcase for my students as well. Here goes the code:
Here is the test class.
My students who took the project wanted an easier layout manager to place the components (as I was quite against using null layout manager). So, they ask me whether there exists any XYLayout. It turns out there are some implementations out there, but I was not happy with their licenses. So, I ended up writing my own XYLayoutManager. It will be a good showcase for my students as well. Here goes the code:
/*
* The code is licensed under Create Commons Attribution 3.0 License
* http://creativecommons.org/licenses/by/3.0/
*
* Copyright (c) 2010 Usman Saleem.
* http://usmans.info
*
*/
package info.usmans;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* The XYLayout places components on x,y location
*
* @author usman
*/
public class XYLayout implements LayoutManager {
/*
* This hash table will contain our components and their x,y location as
* constraints
*/
private Map components = new LinkedHashMap();
// Register a component into a map
// The name is the x,y location of the component. i.e. 10,20
public void addLayoutComponent(String name, Component comp) {
// parse name, which should be in int,int format
if (name == null || name.trim().length() <= 0) {
throw new IllegalArgumentException("Invalid constraint: " + name);
}
String[] location = name.split(",");
if (location == null || location.length != 2) {
throw new IllegalArgumentException("Invalid constraint: " + name);
}
int x = 0;
int y = 0;
try {
x = Integer.parseInt(location[0]);
y = Integer.parseInt(location[1]);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Invalid constraint: " + name);
}
components.put(comp, new XYLocation(x, y));
}
// Remove components from our map
public void removeLayoutComponent(Component comp) {
components.remove(comp);
}
public Dimension preferredLayoutSize(Container target) {
return target.getPreferredSize();
}
// for now return preferredlayoutsize
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
// place all components at its desired location
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
for (Component c : components.keySet()) {
XYLocation location = components.get(c);
Dimension dimension = c.getPreferredSize();
c.setBounds(location.x + insets.left, location.y + insets.top,
dimension.width, dimension.height);
}
}
/*
* This class is a simple value object class to hold x and y location
*/
private class XYLocation {
private int x;
private int y;
public XYLocation(int x, int y) {
this.x = x;
this.y = y;
}
}
}
Here is the test class.
/*
* The code is licensed under Create Commons Attribution 3.0 License
* http://creativecommons.org/licenses/by/3.0/
*
* Copyright 2010 Usman Saleem.
* http://usmans.info
*
*/
package info.usmans;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
/**
* A Test application to test XY Layout.
* @author usman
*/
public class TestXYLayout extends JFrame implements ActionListener {
private JLabel board = new JLabel(new ImageIcon(getClass().getResource("ludo1.gif")));
private JLabel stimpy = new JLabel(new ImageIcon(getClass().getResource("stimpy.gif")));
private JPanel panel = new JPanel();
private JPanel bottom = new JPanel();
private JButton moveButton = new JButton("Move");
public void init() {
setSize(560, 620);
//add our panels in JFrame
add(panel, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH );
//add our button in bottom frame
bottom.add(moveButton);
moveButton.addActionListener(this);
//set panel layout to XYLayout
panel.setLayout(new XYLayout());
panel.add("0,0",stimpy);
panel.add("0,0",board);
//draw our components on center panel
drawComponents();
}
private void drawComponents() {
panel.remove(board);
panel.remove(stimpy);
//calculate random x,y position
int x = new Random().nextInt(this.getX()+this.getWidth());
int y = new Random().nextInt(this.getY()+this.getHeight());
panel.add(String.valueOf(x)+","+String.valueOf(y), stimpy);
panel.add("0,0", board);
panel.validate();
}
public void actionPerformed(ActionEvent e) {
drawComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestXYLayout test = new TestXYLayout();
test.init();
test.setDefaultCloseOperation(TestXYLayout.EXIT_ON_CLOSE);
test.setResizable(false);
test.setVisible(true);
}
});
}
}