Java 抽象输入验证器和JDialog类
我试图理解我遇到的一个类,它验证了我在一些jtext领域的输入。我已经让它很好地工作了,但是我对其中的一些逻辑感到困惑,特别提到了使用JDialog作为父组件,希望有人能帮助我更好地理解它 抽象验证器类:Java 抽象输入验证器和JDialog类,java,swing,Java,Swing,我试图理解我遇到的一个类,它验证了我在一些jtext领域的输入。我已经让它很好地工作了,但是我对其中的一些逻辑感到困惑,特别提到了使用JDialog作为父组件,希望有人能帮助我更好地理解它 抽象验证器类: package gui; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Point; import java.awt.event.KeyEvent;
package gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.border.BevelBorder;
public abstract class AbstractValidator extends InputVerifier implements KeyListener{
private JDialog popup;
private Object parent;
private JLabel messageLabel;
private JLabel image;
private Point point;
private Dimension cDim;
private Color color;
private AbstractValidator(){
color = new Color(243,255,159);
}
private AbstractValidator(JComponent c, String msg){
this();
c.addKeyListener(this);
messageLabel = new JLabel(msg + " ");
//image = new JLabel();
}
public AbstractValidator(JDialog parent, JComponent c, String msg){
this(c,msg);
this.parent = parent;
popup = new JDialog(parent);
initComponents();
}
//implement the actual validation logic, returning false if the data is
//invalid and true if it is not. you can also set the popup msg text with
//setMessage() before returning.
//param c is the component to be validated
protected abstract boolean validationCriteria(JComponent c);
//this method is called by Java when a component needs to be validated.
//it should not be called directly. Don't override this unless you want to change
//validation behaviour. implement validationCriteria() instead.
@Override
public boolean verify(JComponent c){
if(!validationCriteria(c)){
if(parent instanceof Validatable)
((Validatable)parent).validateFailed();
c.setBorder(BorderFactory.createLineBorder(Color.RED));
popup.setSize(0,0);
popup.setLocationRelativeTo(c);
point = popup.getLocation();
cDim = c.getSize();
popup.setLocation(point.x-(int)cDim.getWidth()/2, point.y+(int)cDim.getHeight()/2);
popup.pack();
popup.setVisible(true);
return false;
}
c.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
if(parent instanceof Validatable)
((Validatable)parent).validatePassed();
return true;
}
protected void setMessage(String msg){
messageLabel.setText(msg);
}
@Override
public void keyPressed(KeyEvent e){
popup.setVisible(false);
}
@Override
public void keyTyped(KeyEvent e){
}
@Override
public void keyReleased(KeyEvent e){}
private void initComponents(){
popup.getContentPane().setLayout(new FlowLayout());
popup.setUndecorated(true);
popup.getContentPane().setBackground(color);
popup.getContentPane().add(messageLabel);
popup.setFocusableWindowState(false);
}
}
混凝土等级:
package gui;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JTextField;
public class NotEmptyValidator extends AbstractValidator{
public NotEmptyValidator(JDialog parent, JTextField c, String msg){
super(parent,c, msg);
}
protected boolean validationCriteria(JComponent c){
if(((JTextField)c).getText().equals("")){
return false;
}
return true;
}
}
(未使用的)接口:
package gui;
public interface Validatable {
void validateFailed();
void validatePassed();
}
在主JPanel中的JTextField上使用混凝土类:
textField.setInputVerifier(new NotEmptyValidator(new JDialog(), textField, "msg"));
首先(但不重要的是),我对作者为什么在抽象类中分离构造函数感到困惑?但我认为这并不特别重要
不过,正如前面提到的,我对JDialog思想的使用感到更加困惑。
从上面链接中的描述,以及使用instanceof然后调用接口方法的代码来看,它看起来像是在第一次(由java)调用verify()之后再调用实现的方法“validationCriteria()”时用来操作其他组件
但这是一个让我困惑的JDialog,为什么它不只是一个JComponent呢?我想我在这里缺少一些基础知识——这就是为什么我的具体类实例化只使用了一个“新的”JDialog——尽管我将在inputverifier上阅读oracle trail,因为我认为这个类的一些设计可能也有点过火了
不过,正如前面提到的,我对JDialog思想的使用感到更加困惑。从上面链接中的描述,以及使用instanceof然后调用接口方法的代码来看,它看起来像是在第一次(由java)调用verify()之后再调用实现的方法“validationCriteria()”时用来操作其他组件
他们似乎使用JDialog
(或JFrame
)作为自己内部JDialog
的参考点,在验证失败时用于显示消息。这是JDialog
的一个(可选)要求,它允许将它放置在调用它的父窗口上
根据示例代码,我认为他们只是在作弊,虽然我没有测试它,但您可以通过null
(但您必须将其转换为JDialog
或JFrame
)
也可能有点旧(或者他们不知道一些附加的API功能),因为他们可以使用setLocationRelativeTo
而不是手动定位对话框
深入本质,validationCriteria
是您为组件提供验证的地方,正如您所描述的,这被称为verify
。这提供了作者控制验证过程并实现其定制的方法。请记住,c
是对您试图验证的JComponent
的引用(即JTextArea
)
作者以WantsValidationStatus
的形式提供了额外的定制,可由父级(JDialog
或JFrame
)实现,它提供了一种关于验证过程状态的通知方式
首先(但不重要的是),我对作者为什么在抽象类中分离构造函数感到困惑?但我认为这并不特别重要
我的猜测是,他们希望提供灵活的安排,但不理解Swing API提供的一些特性,例如。您可以将构造函数的数量减少到1,并使用来获取对包含该组件的窗口的引用
但这是一个让我困惑的JDialog,为什么它不只是一个JComponent呢?我想我在这里缺少一些基础知识——这就是为什么我的具体类实例化只使用了一个“新的”JDialog——尽管我将在inputverifier上阅读oracle trail,因为我认为这个类的一些设计可能也有点过火了
好吧,其他两条评论现在应该已经回答了这个问题:p
离别的想法
在我看来,这有点错误。我不会让任何组件通过构造函数传递给类,显示消息或执行其他操作不是它的责任,它的工作只是验证组件并返回true
/false
(然后控制焦点横向)
在我看来,InputVerifier
最好支持观察者模式,然后生成validationFailed
/validationPassed
(或类似)事件,并让其他代表决定应该做什么,但这是;)
不过,正如前面提到的,我对JDialog思想的使用感到更加困惑。从上面链接中的描述,以及使用instanceof然后调用接口方法的代码来看,它看起来像是在第一次(由java)调用verify()之后再调用实现的方法“validationCriteria()”时用来操作其他组件
他们似乎使用JDialog
(或JFrame
)作为自己内部JDialog
的参考点,在验证失败时用于显示消息。这是JDialog
的一个(可选)要求,它允许将它放置在调用它的父窗口上
根据示例代码,我认为他们只是在作弊,虽然我没有测试它,但您可以通过null
(但您必须将其转换为JDialog
或JFrame
)
也可能有点旧(或者他们不知道一些附加的API功能),因为他们可以使用setLocationRelativeTo
而不是手动定位对话框
深入本质,validationCriteria
是为组件提供验证的地方,