java JFormattedTextField :输入持续时间值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2234726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 20:12:24  来源:igfitidea点击:

JFormattedTextField : input time duration value

javatimejtextfielddurationjformattedtextfield

提问by bguiz

I want to use a JFormattedTextFieldto allow the user to input time durationvalues into a form. Sample valid values are:

我想使用 aJFormattedTextField来允许用户将持续时间值输入到表单中。示例有效值为:

2h 30m
72h 15m
6h
0h

2h 30m
72h 15m
6h
0h

However I am having limited success with this. Can some one please suggest how this can be accomplished? I am OK if this result can be achieved using a JTextFieldas well.

但是,我在这方面取得的成功有限。有人可以建议如何做到这一点吗?如果使用 a 也可以实现此结果,我就可以了JTextField

Thanks!

谢谢!



If it is worth anything, here's my current attempt:

如果值得的话,这是我目前的尝试:

 mFormattedText.setFormatterFactory(
    new DefaultFormatterFactory(
        new DateFormatter(
            new SimpleDateFormat("H mm"))));

This sorta works except that:

这种工作方式除了:

  • I cannot get hand mto appear as plain text (I tried escaping)*
  • The number of hours has a max
  • 我无法获取hm显示为纯文本(我尝试转义)*
  • 小时数有最大值

*: See @nanda's answer

*:见@nanda 的回答

采纳答案by nanda

The code:

代码:

public static void main(String[] args) {
    JFrame jFrame = new JFrame();
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jFrame.setLayout(new BorderLayout());
    jFrame.setPreferredSize(new Dimension(500, 500));

    final JFormattedTextField comp = new JFormattedTextField();
    comp.setFormatterFactory(new DefaultFormatterFactory(new DateFormatter(new SimpleDateFormat(
            "H'h' mm'm'"))));
    comp.setValue(Calendar.getInstance().getTime());

    comp.addPropertyChangeListener("value", new PropertyChangeListener() {

        @Override public void propertyChange(PropertyChangeEvent evt) {
            System.out.println(comp.getValue());

        }
    });

    jFrame.getContentPane().add(comp, BorderLayout.CENTER);

    jFrame.pack();
    jFrame.setVisible(true);
}

回答by trashgod

Here's an example of using InputVerifierto accommodate multiple input formats.

这是一个InputVerifier用于适应多种输入格式的示例。

import java.awt.EventQueue;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.Box;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;

public class FormattedFields {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            //@Override
            public void run() {
                new FormattedFields();
            }
        });
    }

    FormattedFields() {
        Box form = Box.createVerticalBox();

        form.add(new JLabel("Date & Time:"));
        DateTimeField dtField = new DateTimeField(new Date());
        form.add(dtField);

        form.add(new JLabel("Amount:"));
        JFormattedTextField amtField = new JFormattedTextField(
            NumberFormat.getCurrencyInstance());
        amtField.setValue(100000);
        form.add(amtField);

        JFrame frame = new JFrame();
        frame.add(form);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

class DateTimeField extends JFormattedTextField {

    public DateTimeField() {
        super(DateTimeVerifier.getDefaultFormat());
        this.setInputVerifier(new DateTimeVerifier(this));
    }

    public DateTimeField(Date date) {
        this();
        this.setValue(date);
    }

    @Override
    protected void invalidEdit() {
        if (!this.getInputVerifier().verify(this)) {
            super.invalidEdit();
        }
    }
}

class DateTimeVerifier extends InputVerifier {

    private static List<SimpleDateFormat> validForms =
        new ArrayList<SimpleDateFormat>();


    static {
        validForms.add(new SimpleDateFormat("dd-MMM-yyyy HH'h':mm'm'"));
        validForms.add(new SimpleDateFormat("dd-MMM-yyyy HH:mm"));
    }
    private JFormattedTextField tf;
    private Date date;

    public DateTimeVerifier(JFormattedTextField tf) {
        this.tf = tf;
    }

    @Override
    public boolean verify(JComponent input) {
        boolean result = false;
        if (input == tf) {
            String text = tf.getText();
            for (SimpleDateFormat format : validForms) {
                try {
                    date = format.parse(text);
                    result |= true;
                } catch (ParseException pe) {
                    result |= false;
                }
            }
        }
        return result;
    }

    @Override
    public boolean shouldYieldFocus(JComponent input) {
        if (verify(input)) {
            tf.setValue(date);
            return true;
        } else {
            return false;
        }
    }

    public static SimpleDateFormat getDefaultFormat() {
        return validForms.get(0);
    }
}

回答by nanda

Have you tried H'h' mm'm'?

你试过H'h' mm'm'吗?

回答by Basil Bourque

tl;dr

tl;博士

Duration.parse( "PT2H30M" )

ISO 8601

ISO 8601

If you are willing to redefine your desired input formats, I suggest using the already-existing formats defined by the ISO 8601standard.

如果您愿意重新定义所需的输入格式,我建议使用ISO 8601标准定义的现有格式。

The pattern PnYnMnDTnHnMnSuses a Pto mark the beginning, a Tto separate any years-months-days portion from any hours-minutes-seconds portion.

该模式PnYnMnDTnHnMnS使用 aP来标记开始,使用 aT将任何年-月-日部分与任何时-分-秒部分分开。

An hour-and-a-half is PT1H30M, for example.

PT1H30M例如,一个半小时。

java.time

时间

The java.time classes use the ISO 8601 formats by default when parsing/generating strings. This includes the Periodand Durationclasses for representing spans of time not attached to the timeline.

java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。这包括用于表示未附加到时间线的时间跨度的PeriodDuration类。

Duration d = Duration.ofHours( 1 ).plusMinutes( 30 );
String output = d.toString();

Going the other direction, parsing a string.

走向另一个方向,解析一个字符串。

Duration d = Duration.parse( "PT1H30M" );

See live code in IdeOne.com.

在 IdeOne.com 中查看实时代码

See my similar Answerto a similar Question.

请参阅类似问题的类似回答



About java.time

关于 java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多

回答by ultrajohn

hmm, what i think is that you can achieve the same goal by, creating three different JTextField for all the three time components, one for the HOUR, MINUTE and Second (if it's included) to get your input... just a thought, you could just concatenate them if you it's necessary... just a thought...

嗯,我认为您可以通过为所有三个时间组件创建三个不同的 JTextField 来实现相同的目标,一个用于 HOUR、MINUTE 和 Second(如果包含)以获取您的输入......只是一个想法,如果有必要,你可以将它们连接起来......只是一个想法......