在LayoutManager中绘制组件

时间:2013-08-15 09:34:14

标签: java swing drawing awt layout-manager

我正在开发一个应用程序,我有一个需要自定义LayoutManager的面板。为了测试我的LayoutManager实现,我想内置一些调试模式,非常类似于MigLayout的调试模式,它在启用调试模式时绘制虚线矩形。

在我的自定义LayoutManager中,这是我尝试过的:

@Override
public void layoutContainer(Container parent) {
    // compX.setBounds(...); // calculate for all components and set bounds

    parent.getGraphics().drawRect(0,0,parent.getWidth(), parent.getHeight());
}

它不像您预期​​的那样有效。

我不想修改正在布局的面板 - 就像MigLayout一样,您在MigLayout构造函数中指定"debug"并且您有虚线并且您不需要修改组件中的任何内容正在铺设。

如何在parent上绘制而不修改其内部结构?

1 个答案:

答案 0 :(得分:2)

假设要绘制的东西是LayoutManager的隐藏细节,那么管理器本身确实是唯一的协作者,并且有足够的知识能够进行绘画,你需要一个没有其他方法的调试绘画钩子但是使用parent.getGraphics()因为这样的绘画不能存活很长时间,使用代码必须反复调用它,fi在计时器中。

带有调试绘制钩子的LayoutManager(注意:这只是一个例子,没有隐藏的状态可以证明这个技巧:)

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);
        }
    }
}

//用法:

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();