Reputation: 3324
I'm developing an application and I have a panel that needs a custom LayoutManager. To test my LayoutManager implementation, I would like to have some debug mode built in, very much like MigLayout's debug mode, which draws dashed rectangles when debug mode is on.
In my custom LayoutManager, this is what I tried:
@Override
public void layoutContainer(Container parent) {
// compX.setBounds(...); // calculate for all components and set bounds
parent.getGraphics().drawRect(0,0,parent.getWidth(), parent.getHeight());
}
It doesn't work as you probably expected.
I don't want to modify the panels that are being layed out - just like MigLayout, you specify "debug"
in the MigLayout constructor and you have your dashed lines and you do not need to modify anything in the component that is being layed out.
How can I draw on parent
while not modifying its internals?
Upvotes: 1
Views: 185
Reputation: 51535
Assuming the thingies to paint are hidden details of the LayoutManager, that is the manager itself is indeed the only collaborator with enough knowledge to be able to do the painting, you need a debug painting hook which has no other means but use parent.getGraphics()
As such painting doesn't survive for long, using code must call it repeatedly, f.i. in a Timer.
A LayoutManager with a debug painting hook (note: it's just an example, no hidden state that would justify the trick :)
public static class MyBorderLayout extends BorderLayout {
Color[] colors = new Color[] {Color.RED, Color.BLUE, Color.GREEN, Color.CYAN, Color.MAGENTA};
public void paintDebug(Container parent) {
Graphics g = parent.getGraphics();
for (int i = 0; i < parent.getComponentCount(); i++) {
Component child = parent.getComponents()[i];
g.setColor(colors[i % colors.length]);
Rectangle r = child.getBounds();
g.drawRect(r.x, r.y, r.width, r.height);
}
}
}
// usage:
final JComponent comp = new JPanel(new MyBorderLayout());
comp.add(new JTable(10, 3));
comp.add(new JLabel("east"), BorderLayout.EAST);
comp.add(new JLabel("west"), BorderLayout.WEST);
comp.add(new JLabel("north"), BorderLayout.NORTH);
comp.add(new JLabel("south"), BorderLayout.SOUTH);
ActionListener l = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((MyBorderLayout) comp.getLayout()).paintDebug(comp);
}
};
showInFrame(comp, "debug");
new Timer(400, l).start();
Upvotes: 2