【问题标题】:Update java Layout Manager更新 java 布局管理器
【发布时间】:2011-09-07 16:33:32
【问题描述】:

我已经全局初始化了一个 GridBagLayout,然后在我的类构造函数中对其进行了实例化并添加了一些按钮等。

事后如何添加内容?简单类扩展了 JFrame。每当我在事后尝试 class.add(stuff, gridbagconstraints) 时(仅在构造函数中使用 add(stuff, gribagconstraints) )什么都没有发生,也没有任何内容添加到我的布局中。

我需要“刷新”布局管理器还是什么?它是全局声明的。

更新:我已经尝试过 revalidate(),但它似乎不起作用,这是我的代码的简化版本,带有一个测试按钮用于概念验证:

public class MainGUI extends JPanel{
    static GridBagConstraints c;
    static MainGUI mainGUIclass;
    static JFrame mainGUIframe;

    public MainGUI() {
    this.setLayout(new GridBagLayout());
    c = new GridBagConstraints();

    saveButton = new JButton("Save and Exit");
    saveButton.setPreferredSize(new Dimension(200, 30));

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 4;
    add(saveButton, c);
    }

public static void main(String[] args) {
    mainGUIframe = new JFrame("Message");

    mainGUIframe.setSize(800,800);

    mainGUIclass = new MainGUI();

    mainGUIframe.add(mainGUIclass);
    mainGUIframe.setVisible(true);


   //now the addition
    JButton newButton = new JButton("New Button");  

    newButton.setPreferredSize(new Dimension(200, 30));


    c.gridx = 5;
    c.gridy = 0;
    c.gridwidth = 4;
    mainGUIclass.add(newButton,c);

    //none of this seems to work
    mainGUIclass.revalidate();//?
    mainGUIclass.repaint();//?

  }
}

Update2:这似乎是 java 的传递值性质和我试图添加到我的布局中的另一个类(画布)的问题。如果我找到解决方案会更新。

Update3:这是一个线程问题,我正在调用的类正在挂起主窗口。

编辑:我提供了代码作为参考,并尽量完整提供完整的图片,不要轻易自行编译。感谢所有提供帮助的人。

更新4:成功!他们的关键是 mediaplayer 类做了一个“isDisplayable()”检查,如果它被添加到的框架没有被添加到 gridbaglayout,它会导致它挂起程序。一系列看起来很不幸的传递值(JInternalFrames),将内部框架预先添加到 gridbaglayout 以及从另一种方法远程启动媒体允许我正在寻求工作。

【问题讨论】:

  • 您发布的代码甚至无法编译。我没有时间修复你的编译错误!此外,您不应该使用静态变量。
  • @Time,MediaPlayer 与什么有什么关系?我们不是头脑读者,这就是为什么您发布的代码应该被编译并展示您遇到的问题的原因。几行代码对我们毫无用处,除非我们知道代码是如何使用的上下文。

标签: java swing layout layout-manager gridbaglayout


【解决方案1】:

您可以在容器上调用revalidate()(如果它派生自 JComponent,例如 JPanel),该容器使用布局让布局重新设置它们包含的组件。这应该通过此布局持有的所有容器进行递归,并且它们也应该更新其组件布局。我知道的主要例外是 JScrollPanes 中保存的组件,为此,您需要在滚动窗格的 JViewport 上调用 revalidate。

此外,有时您需要在revalidate() 之后调用repaint(),尤其是在您移除了容器中的任何组件的情况下。

【讨论】:

  • 只是好奇你用revalidate on the scrollpane's JViewport 是什么意思,嗯,你的意思是用JViewport 移动到正确的点,然后删除-然后-添加+1
  • @mKorbel:如果将组件添加到 JScrollPane 中保存的容器中,那么在 JScrollPane 或任何包含它的容器上调用 revalidate 将不会渗透到 JScrollPane 保存的容器中。您将需要在 JViewport 上调用 revalidate。
  • 我通常 revalidate() 我添加组件的面板,无论面板是否添加到滚动面板。
  • @TimCurry:您没有正确更新 GridBagConstraint,这就是按钮未显示的原因
【解决方案2】:

在您的示例中,您添加的按钮与前一个按钮具有完全相同的GridBagConstraints。当我尝试运行该代码时,您的按钮被放置在彼此之上,因此您只会看到其中一个。尝试更改您的GridBagConstraints,以便将您添加的第二个按钮放置在另一个位置。建议为每个受约束的组件实例化一个新的GridBagConstraints,以消除发生此类编程错误的可能性。

另外,关于您的更新,JFrame 没有revalidate() 函数。

如果您还没有这样做,那么值得您通过this 仔细阅读。

【讨论】:

  • 对不起,这实际上不是我的代码,而是它的简化,我忘记在示例中添加新的 gridbagconstraints,但不是在我的代码中。有关更新,请参见上文。这不是我想象的 GridBagLayout 的问题,而是更新任何布局管理器。
  • @Tim:坦率地说:这是一个糟糕的简化。请发布可编译或几乎可编译的代码。如果我们必须处理糟糕代码产生的其他问题,我们将无法知道您的真正问题是什么。
  • 您使用的是什么版本的 Java?如果我在您的示例中运行(现已更新)代码,我会看到两个按钮都很好。