2012-05-24 29 views
0

我目前正在研究我们小组第一学期考试项目的GUI部分,并且遇到了一个关于回调和事件处理的奇怪问题。FocusListener回调方法不适用于来自相同变量的单独实例化对象吗?

有点偏离主题:我用这个搜索引擎很难,但真的没有找到在Java中使用回调的具体例子,所以从我收集的...根据定义...我是什么在这里做实际上是一个回调(将是真棒,如果你能解释一下为什么,或指向我一个网页,详细地介绍了它)

下面的代码:

private FocusListener callback = new FocusListener(){ 
    @Override public void focusGained(FocusEvent e){ 
     if(hasBeenSet){}else{tfield.setText("");hasBeenSet=true;} 
    } @Override public void focusLost(FocusEvent e){}}; 

    ... 

    tfield = new JTextField("Insert CPR number", 8); 
    constraint.gridx = 0; 
    constraint.gridy = 1; 
    constraint.gridwidth = 2; 
    panel.add(tfield, constraint); 

      tfield.addFocusListener(callback); 

    tfield = new JTextField("Type new password", 8); 
    constraint.gridx = 0; 
    constraint.gridy = 2; 
    panel.add(tfield, constraint); 

      tfield.addFocusListener(callback); 

    tfield = new JTextField("Retype new password", 8); 
    constraint.gridx = 0; 
    constraint.gridy = 3; 
    panel.add(tfield, constraint); 

      tfield.addFocusListener(callback); 

当我进入GUI,它具有这三(3)个文本字段,并且当用户关注文本字段时,该想法是删除文本。这应该适用于所有三个文本字段,但显然,无论您单击哪个文本字段,只有最后一个文本字段被设置为空字符串。我对此很好奇,因为每个对象都是单独实例化的。

这里最明显的解决办法,是只重命名tfield喜欢“tfield [1-3]”,但如果你能幽默我这个:)

也将是巨大的:请注意,所有的GUI代码实际上在构造函数内部。是的,我知道这是完全荒谬的,但我们的设计表明,所有的逻辑和数据处理将在构造函数完成后发生......因此,这里不应该有任何威胁,但我不知道这是否会以某种方式冲突FocusListener的回调方法。

谢谢。 :)

P.S.对于“重新输入新密码”字段,我确实承认JComponent JPasswordField,并且在解决此问题后将更改它。所以不需要安全警告:)

回答

2

tfield变量保存对的最后一个参考JTextField的实例。做你想要的东西的方式是这样的:

private FocusListener callback = new FocusListener() { 
    @Override public void focusGained(FocusEvent e){ 
     JTextField jtf = (JTextField) e.getSource(); 
     if(hasBeenSet){}else{jtf.setText("");hasBeenSet=true;} 
    } 
    ... 

注:如你的代码读取的那一刻,hasBeenSet将在所有3个文本字段共享。

更新:

Java有倒闭的支持,所以当focusGained运行时,它看到的tfield的最后一个值,在安装时listerner不是值tfield了。

它看起来像hasBeenSet被定义为外类的成员,因此focusGained正在检查所有3个文本框的相同变量。这是一种处理方式是什么,我认为你正在试图做的:

tfield = new JTextField("Insert CPR number", 8); 
tfield.putClientProperty("originalText", tfield.getText()); 

然后在focusGained:

@Override public void focusGained(FocusEvent e){ 
     JTextField jtf = (JTextField) e.getSource(); 
     if(jtf.getClientProperty("originalText").equals(jtf.getText())){ 
      jtf.setText(""); 
     } 
    } 

putClientProperty/getClientProperty方法在JComponent类中定义等等这些都是每个可用从JComponent继承的Swing GUI组件。他们根据字符串存储/检索Object。在这种情况下,字符串“originalText”持有原本用来初始化JTextField值。获得焦点后,如果该字段仍包含该值,则该字段将设置为空白。同样,你可以在那里focusLost如果该字段为空将其设置为“originalText”检索到的值进行类似的操作。

+0

虽然这并修复被设置只有最后文本框的问题,每次的回调现在只发生在文本框的一个(无论是第一次在网上的focusListener的增加本身。)还有,为什么它应该是一个问题该tfield指向JTextField的最后一个实例?我为它的每个实例添加一个新的focusListener。 – yackyackyack

相关问题