我有一个JFrame,其中包含两个嵌套的JSplitPane。我希望在启动时将它们设置为正确的比例。

我不能使用setDividerLocation(int),因为我还不知道框架的大小(我在启动时将其最大化)。因此,我使用比例版本setDividerLocation(double)

码:

// ...
JSplitPane left = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JSplitPane right = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
right.setResizeWeight(1); // So that I can move the dividers independently
left.setLeftComponent(scrollPane1);
right.setLeftComponent(scrollPane2);
right.setRightComponent(scrollPane3);
left.setRightComponent(right);
add(left, BorderLayout.CENTER);
add(statusLabel, BorderLayout.PAGE_END);
setVisible(true);
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
left.setDividerLocation(0.3);
right.setDividerLocation(0.7);
// ...


现在,有时这可以很好地工作,但有时却不会改变分隔线。我相信这是因为未在屏幕上加载框架。从setDividerLocation(double)文档:


如果未正确实现拆分窗格并在屏幕上显示,则此方法无效(新的分隔符位置将变为(当前大小*比例位置)为0)。


有没有办法等到框架“显示在屏幕上”?这大概是几毫秒,但是仍然会在启动时中断布局。我不想使用具有固定值的Thread.sleep,但有些方式可以与Swing一起使用。

编辑:我尝试了hack Behe建议。它没有用,所以可能与时机无关。

编辑2:我调试了更多。看来这是由于我的调整大小权重设置为1引起的。但是,这是我的布局所必需的。

最佳答案

我找到了一个方法。我在内部ComponentListener中添加了JSplitPane,当通过帧最大化调整其大小时会通知我。发生这种情况时,我可以安全地设置调整大小的权重。

final JSplitPane left = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
final JSplitPane right = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left.setDividerLocation(0.3);
right.setDividerLocation(0.3);
left.setLeftComponent(scrollPane1);
right.setLeftComponent(scrollPane2);
right.setRightComponent(scrollPane3);
left.setRightComponent(right);
add(left, BorderLayout.CENTER);
add(status, BorderLayout.PAGE_END);
setVisible(true);
right.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent e) {
        right.setResizeWeight(1);
    }
});
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);

09-29 21:53