无法找到答案(或者很可能我没有正确询问)。
我的JTextField textfield1
启动后,如何将注意力集中在JFrame
上?
通过焦点我的意思是用户可以立即开始输入,而无需点击JTextField
。
我尝试textfield1.setCaretPosition(0)
和textfield1.moveCaretPosition(0)
,但都没有效果。
点击后,焦点仍然停留在提交按钮上(即使我在点击后调用上面的2)。
答案 0 :(得分:4)
在Swing中可以通过多种方式控制焦点,但在您的情况下,最简单的可能就是使用JTextField#requestFocusInWindow
这有点偏离主题,但你可能想看看How to use the a Focus Subsystem
答案 1 :(得分:3)
比直接请求关注初始组件更有趣的是自定义FocusTraversalPolicy,它实现了查找/配置默认值的一般机制。基本概念已在其api中可用,具有返回初始/ defaultComponent的方法,f.i。:
public abstract Component getDefaultComponent(Container aContainer)
返回要关注的默认Component。这个组件将是 首先在遍历新的焦点遍历时获得焦点 以aContainer为基础的循环。
默认实现返回循环中的第一个组件,自定义实现可能会查找自定义指示符f.i.客户财产。简单的用法会将该策略设置为在其contentPane中具有标记的框架,如:
// a custom policy checking for the property
FocusTraversalPolicy policy = new LayoutFocusTraversalPolicy() {
@Override
public Component getDefaultComponent(Container aContainer) {
if (aContainer instanceof JComponent) {
JComponent parent = (JComponent) aContainer;
if (parent.getClientProperty("defaultFocus") instanceof Component) {
return (Component) parent.getClientProperty("defaultFocus");
}
}
if (aContainer instanceof RootPaneContainer) {
RootPaneContainer root = (RootPaneContainer) aContainer;
JComponent parent = (JComponent) root.getContentPane();
if (parent.getClientProperty("defaultFocus") instanceof Component) {
return (Component) parent.getClientProperty("defaultFocus");
}
}
return super.getDefaultComponent(aContainer);
}
};
JFrame frame = ... // create and fill
JTextField field = new JTextField(20);
frame.add(field, BorderLayout.SOUTH);
// set the client property
((JComponent) frame.getContentPane()).putClientProperty("defaultFocus", field);
// set the custom policy
frame.setFocusTraversalPolicy(policy);
更优雅的是默认使用这样的策略 - 可以通过将其安装为KeyboardFocusManager的默认策略来实现。有了这个,使用将简化为
代码:
// very early in the application code
initializeDefaultFocusTraversalPolicy();
// default in any frame
JFrame frame = ... // create and fill
JTextField field = new JTextField(20);
frame.add(field, BorderLayout.SOUTH);
// set the client property
((JComponent) frame.getContentPane())
.putClientProperty(DelegatingFocusTraversalPolicy.DEFAULT_FOCUS_KEY, field);
Swing不会是Swing它没有捕获,但是:
出路是创建一个虚拟框架,然后设置策略:
public static void initializeDefaultFocusTraversalPolicy() {
// a custom default policy is overwritten by the UIManager the
// very first time it sees a top-level container created
// it does so unconditionally depending on a flag in LAFState
// see UIManager.maybeInitializeFocusPolicy
// so we tricks him into doing it for a fake frame
new JFrame();
// and set our custom default afterwards
FocusTraversalPolicy p = KeyboardFocusManager.getCurrentKeyboardFocusManager()
.getDefaultFocusTraversalPolicy();
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.setDefaultFocusTraversalPolicy(new CustomFocusTraversalPolicy(p));
}
/**
* Basically the same custom policy as the ad-hoc above, just with
* delegating
*/
public static class CustomFocusTraversalPolicy extends FocusTraversalPolicy {
public static final String DEFAULT_FOCUS_KEY = "defaultFocus";
private FocusTraversalPolicy delegate;
public CustomFocusTraversalPolicy(FocusTraversalPolicy delegate) {
this.delegate = Contract.asNotNull(delegate, "the delegate must not be null");
}
@Override
public Component getDefaultComponent(Container container) {
if (container instanceof JComponent) {
JComponent parent = (JComponent) container;
if (parent.getClientProperty(DEFAULT_FOCUS_KEY) instanceof Component) {
return (Component) parent.getClientProperty(DEFAULT_FOCUS_KEY);
}
}
if (container instanceof RootPaneContainer) {
RootPaneContainer root = (RootPaneContainer) container;
JComponent parent = (JComponent) root.getContentPane();
if (parent.getClientProperty(DEFAULT_FOCUS_KEY) instanceof Component) {
return (Component) parent.getClientProperty(DEFAULT_FOCUS_KEY);
}
}
return delegate.getDefaultComponent(container);
}
@Override
public Component getComponentAfter(Container aContainer,
Component aComponent) {
return delegate.getComponentAfter(aContainer, aComponent);
}
@Override
public Component getComponentBefore(Container aContainer,
Component aComponent) {
return delegate.getComponentBefore(aContainer, aComponent);
}
@Override
public Component getFirstComponent(Container aContainer) {
return delegate.getFirstComponent(aContainer);
}
@Override
public Component getLastComponent(Container aContainer) {
return delegate.getLastComponent(aContainer);
}
}