鉴于以下情况:
InputVerifier.
textField是当前的焦点所有者,它的输入不能满足inputVerifier (在这里:在组合框上单击不到3 JComboBox,这将触发 InputVerifier )显示它的错误消息。
F 213
对我来说,这是一种不想要的行为,在inputVerifier满意之前,我希望不让其他组件更改它的输入。在所描述的场景中,JComboBox可以有自己的ActionListener,在出现新的选择时可以改变整个情况。
下面的代码通过应用PopupMenuListener来解决这个问题,它在验证器中检查一个布尔值,告诉它的状态,然后决定是否显示弹出窗口。
我现在想要做的是编写一个扩展的JComboBox类,实现这个功能,并接受所有类型的(扩展) InputVerifiers。但是我已经被困在这里的测试代码中了,因为我不知道如何让PopupMenuListener访问普通的“布尔”“满意”。如果只将一个InputVerifier作为参数传递,则需要稍后进行转换,这就不具有通用性。-还是有“可变”铸造?
任何想法都是受欢迎的,即使它是一种完全不同的方法来解决最初的问题。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
public class DisableComboPopupByVerifier extends JFrame {
public static final long serialVersionUID = 100L;
JComboBox<String> cmb;
public DisableComboPopupByVerifier() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(450, 240);
setLocationRelativeTo(null);
setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));
cmb= new JComboBox<>(new String[]{"AA", "BB", "CC"});
cmb.setPreferredSize(new Dimension(43, 20));
MyMinLenVerifier verifier= new MyMinLenVerifier(this, 3);
MyPopupListener popupListener= new MyPopupListener(verifier);
cmb.addPopupMenuListener(popupListener);
add(cmb);
JTextField tf1= new JTextField(5);
tf1.setInputVerifier(verifier);
add(tf1);
JTextField tf2= new JTextField(5);
tf2.setInputVerifier(verifier);
add(tf2);
SwingUtilities.invokeLater(() -> tf1.requestFocusInWindow());
setVisible(true);
}
static public void main(String args[]) {
EventQueue.invokeLater(DisableComboPopupByVerifier::new);
}
class MyMinLenVerifier extends InputVerifier {
boolean satisfied;
int minlen;
Component parent;
public MyMinLenVerifier(Component parent, int minlen) {
this.minlen= minlen;
this.parent= parent;
}
public boolean verify(JComponent input) {
String s= ((JTextField)input).getText();
if (s.length()>=minlen) {
satisfied= true;
}
else {
satisfied= false;
JOptionPane.showMessageDialog(parent,
"Enter at least "+minlen+" characters.",
"Error", JOptionPane.ERROR_MESSAGE);
}
return satisfied;
}
}
class MyPopupListener implements PopupMenuListener {
//** To accept all kinds of verifiers the specific one here needs to be replaced
by the super class InputVerifier, which, however, makes casting necessary to access the boolean 'satisfied' below.
**//
MyMinLenVerifier verifier;
public MyPopupListener(MyMinLenVerifier verifier) {
this.verifier= verifier;
}
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//** boolean 'satisfied' is a requirement in all passed verifiers. **//
if (!verifier.satisfied) {
BasicComboPopup popup= (BasicComboPopup)cmb.getUI()
.getAccessibleChild(cmb, 0);
SwingUtilities.invokeLater(() -> {
popup.setVisible(false);
// This restauration of the button background is not reliable!
MetalComboBoxButton btn= (MetalComboBoxButton)cmb.getComponent(0);
btn.getModel().setPressed(false);
btn.repaint();
((JComboBox)e.getSource()).repaint();
});
}
}
}
}发布于 2022-05-16 05:25:47
由于缺乏更好的想法,我在MyMinLenVerifier中忽略了MyMinLenVerifier()
@Override
public String toString() {
return "satisfied:"+satisfied;
}MyPopupListener类现在看起来如下所示:
class MyPopupListener implements PopupMenuListener {
InputVerifier verifier;
public MyPopupListener(InputVerifier verifier) {
this.verifier= verifier;
}
.
.
.
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
if (verifier.toString().endsWith("false")) {
...https://stackoverflow.com/questions/72240670
复制相似问题