Java Swing - 难以实现所需的布局

时间:2013-03-14 17:09:12

标签: java swing layout jpanel

我正在使用Swing在Java中编写GUI。目前,我正在尝试创建一个“模块”(黄色块),左边和右边有一个小工具架(黑色条)。每个支架将容纳几个我希望以垂直线显示的小块。这是一张图片:

示例模块: enter image description here

我希望能够沿着小工具夹具均匀地放置洋红色/青色块。

我看过Swing的几个教程,并尝试将小部件持有者的布局实现为GridLayout和BoxLayout,但两者都没有运气。单列GridLayout似乎是这里的自然选择,但我似乎无法使其工作,即使我已经编写了正确使用网格的小型测试程序。

布局管理人员在简单的例子中工作但不是在这个稍微复杂的程序中这一事实让我感到困惑。

在我的计划中,

  • 该模块是JPanel
  • 小部件持有人/黑条也是JPanels
  • 小部件本身(青色/洋红色块)目前是JPanels,但我也试过将它们作为JLabel和JButton。我只是希望他们能够收听鼠标事件并拥有一个区域和颜色。

另一方面,我也遇到了模块本身的布局问题,无法将小部件支架放在左右两侧。我尝试使用水平BoxLayout(支架,水平胶水,支架),另一次我尝试使用BorderLayout(使用EAST / WEST作为持有者),但无论我做了什么,持有人都不会让步 - 所以和我一样多我不想,我用setBounds()来定位它们。

模块类(小部件持有者是inputLine和outputLine):

public class Module extends JPanel
{
private static final int MOD_WIDTH  = 86;
private static final int MOD_HEIGHT = 60;

private int screenX, screenY, myX, myY;

private boolean moving = false;

// figure out the layout !
private JPanel inputLine, outputLine;

public Module()
{
    //super(new BorderLayout());

    initPanel();
    initWidgets();
    initMouse();

    setLayout(null);

    list();
}

private final void initPanel()
{
    this.setSize(new Dimension(MOD_WIDTH, MOD_HEIGHT));
    this.setBackground(Color.ORANGE);
}

private void initWidgets()
{
    inputLine   = new JPanel(new GridLayout(0, 1, 5, 5));
    outputLine  = new JPanel(new GridLayout(0, 1, 5, 5));

    inputLine.setBounds (0, 0, 18, 60);
    outputLine.setBounds(68, 0, 18, 60);

    this.add(inputLine);
    this.add(outputLine);

    /* adding IOWidgets to test */
    inputLine.add(new InputWidget());
    inputLine.add(new InputWidget());
    inputLine.add(new InputWidget());

    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());

    inputLine.setBackground(Color.BLACK);
    outputLine.setBackground(Color.BLACK);
}


这是两种类型的小部件(输入[洋红色],输出[青色])派生自的抽象IOWidget类。它稍后会添加功能。

public abstract class IOWidget extends JLabel
{   

    private static final int EDGE_SIZE = 8;

    public IOWidget()
    {
        this.setSize(new Dimension(EDGE_SIZE, EDGE_SIZE));
    }
}


这是InputWidget类。目前,它与OutputWidget完全相同,直到我添加了额外的功能,所以我只发布这个:

public class InputWidget extends IOWidget
{
    public InputWidget()
    {
        this.setBackground(Color.MAGENTA);
    }
}


在我的应用程序中,模块被添加到更大的JPanel中。我希望模块的布局与它添加到另一个JComponent的方式无关,所以我将省略其余的代码。

以下是程序在运行时的样子:

enter image description here

为了完整性,这是单个模块上调用列表的输出:

rhopkins.honors.Dataflow.Module[,0,0,86x60,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
 javax.swing.JPanel[,0,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
 javax.swing.JPanel[,68,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]

我非常想知道我做错了什么。另外,我知道我对Swing和GUI开发很新,所以对样式/约定/任何东西的任何批评都是受欢迎的。

1 个答案:

答案 0 :(得分:4)

不要使用null布局。

您的主面板可能应该是BorderLayout。您可以将小部件持有者添加到主面板的WEST和EAST。

小部件面板应该能够使用垂直BoxLayout。您需要在添加到面板的每个小部件之前/之后添加胶水。由于BoxLayout尊重组件的大小,因此您需要覆盖getPreferredSize(),getMinimumSize()和getMaximumSize()方法,以返回相同的值。这样,面板中的任何额外空间都应该在您添加的胶水中平均分配。