java限制窗口/ Jpanel的切换

时间:2016-01-11 16:39:33

标签: java swing focuslistener

JFrame有3 JPanel(基本上是三个标签)。其中一个面板有一个文本框。文本框有价值限制。这意味着,用户只能输入1-1000号码。如果他输入的数字> 1000,则会抛出警告消息。 现在我使用focuslistener一旦失去焦点就保存输入的数字。但是,如果用户输入1200并单击另一个选项卡(面板),它会给出我预期的警告消息,但也会转到另一个选项卡。如果有警告框,我需要保持在同一个面板中。我不想放松当前面板的焦点。

mMaxLabelLength = new JTextField();
mMaxLabelLength.addActionListener(this);

public void focusGained(FocusEvent fe)
{
    // do NOTHING
}

@Override
public void focusLost(FocusEvent fe)
{
    saveActions();
}

public void actionPerformed(ActionEvent e)
{
    //Do something
}

private void saveActions()
{
    // error message
    JOptionPane.showMessageDialog(this, 
        "Please enter an integer value between 1 and 1000.", 
        "Invalid Entry", JOptionPane.INFORMATION_MESSAGE);
    SwiftApplication APP = SwiftApplication.getInstance();
    int nMaxLabel = APP.getMaxPieLabel();
    mMaxLabelLength.setText(new Integer(nMaxLabel).toString());
    mMaxLabelLength.requestFocus();
}

2 个答案:

答案 0 :(得分:1)

看起来您正在寻找InputVerifier

  

抽象类,允许通过焦点机制进行输入验证。当尝试将焦点从包含输入验证器的组件移开时,在验证者满意之前不会放弃焦点。

正如oracle page描述的那样,它可以用来编写自己的验证器,它们拒绝无效的输入并同时将焦点保持在关联的 "karma": "0.13.19", 上。

因此,您只需做两件事:

  1. 编写您自己的JComponent,例如InputVerifier或者使用其中一个已存在的并创建它的实例。 (参见下面的小型完整可验证示例)
  2. 使用对Input Verification API的调用,在目标MyVerifier上注册您的验证者实例。
  3. 这意味着,要注册...

      

    JComponent调用InputVerifier类的setInputVerifier方法。例如,JComponent具有以下代码:

    InputVerificationDemo

    注意由于某种原因,我现在无法找到java8 InputVerifier的来源,似乎链接已损坏。

    小型可验证完整示例(来自here

    private MyVerifier verifier = new MyVerifier();
    ...
    amountField.setInputVerifier(verifier);
    

答案 1 :(得分:1)

问题中的代码块没有提供太多细节,但据我了解,您需要使用VetoableChangeListener来禁止焦点更改。

这是Java2s的一个例子:

import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class Main {
  public static void main(String[] argv) {
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addVetoableChangeListener(
        new FocusVetoableChangeListener());
  }
}

class FocusVetoableChangeListener implements VetoableChangeListener {
  public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
    Component oldComp = (Component) evt.getOldValue();
    Component newComp = (Component) evt.getNewValue();

    if ("focusOwner".equals(evt.getPropertyName())) {
      if (oldComp == null) {
        System.out.println(newComp.getName());
      } else {
        System.out.println(oldComp.getName());
      }
    } else if ("focusedWindow".equals(evt.getPropertyName())) {
      if (oldComp == null) {
        System.out.println(newComp.getName());
      } else {
        System.out.println(oldComp.getName());
      }
    }

    boolean vetoFocusChange = false;
    if (vetoFocusChange) {
      throw new PropertyVetoException("message", evt);
    }
  }
}

但是,我想的越多,可能使用InputVerifierpublic boolean shouldYieldFocus(JComponent input)更合适。请参阅Java教程的"How to Use the Focus Subsystem"中的“验证输入”。