首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >InputVerifier更改按钮背景

InputVerifier更改按钮背景
EN

Stack Overflow用户
提问于 2022-05-29 18:40:01
回答 1查看 78关注 0票数 1
  • 下面的代码只显示一个文本框和一个按钮。

  • 文本框有一个不接受空字段的inputVerifier。

  • 只要验证器的"false“结果由optionPane发出信号,按钮的背景就会在关闭optionPane后变为灰色,并在mouseOver上”按下“(并且只有当按钮被单击时,而不是在文本字段与选项卡键一起保留时)。

现在,删除该按钮的MouseListener的注释斜杠并再次运行该程序。您将看到,一旦关闭optionPane,该按钮将返回到其常规背景。

此解决方案在许多情况下都有效,但当涉及到SSCCE范围之外的实际程序时,它并不是不稳定的。在不稳定的情况下,我的意思是有时一切都按预期工作,有时尽管inputVerifier发出错误信号并返回"false",焦点从textField中释放出来,因此丢失的输入被接受。我想这是由于invokeLater在MouseListener。

为了演示这个问题,我可以将当前的实际代码减少到最低限度,但我恐怕最后会有几页代码。所以我首先想问,是否有人已经处理过这个问题,并能给出一个提示。谢谢,

代码语言:javascript
复制
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class ButtonBackground2 extends JFrame {

    public ButtonBackground2() {
        setSize(350, 200);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel p= new JPanel();
        JTextField tf = new JTextField();
        tf.setPreferredSize(new Dimension(100, 20));
        tf.setInputVerifier(new NonEmptyVerifier());
        p.add(tf);
        add(p, BorderLayout.CENTER);

        p= new JPanel();
        JButton btn = new JButton("Button");
        btn.setPreferredSize(new Dimension(80, 30));
//        btn.addMouseListener(new BtnBackgroundListener());
        p.add(btn);
        add(p, BorderLayout.SOUTH);
        setVisible(true);
    }
 
 
    public static void main(String arg[]) {
        EventQueue.invokeLater(ButtonBackground2::new);
    }
 
 
    class NonEmptyVerifier extends InputVerifier {
/*
        public boolean shouldYieldFocus(JComponent source, JComponent target) {
            return verify(source);
        }
*/
        public boolean verify(final JComponent input) {
            JTextField tf = (JTextField) input;
            if (tf.getText().trim().length()>0) {
                System.out.println("OK");
                return true;
            }
            JOptionPane.showMessageDialog(ButtonBackground2.this,
                        "Enter at least one character.",
                        "Missing input", JOptionPane.ERROR_MESSAGE);
            return false;
        }
    }


    class BtnBackgroundListener extends MouseAdapter {
        public void mousePressed(final MouseEvent e) {
            SwingUtilities.invokeLater(() -> {
                JButton btn= (JButton)e.getSource();
                if (!btn.hasFocus()) btn.getModel().setPressed(false);
            });
        }
    }
 
}

编辑

令人惊讶的是,我可以将我的实际代码减少到一小部分,以证明行为不当。

代码语言:javascript
复制
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import javax.swing.*;

public class Y extends JFrame {
  public static final long serialVersionUID = 100L;

  public Y() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(300, 240);
    setLocationRelativeTo(null);

    add(createTextFieldPanel(), BorderLayout.CENTER);
    JButton bOK= new JButton("OK");
    bOK.addActionListener(e -> System.out.println("OK, input accepted."));
/*  Adding the following listener makes in case of erroneous input the focus
    locking of the textfield's InputVerifier shaky. The InputVerifier itself,
    however, works alright, as one sees from the unfailingly displayed error
    message.
*/
    bOK.addMouseListener(new BtnBackgroundListener());
    add(bOK, BorderLayout.SOUTH);
    setVisible(true);
  }


  static public void main(String args[]) {
    EventQueue.invokeLater(Y::new);
  }


  private JPanel createTextFieldPanel() {
    JPanel p= new JPanel(new FlowLayout(FlowLayout.LEFT));
    p.add(new JLabel("Input:"));
    MyTextField tf= new MyTextField(this);
    tf.setPreferredSize(new Dimension(95, 20));
    tf.setFont(new Font("Monospaced", Font.PLAIN, 13));
    p.add(tf);
    return p;
  }
}

-----------------------------------------------------------


import java.awt.*;
import javax.swing.*;

public class MyTextField extends JTextField {
  public static final long serialVersionUID = 50161L;

  Component parent;

  public MyTextField(Component parent) {
    this.parent= parent;
    setInputVerifier(new InputVerifier() {
/*
      public boolean shouldYieldFocus(JComponent source, JComponent target) {
        return verify(source);
      }
*/
      public boolean verify(JComponent comp) {
        if (getText().equals("pass")) return true;
        JOptionPane.showMessageDialog(parent,
            "Input does not match the requested format.\n"+getText(),
            "Input error", JOptionPane.ERROR_MESSAGE);
        return false;
      }
    });
  }
}

首先,我们可以说Camickr对代码的长度/复杂性有任何影响是正确的。

其次,在这个演示中,删除MouseListener也会阻止焦点被不适当地释放。

那么,为什么程序ButtonBackground2只在某些时候起作用,而程序Y只在某些时候起作用呢?有时不正确的输入被接受在第一个按钮点击,有时一个人必须重复点击几次。

顺便说一下,我正在运行jdk 18,构建18+36-2087。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-01 14:23:53

该建议基于gthanop的建议,并结合了OP的方法,以便在验证失败时重置按钮模型状态:

代码语言:javascript
复制
import java.awt.GridLayout;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Main5 {

    private static class MyInputVerifier extends InputVerifier {

        private boolean validInput = false;
        private JButton button;

        public MyInputVerifier (JButton button)
        {
            this.button = button;
        }

        @Override
        public boolean verify(final JComponent input)
        {
            validInput = ((JTextField) input).getText().equals("pass");

            if (!validInput)
            {
                JOptionPane.showMessageDialog(input, "Verifier detected invalid input!");

                button.getModel().setPressed(false);
            }

            return validInput;
        }
    }

    private static void createAndShowGUI() {

        final JTextField field1 = new JTextField(12),
                         field2 = new JTextField("Anything");
        final JButton accept = new JButton("Submit");

        final MyInputVerifier miv = new MyInputVerifier(accept);
        field1.setInputVerifier(miv);

        accept.addActionListener(e -> {
            if (miv.validInput)
                System.out.println("Accepted!");
//            else
//                JOptionPane.showMessageDialog(accept, "Invalid input!");
        });

        final JPanel form = new JPanel(new GridLayout(0, 1));
        form.add(field1);
        form.add(field2);
        form.add(accept);
        
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(form);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(Main5::createAndShowGUI);
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72426364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档