Java GUI动态重新定位对象

时间:2012-06-12 17:42:36

标签: java swing gridbaglayout

Hello StackOverflow用户!

我遇到了问题,我找到了问题的解决方案,但我觉得解决方案不是最优。我觉得我用蛮力来实现我想做的事情,并且想知道是否有更好的方法来实现我想要的目标。

基本上我所拥有的是使用GridBagLayout的Java GUI应用程序。我使用GridBagLayout,因为布局基本上总是居中对齐。当添加其他内容时,它会向上,向下,向左或向右移动所有内容(取决于添加新对象的位置)。问题是,我的程序还需要删除某些对象(取决于其他代码块中发生的情况)。所以假设我有四个像[1] [2] [3] [4]这样排列的对象,我想删除[3]。我基本上希望布局更改为[1] [2] [3],实际上在[3]之后将所有内容都移到了一边。在视觉上这样做是没有问题的(因为GridBagLayout的工作原理)。但是,当要将新内容添加到显示中时,会有重叠,因为尽管[4]占据了[3]的视觉位置,但GridBagPosition(不确定还有什么称之为)并没有改变。所以我为删除过程实现了以下代码。

public void removeSubImagePanel (int subPanelIdx) {
    int x, y, nextX, nextY;
    this.remove(this.portraits[subPanelIdx]);

    nextX = this.portraits[subPanelIdx].getGbx();
    nextY = this.portraits[subPanelIdx].getGby();

    for (int i = subPanelIdx; i < this.numberOfPortraits; i++) {
        x = nextX;
        y = nextY;

        this.portraits[i] = this.portraits[i+1];
        if (this.portraits[i+1] != null) {
            nextX = this.portraits[i+1].getGbx();
            nextY = this.portraits[i+1].getGby();
            this.portraits[i].getObject().setSubPanelIdx(i);
            gbc.gridx = x;
            gbc.gridy = y;
            this.portraits[i].setGbLocation(x, y);
            gb.setConstraints(this.portraits[i], gbc);
        }
    }
    this.portraits[this.numberOfPortraits] = null;
    this.numberOfPortraits--;
}

基本上,我在“portraits”对象中添加了两个整数变量来保存GridBagLayout上X和Y的位置。这样,我就可以获得排名[3],将[4]设置[4]的位置定位到[3]所在的位置,然后(如果有[5] 1}},将[5]的位置设置为[4]的旧位置,依此类推,直到我到达最后一个元素。

感觉太“蛮力”,不得不添加那些整数,我觉得如果我为每个对象制作一个单独的GridBagConstraint会更糟。有没有更好的方法来实现我需要做的转变?

抱歉,这个问题很长。我认为不会这么久。我希望这还可以。如果我不清楚你需要澄清,请不要犹豫!

编辑:如果这是在CodeReview stackexchange上会更好吗?它实际上似乎更有意义。我不太确定。

2 个答案:

答案 0 :(得分:2)

我不确定您对此项目的要求是什么,但我会查看Spring Layout - 此布局允许您指定以下内容:

the left of [1] should be 10 pixels from the left of the panel
the right of [1]  should be 10 pixels from the left of [2]
etc.

实现像你在这里描述的流畅布局要容易得多(imo)。

修改:尝试添加到讨论中:

也许你可以有一个名为PortraitPanel的类,它可以从Panel扩展,在那里你可以维护一个图像面板列表。你可以有公共方法:     add(int index);     remove(int index);

因此,当你调用add(2)时,它会将该面板添加到该索引处的列表中 - 然后将面板放在index - 1和index + 1处,然后执行例程来调整这些面板上的约束,以便它放置它们出现在新添加的面板的两侧。类似地,对于remove,你可以使用index - 1并设置它的约束以在index + 1旁边布局,然后删除index处的项。同样,如果你使用SpringLayout,它将很容易设置,以便在窗口调整大小等时保持流畅。

希望这与你想要做的事情一致。

答案 1 :(得分:2)

example表示可以从容器中删除所有组件,并以任意顺序完全替换每个组件。 validate()封闭容器所需的时间可以忽略不计,因为组件本身保持不变。