我有一个可浮动的工具栏,用户可以在方便的时候四处移动,我想保留最后一个位置,以便他在下次启动时在同一位置找到它。
我正在使用BorderLayout
,因此工具栏可以停靠在北、南、东或西(或位于单独的框架中(,因此我可以调用BorderLayout.getConstraints()
来获取其 BorderLayout 约束。
我注册了一个AncestorListener
来捕获ancestorMoved()
回调,但它以某种方式被随机调用。ComponentListener
具有相同的效果(componentMoved()
回调(。
如果我定期查询工具栏约束,尽管我可以看到它发生了变化,所以我可以在应用程序退出时查询它,但我想了解为什么我的侦听器没有像我希望的那样被调用。
在我的 Ubuntu Oracle JDK 1.7_80 上运行以下 SSCCE,我将工具栏从北移动到西 ->没有输出。从西到南->作品。南到东->作品。东到北->作品。从北到西->没有输出,... 在Oracle JDK 1.8.0_102和Windows上也注意到了相同的行为。
class ToolBarPos extends JFrame {
private static final long serialVersionUID = 1L;
ToolBarPos() {
super();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
Container cp = getContentPane();
final BorderLayout layout = new BorderLayout();
cp.setLayout(layout);
final JToolBar tb = new JToolBar();
cp.add(tb, BorderLayout.NORTH);
tb.addAncestorListener(new AncestorListener() {
@Override public void ancestorAdded(AncestorEvent event) { }
@Override public void ancestorRemoved(AncestorEvent event) { }
@Override public void ancestorMoved(AncestorEvent event) {
String pos = (String)layout.getConstraints(event.getComponent()); // null if detached
System.out.println("Moved "+pos+".");
}
});
tb.add(new JLabel("Element"));
cp.add(new JLabel("CENTER"), BorderLayout.CENTER);
}
public static void main(String[] args) {
new ToolBarPos().setVisible(true);
}
}
我猜当工具栏从北移动到西时,你不会得到一个事件,因为位置没有改变。也就是说,它仍位于内容窗格的 (0, 0( 处。
我建议您使用ComponentListener
并收听componentMoved
和componentResized
事件。