简体   繁体   English

Java-JFormattedTextField AddActionListener

[英]Java - JFormattedTextField AddActionListener

I've been learning a bit more related to Java GUIs. 我一直在学习与Java GUI相关的内容。 However, I've encountered an problem and am unsure of how to fix it. 但是,我遇到了一个问题,不确定如何解决。

I have a part of my program (displayed below, but irrelevant code has been removed), and everything aside from the JFormattedTextField variable (sliderField) works. 我的程序中有一部分(如下所示,但是不相关的代码已删除),除JFormattedTextField变量(sliderField)之外的所有东西都可以工作。 What I am trying to do is make it so if a value is typed into sliderField that is greater than 5000, and the panel refreshes (already done elsewhere), the field will change to 5000. However, for some reason, actionPerformed doesn't seem to register any sort of change in my JFormattedTextField, also preventing the variable from being changed. 我要尝试做的是,如果将一个值键入到大于5000的sliderField中,并且面板刷新(已经在其他地方完成),则该字段将更改为5000。但是,由于某些原因,actionPerformed不会似乎在我的JFormattedTextField中注册了任何形式的更改,也阻止了该变量被更改。

Here is my code: 这是我的代码:

public class testMenu extends JPanel implements ActionListener, ChangeListener {
    public testMenu(GUI p) {
        parent = p;
        setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
        createPanel();
        setVisible(true);
    }

    public void createPanel() {
        createOptions();
    }

    private void createOptions() {
        options[0] = new JPanel();
        add(options[0]);

        options[1] = new JPanel();
        add(options[1]);

        options[2] = new JPanel();
        add(options[2]);

        options[3] = new JPanel();
        add(options[3]);

        options[4] = new JPanel();
        add(options[4]);

        slider = new JSlider(0, 5000, 0);
        slider.setPaintTicks(true);
        slider.setValue(parent.variable);
        slider.addChangeListener(this);
        sliderField = new JFormattedTextField(NumberFormat.getInstance());
        sliderField.setText(Integer.toString(parent.variable));
        sliderField.setColumns(4);
        sliderField.addActionListener(this);

        options[5] = new JPanel();
        options[5].add(new JLabel("Slider Value:"));
        options[5].add(slider);
        options[5].add(sliderField);
        options[5].setVisible(false);

        add(options[5]);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == sliderField) {
            int size = Integer.parseInt(sliderField.getText());
            System.out.println(size);
            if (size > 5000) {
                sliderField.setText("5000");
                size = 5000;
            }
            parent.setVariable("" + size);
        }
    }

    private GUI parent;

    private JSlider slider;
    private JFormattedTextField sliderField;

    private JPanel[] options = new JPanel[5];
}

My question is simple: Why is actionPerformed not registering any sort of action being done on the JFormattedTextField, and how can I fix it? 我的问题很简单:为什么actionPerformed不注册在JFormattedTextField上进行的任何操作,我该如何解决?

Also, how would I set up my JFormattedTextField so if a value is put in that is greater than 999, no commas are added (preventing 1000 from displaying as 1,000)? 另外,我将如何设置JFormattedTextField,以便如果输入的值大于999,则不添加逗号(防止1000显示为1000)?

To get rid of the commas, just use a formatter that doesn't allow them. 要摆脱逗号,只需使用不允许使用的格式化程序即可。 eg, 例如,

  NumberFormat format = NumberFormat.getInstance();
  format.setGroupingUsed(true);  // *** set it so it doesn't use a grouping ***
  final JFormattedTextField formattedField = new JFormattedTextField(format);
  formattedField.setColumns(10);

As for your other problem, what if you get and set the value rather than the text? 至于其他问题,如果获取并设置值而不是文本怎么办?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;

import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class TestJFormattedText {
   public static void main(String[] args) {
      NumberFormat format = NumberFormat.getNumberInstance();
      format.setGroupingUsed(false);
      final JFormattedTextField formattedField = new JFormattedTextField(format);
      formattedField.setColumns(10);

      formattedField.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            long value = ((Long)formattedField.getValue()).longValue();
            if (value > 5000) {
               formattedField.setValue(5000);
            }
         }
      });


      JPanel panel = new JPanel();
      panel.add(formattedField);
      JFrame frame = new JFrame("Foo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(panel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
}

An advantage of using values is that you avoid the pesky NumberFormatExceptions if the text held by the JFormattedTextField are not appropriate, do not conform to the formatter. 使用值的优点是,如果JFormattedTextField所保存的文本不合适,不符合格式化程序,则可以避免讨厌的NumberFormatExceptions。


As an aside, your code posted in your question contains quite a bit of code unrelated to your problem, and does not compile or run for us. 顺便说一句,问题中发布的代码包含与问题无关的大量代码,并且不会为我们编译或运行。 In the future, consider posting only code that is required to both show the problem and to allow the code to run, kind of like what I posted above. 将来,考虑只显示既显示问题又允许代码运行所需的代码,类似于我上面发布的代码。


Edit 编辑
You ask in comment, 您在评论中问,

How can I make it so I do not need to hit 'Enter' for the actionEvent to execute? 如何做到这一点,这样我就不需要点击Enter即可执行actionEvent?

You can't as that's how ActionListeners work for JTextFields and for classes derived from JTextFields. 那样的话,ActionListeners不能用于JTextField和从JTextField派生的类。 I suppose you could add a DocumentFilter to the JFormattedTextField's Document if you want to fiddle with the field's contents before it is displayed in itself, but while I've used these with JTextFields, I've never used them with Documents used with JFormattedTextFields and cannot say that I know from experience that this will work. 我想如果可以在字段本身显示之前弄弄字段的内容则可以在JFormattedTextField的Document中添加一个DocumentFilter,但是尽管我将它们与JTextFields一起使用,但我从未将它们与用于JFormattedTextFields的Documents一起使用,并且不能说我从经验中知道这是行得通的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM