问题
I have JPanel which contains JSplitPane. The JPanel is injected during a runtime into a JFrame using the method invokeAndWait. Then the invokeLater is called to update divider location in SplitPane.
The problem is, when the divider update is invoked, JPanel width is still 0.
When I add sleep or a breakpoint anywhere in the code (except the invokeLater), the code works fine.
final JPanel viewPanel = new JPanel();
viewPanel.setLayout(new BorderLayout());
final JPanel header = getPresenterHeader(getPageTitle(), getPageInstructions());
viewPanel.add(header, BorderLayout.NORTH);
viewPanel.add(getSplitPane(), BorderLayout.CENTER);
toolbar = createActionsToolBar();
toolbar.addAction(new ExitPresenterAction(this));
viewPanel.add(toolbar, BorderLayout.SOUTH);
addContent(viewPanel);
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
splitPane.setDividerLocation(0.5);
}
});
回答1:
I'm not sure whether it helps for you, but we have a method which mostly helps in this situation:
public static JSplitPane setDividerLocation(final JSplitPane splitter, final double proportion) {
if (splitter.isShowing()) {
if ((splitter.getWidth() > 0) && (splitter.getHeight() > 0)) {
splitter.setDividerLocation(proportion);
} else {
splitter.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent ce) {
splitter.removeComponentListener(this);
setDividerLocation(splitter, proportion);
}
});
}
} else {
splitter.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
if (((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) && splitter.isShowing()) {
splitter.removeHierarchyListener(this);
setDividerLocation(splitter, proportion);
}
}
});
}
return splitter;
}
Use it instead of invokeLater
call
setDividerLocation(splitPane, 0.5);
来源:https://stackoverflow.com/questions/40213542/how-to-set-divider-location-for-jsplitpane-on-start-up