使用 GridBagLayout 为 JFrame 自定义 FocusTraversalPolicy
我有一个包含四个组件的 JFrame:三个 JPanel 和一个 JTabbedPane。两个面板具有可选组件,大约位于 BorderLayout.NORTH 和 EAST,而 JTabbedPane 大约位于 CENTER。 TabbedPane 的选项卡在窗格底部对齐。我说大约是因为实际布局是使用 GridBagLayout 完成的(抱歉!)。
目前,焦点遍历周期是这样的:
Current Cycle:
1) North JPanel
2) East JPanel
3) JTabbedPane selected tab
4) JTabbedPane selected tab content
但是,我希望它是:
Desired Cycle:
1) North JPanel
2) JTabbedPane selected tab content
3) JTabbedPane selected tab
4) East JPanel
我已经尝试了 Java Focus Guide 不幸的是:我无法让光标进入选项卡面板内容。
然后,我考虑扩展/更改其他 FocusTraversalPolicy 类,但也一无所获。
我相当确定问题是当前的 FocusTraversalPolicy 使用屏幕上的组件位置来确定布局周期。从技术上讲,侧面板在屏幕上的位置高于中心选项卡式窗格。但我真的很想改变这一点。还有其他人遇到过这个/有什么见解吗?谢谢!!
编辑:
这是一个带有正确布局代码的 SSCCE,演示了该问题。请注意:问题不在于布局,因为布局必须保持不变。
package SO;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class ssccee7729709{
JPanel north;
JPanel north2;
JPanel east;
JTabbedPane center;
JFrame content;
void initialize() {
north = new JPanel(new FlowLayout()) {
{
this.setBackground(Color.CYAN);
}
};
north.add(new JLabel("Title panel"));
north2 = new JPanel(new FlowLayout()) {
{
this.setBackground(Color.RED);
}
};
north2.add(new JLabel("north2 Panel"));
north2.add(new JTextField(4));
north2.add(new JTextField(4));
east = new JPanel(new GridLayout(3,1)) {
{
this.setBackground(Color.BLUE);
}
};
east.add(new JButton("b1"));
east.add(new JButton("b2"));
center = new JTabbedPane(JTabbedPane.BOTTOM, JTabbedPane.WRAP_TAB_LAYOUT);
for (int i = 0; i < 2; i++) {
JPanel panel = new JPanel(new GridLayout(4,1));
panel.add(new JLabel("Panel " + i));
panel.add(new JTextField(6));
panel.add(new JTextField(6));
panel.add(new JTextField(6));
center.addTab("Tab " + i, panel);
}
content = new JFrame();
content.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
content.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
{
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 4;
gbc.weightx = 1;
content.add(north, gbc);
}
{
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.gridwidth = 1;
gbc.weightx = 1;
// gbc.weighty = .1;
gbc.gridy = 1;
gbc.gridx = 1;
content.add(north2, gbc);
}
{
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = GridBagConstraints.RELATIVE;
gbc.gridheight = GridBagConstraints.RELATIVE;
gbc.weighty = 1;
gbc.gridy = 2;
content.add(center, gbc);
}
{
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.VERTICAL;
gbc.anchor = GridBagConstraints.SOUTHEAST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridx = 3;
gbc.gridheight = 4;
content.add(east, gbc);
}
content.setVisible(true);
content.pack();
}
public static void main(String args[]) {
ssccee7729709 so = new ssccee7729709();
so.initialize();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您查看默认策略 LayoutFocusTraversalPolicy 的源代码,它几乎只是扩展了 SortingFocusTraversalPolicy,它需要一个
Comparator
。您应该能够提供自己的 Comparator,它是一个内部类,因此可以访问父组件,并通过查看自己及其父组件来提供适当的比较值。
查看 LayoutComparator 这是 LayoutFocusTraveralPolicy 使用的。
If you look at the source for LayoutFocusTraversalPolicy, which is the default policy, it pretty much just extends SortingFocusTraversalPolicy, which takes a
Comparator<? extends Component>
.You should be able to provide your own Comparator which is an inner class and so has access to parent components, and provide appropriate comparison values by looking at themselves and their parents.
It probably wouldn't hurt to check out the source to LayoutComparator which is what LayoutFocusTraveralPolicy uses.
克隆 LayoutComparator 后,我必须将以下几行添加到
compare
方法中:老实说,我不知道这是如何工作的...使用
compare
订购组件的机制对我来说很奇怪......但这有效,所以......万岁魔法!After cloning LayoutComparator, I had to add the following lines to the
compare
method:Honestly I don't know how this works...the mechanism of using
compare
to order components is strange to me...but this works, so... hooray magic!