【问题标题】:Why does setContentPane() not contain repaint()?为什么 setContentPane() 不包含 repaint()?
【发布时间】:2015-04-25 23:19:46
【问题描述】:

这个问题我想了很久。

我通常通过将JFrame 和包含窗口内容的JPanel 设置为setContentPane() 的内容窗格来构建我的SWING 程序。当我希望将我的内容替换为另一个内容时(例如,单击按钮后获取新蒙版),我再次调用 setContentPane() 并将内容窗格替换为另一个面板。但是每次我这样做时,我都需要在setContentPane() 之后调用repaint() 以使更改可见,因此我创建了一个自己的类用于创建框架。此类扩展 JFrame 并覆盖 setContentPane(),如下所示:

@Override
public void setContentPane(Container c) {
  super.setContentPane(c);
  revalidate();
  repaint();
}

为什么这在默认的JFrame 类中没有实现?这样做会不会有不好的副作用?

【问题讨论】:

  • 你用什么布局管理器?
  • 为什么要这样?一般来说,您应该按原样设置并保留内容窗格。您可能还会对 UI 进行更多更改,而您不想在完成之前安排重绘......
  • 您还要求回溯大约 15 年以上设计和编写 API 的开发人员的头脑。需求与我们今天的需求明显不同,以 JavaFX 的概念差异为例
  • @MadProgrammer:为什么要在 setContentPane() 之后进行更改?我完全准备好新面具,所以我的“主面板”中有全新的面具。在此之后我调用 setContentPane()。这是我要做的最后一步。
  • @Foxx 因为我不认为这是设计者对setContentPane 的想法,他们的想法是“设置”一次,然后修改contentPane 本身的内容。同样,您是在询问设计师最初的想法。

标签: java swing jframe contentpane


【解决方案1】:

我认为这与在 Container 中添加或删除组件后不调用它的原因相同。设置内容窗格与将组件添加到已经存在的窗格相同。组件层次结构失效,所以你必须调用revalidate()repaint()

以及它不被自动调用的原因,在Container.validate()的文档中给出了建议:

验证容器可能是一项相当耗时的操作。出于性能原因,开发人员可能会推迟层次结构的验证,直到一组与布局相关的操作完成,例如将所有子项添加到容器后。

但这只是我的猜测。

【讨论】:

  • 好吧,但我总是先在面板中构建我完全完成的蒙版,当我完成后,我最后将此面板设置为我的 JFrame 的内容窗格。所以我通常会在每个用户操作中调用一次。我无法想象以不同方式使用 setContentPane() 的干净方式。我认为这就是它的目的。
  • 您可以设置内容窗格,然后在其中添加组件。这没什么错。就像Container.add 一样,您可以随时致电setContentPane。没有规定必须始终最后调用它。
  • 嗯...是的,没错。我只是认为这是一步一步做的最好的方法,我的最后一步是每次都是 setContentPane() 。但是好吧,我接受它... ;) 但是当我像我一样使用 setContentPane() 时,使用我从一开始的方法应该没问题,对吧?我认为那里没有不良的副作用。
  • 是的,没关系。虽然,正如 Andrew Thompson 建议的那样,您应该考虑使用CardLayout。重置整个内容窗格可能需要更长的时间,这在 GUI 中会出现短暂的卡顿。
猜你喜欢
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-29
  • 2014-07-15
  • 1970-01-01
  • 2014-04-21
  • 2020-11-01
相关资源
最近更新 更多