问题描述
我想更改JSpinner的行为,以便在单击文本时选择它。这样可以更轻松地使用所需的值替换字段。不幸的是,我无法让行为起作用,相反,它只是将光标插入文本而不选择已经存在的内容。
I would like to change the behavior of a JSpinner so that when you click on the text, it selects it. This makes it easier to replace the field with the value that you want. Unfortunately, I can't get the behavior to work and instead, it just inserts the cursor in the text without selecting what is already there.
我尝试添加焦点通过((DefaultEditor)this.getEditor())。getTextField()
监听JSpinner本身和文本区域本身,但这些似乎都没有影响。我的代码(对于JSpinner本身)如下:
I have tried adding a focus Listener to both the JSpinner itself and the text area itself, via ((DefaultEditor) this.getEditor()).getTextField()
, yet neither of these seem to have the intended effect. My code (for the JSpinner itself) is as follows:
spinner.addFocusListener(new FocusAdapter(){
@Override
public void focusGained(FocusEvent e) {
((DefaultEditor) ((JSpinner) e.getSource()).getEditor()).getTextField().selectAll();
}
});
我不确定是什么问题。如果重要的话,我正在运行Mac OS 10.7.5和Java 6u43。
I'm not sure what the problem is. If it matters, I'm running Mac OS 10.7.5 and Java 6u43.
编辑:我放了一个 System.out.println
就在focusGained方法的开头,发现它从未被调用过。所以看起来焦点在于JSpinner没有注册。同样,我尝试将focusAdpater放在微调器和文本字段上(但不是同时)。
I put a System.out.println
right at the beginning of the focusGained method and discovered that it was never called. So it looks like getting focus on the JSpinner isn't registering. Again, I tried putting the focusAdpater both on the spinner and on the text field (not at the same time though).
推荐答案
您遇到的大部分问题都与微调器在焦点事件(以及其他几个状态事件)之后验证旋转器中的任何值有关,这将绕过突出显示。
Much of the problem you are facing has to do with how the spinner validates any values within the spinner AFTER a focus event (and several other state events), which will circumvent the highlight.
MacOS更糟糕。
我最后做的是开始一个线程
等待一个非常短时间段(约25毫秒),然后使用 SwingUtilities.invokeLater
来实际执行选择......
What I ended up doing was starting a Thread
that waited a very short time period (around 25 milliseconds) and then used SwingUtilities.invokeLater
to actually perform the selection...
更新了示例
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.JTextComponent;
public class AutoFocusSpinner {
public static void main(String[] args) {
new AutoFocusSpinner();
}
public static final SelectOnFocusGainedHandler SHARED_INSTANCE = new SelectOnFocusGainedHandler();
public AutoFocusSpinner() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 0, 100, 1));
installFocusListener(spinner);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(spinner);
frame.add(new JButton("Here for testing"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void installFocusListener(JSpinner spinner) {
JComponent spinnerEditor = spinner.getEditor();
if (spinnerEditor != null) {
// This is me spending a few days trying to make this work and
// eventually throwing a hissy fit and just grabbing all the
// JTextComponent components contained within the editor....
List<JTextComponent> lstChildren = findAllChildren(spinner, JTextComponent.class);
if (lstChildren != null && lstChildren.size() > 0) {
JTextComponent editor = lstChildren.get(0);
editor.addFocusListener(SHARED_INSTANCE);
}
}
}
public static <T extends Component> List<T> findAllChildren(JComponent component, Class<T> clazz) {
List<T> lstChildren = new ArrayList<T>(5);
for (Component comp : component.getComponents()) {
if (clazz.isInstance(comp)) {
lstChildren.add((T) comp);
} else if (comp instanceof JComponent) {
lstChildren.addAll(findAllChildren((JComponent) comp, clazz));
}
}
return Collections.unmodifiableList(lstChildren);
}
public static class SelectOnFocusGainedHandler extends FocusAdapter {
@Override
public void focusGained(FocusEvent e) {
Component comp = e.getComponent();
if (comp instanceof JTextComponent) {
final JTextComponent textComponent = (JTextComponent) comp;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textComponent.selectAll();
}
});
}
}).start();
}
}
}
}
现在,现在,我正在祈祷一些非常好,简单,无证的财产,我们可以设置,这意味着我们不需要做所有这些:P
Now, right about now, I'm praying for some really nice, simple, undocumented property that we can set that will mean we don't need to do all this :P
这篇关于使JSpinner在聚焦时选择文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!