我对CustomTextField
类实现的焦点侦听器有一个问题。只有当另一个Swing组件获得焦点时,才会调用焦点侦听器。但是如果我通过鼠标拖动来移动JFrame本身,focusLost()
方法永远不会被调用(换句话说,焦点似乎并没有从CustomTextField转移到JFrame)。
编辑:我的问题的解决方案如下:
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class ScrollFocus extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ScrollFocus();
}
});
}
public ScrollFocus() {
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<String> values = new Vector<>();
values.add("a");
values.add("b");
values.add("c");
values.add("d");
values.add("e");
JComboBox<String> comboBox = new JComboBox<>(values);
JScrollPane scrollPane = new JScrollPane(comboBox);
this.add(scrollPane, BorderLayout.NORTH);
CustomTextField customTextField = new CustomTextField();
this.add(customTextField, BorderLayout.CENTER);
JButton button = new JButton("press");
final JPopupMenu menu = new JPopupMenu("Menu");
menu.add(new JMenuItem("Test"));
button.setComponentPopupMenu(menu);
this.add(button, BorderLayout.SOUTH);
pack();
setVisible(true);
}
class CustomTextField extends JTextField implements FocusListener {
private CustomPopup customPopup = new CustomPopup();
public CustomTextField() {
this.addFocusListener(this);
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "VK_UP");
this.getActionMap().put("VK_UP", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "VK_DOWN");
this.getActionMap().put("VK_DOWN", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
}
public void setPopupSize() {
customPopup.setPopupSize(new Dimension(this.getWidth(), 110));
}
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
}
class CustomPopup extends JPopupMenu {
String[] values = new String[]{"Value1", "Value2", "Value3", "Value4", "Value5", "Value6", "Value7",
"Value8","Value9", "Value10", "Value11", "Value12", "Value13", "Value14", "Value15", "Value16",};
JList<String> list = new JList<>(values);
JScrollPane scrollPane = new JScrollPane(list);
public int index = 0;
public CustomPopup() {
this.setLayout(new GridLayout(0,1));
this.add(scrollPane);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
if(customPopup.index > 0)
customPopup.setSelectedIndex(--customPopup.index);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
if(customPopup.index < customPopup.getListSize()-1)
customPopup.setSelectedIndex(++customPopup.index);
}
}
});
this.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
index=0;
}
});
pack();
}
public void setSelectedIndex(int index) {
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
requestFocus();
}
public int getListSize() {
return values.length;
}
}
}
}
发布于 2013-06-01 16:30:29
//customPopup.setVisible(true);
customPopup.show((JComponent)e.getSource(), 0, 20);
您应该使用show(...)
方法来显示弹出窗口。这必须向弹出窗口添加一些侦听器,以便您不再需要文本字段上的FocusListener。
然而,现在这是一个不同的问题。文本字段失去焦点,因此操作永远不会被调用。这是可以的,但JList永远不会获得焦点,所以它不会响应向上/向下键,除非您首先单击列表框。我不确定这里有什么问题。
也许你可以尝试使弹出窗口、滚动窗格和列出所有非焦点,以便焦点停留在文本字段上?
发布于 2013-06-01 10:38:21
不可否认,“焦点”是一个有点模棱两可的术语,通常适用于一个组件,而不是整个窗口。我们认为“有焦点的窗口”,但我认为我们真正的意思是“当前窗口,包含焦点的窗口”。如果我移动窗口(也就是JFrame)本身,我不希望调用focus_lost。
另一种想法是:如果我有一个文本字段,在其中单击,然后键入一两个字母,我就会在该文本字段中看到这些字母。如果我随后稍微移动窗口并键入另外一两个字母,我仍然希望这些字母出现在该字段中。它仍然有专注,从来没有失去过。
https://stackoverflow.com/questions/16870922
复制相似问题