我试图理解我遇到的一个类here来验证我所拥有的几个JTextAreas的输入。我的工作正常,但我对某些逻辑感到困惑,特别提到使用JDialog作为父组件,并希望有人能帮助我更好地理解它。
Abstract validator类:
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的代码然后调用接口方法,看起来它在第一次调用verify()时被用来操作其他组件(通过java),然后是实现的方法&#39 ; validationCriteria()'
但事实上它是一个令我困惑的JDialog,为什么它不仅仅是一个JComponent?我想我在这里缺少一些基础知识 - 这就是为什么我对具体课程的实例只使用了一个新的' JDialog - 虽然我将要阅读inputverifier上的oracle路径,因为我认为这个类设计中的一些可能有点矫枉过正....
答案 0 :(得分:2)
如上所述,我对JDialog的使用更加困惑。从上面链接中的描述,以及使用instanceof的代码然后调用接口方法,看起来它在第一次调用verify()时被用来操作其他组件(通过java),然后是实现的方法'validationCriteria( )”
他们似乎使用JDialog
(或JFrame
)作为他们自己的内部JDialog
的参考点,用于在验证失败时显示消息。这是JDialog
的一个(可选)要求,它允许将它放在称为它的父窗口上
根据示例代码,我会说他们只是在作弊,虽然我没有对其进行测试,但您可以通过null
(但您必须将其转换为JDialog
或JFrame
)
可能还有点旧(或者他们不知道一些额外的API功能)因为他们可以使用setLocationRelativeTo
而不是手动定位对话框
进入细节,validationCriteria
是您为组件提供验证的地方,正如您所描述的那样,verify
调用了它。这提供了一种方法,通过该方法,作者可以控制验证过程并实现其自定义。请注意,c
是对您要验证的JComponent
的引用(即JTextArea
)
作者以WantsValidationStatus
的形式提供了其他自定义功能,可以由parent
(JDialog
或JFrame
)实施,该true
提供了有关验证过程的状态
首先(但不重要)我很困惑为什么作者在抽象类中分离了构造函数?我不认为这特别重要。
我的猜测是,他们希望提供灵活的安排,但不了解Swing API提供的一些功能,例如。您可以将构造函数的数量减少到1并使用SwingUtilities#windowForComponent
来获取对包含组件的窗口的引用
但事实上,它是一个令我困惑的JDialog,为什么它不只是一个JComponent?我想我在这里缺少一些基础知识 - 这就是为什么我的具体类实例化只使用'新'JDialog - 虽然我将在inputverifier上读取oracle路径,因为我认为这个类设计中的一些可能是有点矫枉过正....
嗯,其他两条评论应该已经回答了现在:P
在我看来,这有点不对劲。我没有通过构造函数传递给类的任何组件,显示消息或采取其他操作不是它的责任,它的工作就是验证组件并返回false
/ InputVerifier
(然后控制焦点横向。)
在我看来,validationFailed
最好支持一个观察者模式,然后生成validationPassed
/ filter.setStopwordsHandler(new RegExStopwords("([^\\u1F600-\\u1F6FF\\s].*|[A-Za-z0-9].*|[٠-٩].*|[\\u0617-\\u061A\\u064B-\\u0652].*|[ؐ-ًؚٟ].*|[/(آ|إ|أ)/g, 'ا']|[/(ة)/g, 'ه']|[/(ئ|ؤ)/g, 'ء']|[/(ى)/g, 'ي']|[/([^\\u0621-\\u063A\\u0641-\\u064A\\u0660-\\u0669])/g, '']"));
(或类似)事件并让其他一些委托制作关于应该做什么的决定,但那是;)