有没有适用于Java Swing的好用且免费的日期时间选择器?

56

有没有适用于Java Swing的好用且免费的日期和时间选择器?

现在有很多日期选择器可供选择,但没有日期和时间选择器。目前我找到的最接近的是:寻找日期和时间选择器

有人知道吗?

5个回答

67

你可以使用JSpinner来实现时间选择器,并设置一个只显示时间值的JSpinner.DateEditor。

JSpinner timeSpinner = new JSpinner( new SpinnerDateModel() );
JSpinner.DateEditor timeEditor = new JSpinner.DateEditor(timeSpinner, "HH:mm:ss");
timeSpinner.setEditor(timeEditor);
timeSpinner.setValue(new Date()); // will only show the current time

1
哇,如此简单而且好!谢谢你,你真棒! - JavaNullPointer
您可能还想使用像JDatePicker这样的库来选择日期:http://jdatepicker.org。 - juanheyns
4
LGoodDatePicker 库包括一个很好的日期时间选择器组件(以及独立的 DatePicker 和 TimePicker 类)。这三个组件都很简单易用。以下是组件和演示应用程序的一些屏幕截图。屏幕截图1屏幕截图2。该项目主页位于 https://github.com/LGoodDatePicker/LGoodDatePicker。 - BlakeTNC
JSpinners 在我看来既难看又难以使用。如果您想要同时选择日期和时间,lbalazscs 的回答提供了一个更加视觉上吸引人的选择器。 - Agi Hammerthief

16
你可以扩展swingx JXDatePicker组件:
JXDatePicker只处理没有时间的日期。很多时候,我们需要让用户选择日期和时间。这是一个如何利用JXDatePicker处理日期和时间的示例。

http://wiki.java.net/twiki/bin/view/Javadesktop/JXDateTimePicker

编辑:这篇文章已经从网上消失了,但是SingleShot发现它仍然可以在互联网档案馆中找到。为了确保,这里是完整的工作示例:

import org.jdesktop.swingx.calendar.SingleDaySelectionModel;
import org.jdesktop.swingx.JXDatePicker;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.DateFormatter;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.*;
import java.awt.*;

/**
 * This is licensed under LGPL.  License can be found here:  http://www.gnu.org/licenses/lgpl-3.0.txt
 *
 * This is provided as is.  If you have questions please direct them to charlie.hubbard at gmail dot you know what.
 */
public class DateTimePicker extends JXDatePicker {
    private JSpinner timeSpinner;
    private JPanel timePanel;
    private DateFormat timeFormat;

    public DateTimePicker() {
        super();
        getMonthView().setSelectionModel(new SingleDaySelectionModel());
    }

    public DateTimePicker( Date d ) {
        this();
        setDate(d);
    }

    public void commitEdit() throws ParseException {
        commitTime();
        super.commitEdit();
    }

    public void cancelEdit() {
        super.cancelEdit();
        setTimeSpinners();
    }

    @Override
    public JPanel getLinkPanel() {
        super.getLinkPanel();
        if( timePanel == null ) {
            timePanel = createTimePanel();
        }
        setTimeSpinners();
        return timePanel;
    }

    private JPanel createTimePanel() {
        JPanel newPanel = new JPanel();
        newPanel.setLayout(new FlowLayout());
        //newPanel.add(panelOriginal);

        SpinnerDateModel dateModel = new SpinnerDateModel();
        timeSpinner = new JSpinner(dateModel);
        if( timeFormat == null ) timeFormat = DateFormat.getTimeInstance( DateFormat.SHORT );
        updateTextFieldFormat();
        newPanel.add(new JLabel( "Time:" ) );
        newPanel.add(timeSpinner);
        newPanel.setBackground(Color.WHITE);
        return newPanel;
    }

    private void updateTextFieldFormat() {
        if( timeSpinner == null ) return;
        JFormattedTextField tf = ((JSpinner.DefaultEditor) timeSpinner.getEditor()).getTextField();
        DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
        DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();
        // Change the date format to only show the hours
        formatter.setFormat( timeFormat );
    }

    private void commitTime() {
        Date date = getDate();
        if (date != null) {
            Date time = (Date) timeSpinner.getValue();
            GregorianCalendar timeCalendar = new GregorianCalendar();
            timeCalendar.setTime( time );

            GregorianCalendar calendar = new GregorianCalendar();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get( Calendar.HOUR_OF_DAY ) );
            calendar.set(Calendar.MINUTE, timeCalendar.get( Calendar.MINUTE ) );
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            Date newDate = calendar.getTime();
            setDate(newDate);
        }

    }

    private void setTimeSpinners() {
        Date date = getDate();
        if (date != null) {
            timeSpinner.setValue( date );
        }
    }

    public DateFormat getTimeFormat() {
        return timeFormat;
    }

    public void setTimeFormat(DateFormat timeFormat) {
        this.timeFormat = timeFormat;
        updateTextFieldFormat();
    }

    public static void main(String[] args) {
        Date date = new Date();
        JFrame frame = new JFrame();
        frame.setTitle("Date Time Picker");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DateTimePicker dateTimePicker = new DateTimePicker();
        dateTimePicker.setFormats( DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.MEDIUM ) );
        dateTimePicker.setTimeFormat( DateFormat.getTimeInstance( DateFormat.MEDIUM ) );

        dateTimePicker.setDate(date);

        frame.getContentPane().add(dateTimePicker);
        frame.pack();
        frame.setVisible(true);
    }
}

1
这个链接已经失效了,但是Wayback Machine这里有备份。 - SingleShot
我现在在这里包含了这个小宝石的完整代码 :) - lbalazscs
1
有没有单元格编辑器,可以将其放到表格单元格中? - whatswrong
如何在文本字段中显示时间部分? - Avatar Girase
我明白了,只需要设置DateTimePicker的格式即可: DateTimePicker dp = new DateTimePicker(); dp.setFormats("dd-MM-yyyy HH:mm:ss"); - Avatar Girase

9

使用两者的组合..这就是我所做的:

public static JPanel buildDatePanel(String label, Date value) {
JPanel datePanel = new JPanel();

JDateChooser dateChooser = new JDateChooser();
if (value != null) {
    dateChooser.setDate(value);
}
for (Component comp : dateChooser.getComponents()) {
    if (comp instanceof JTextField) {
    ((JTextField) comp).setColumns(50);
    ((JTextField) comp).setEditable(false);
    }
}

datePanel.add(dateChooser);

SpinnerModel model = new SpinnerDateModel();
JSpinner timeSpinner = new JSpinner(model);
JComponent editor = new JSpinner.DateEditor(timeSpinner, "HH:mm:ss");
timeSpinner.setEditor(editor);
if(value != null) {
    timeSpinner.setValue(value);
}

datePanel.add(timeSpinner);

return datePanel;
}

4

有一个名为FLib-JCalendar的组件,它结合了日期和时间选择器。


1

如你所说,日期选择器非常容易,市面上有很多选择。

至于时间选择器,可以参考谷歌日历在创建新条目时的做法。它允许您键入任何内容,同时以30分钟为间隔提供下拉列表。当您更改分钟数时,下拉列表也会相应更改。

如果需要允许用户选择秒数,则最好的办法是使用可键入/下拉列表组合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接