2014-06-18 2 views
1

У меня есть такой простой код, который создает JFormattedTextField, который должен содержать дату рождения (только цифры, разделенные дефисом):JFormattedTextField с начальным значением, которое может быть перезаписана знак знаком

MaskFormatter mf = new MaskFormatter("##-##-####"); 
mf.setPlaceholderCharacter('_'); 
JFormattedTextField birthDate = new JFormattedTextField(mf); 

Но как создать birthDate в порядке он будет содержать начальное значение «dd-mm-yyyy».
Я знаю, что есть такая вещь, как setPlaceholder("some string"), но когда я ее использую, только способ изменить значение birthDate - это выбрать весь существующий контент, а затем ввести новый.
Мое намерение - разрешить пользователю перезаписывать существующий знак контента по знаку, и если после потери фокуса это значение не разрешено, вернитесь к первоначальному. Например.

1d-мм-гггг
11-мм-гггг
11-0m-гггг (теперь BirthDate теряет фокус)
дд-мм-гггг (потому что значение неверно BirthDate как на начала)

Возможно ли такое поведение JFormattedTextField? Или, может быть, для этого есть еще один подходящий JComponent?

+1

Возможно, для этого есть еще один подходящий JComponent? - JSpinner – mKorbel

+0

Или, может быть, для этого есть еще один подходящий JComponent? - [JCalendar by Kai Toedter] (http://toedter.com/jcalendar/) – mKorbel

+0

неплохой код, отличный форматтер, требуется/требуется адаптировать [NumberFormatter to Date] (http://stackoverflow.com/a/ 13424140/714968) by @Robin – mKorbel

ответ

2

не ответ только направление, чтобы использовать некоторые из JCalendar

простой пример кода для JSpinner (я не нашел Уведомитель для PropertyChangeListener/Support)

import java.awt.*; 
import java.text.SimpleDateFormat; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.event.*; 

public class TimeZoneSpinners { 

    private final String[] zones = {"Asia/Tokyo", "Asia/Hong_Kong", 
     "Asia/Calcutta", "Europe/Paris", "Europe/London", 
     "America/New_York", "America/Los_Angeles" 
    }; 
    private final JLabel[] labels = new JLabel[zones.length]; 
    private final SimpleDateFormat[] formats = new SimpleDateFormat[zones.length]; 
    private JSpinner spinner; 
    private SpinnerDateModel model; 
    private SimpleDateFormat format; 
    private JPanel panel; 
    private JFrame frame = new JFrame(); 

    public TimeZoneSpinners() { 
     Calendar cal = Calendar.getInstance(); 
     Date date = cal.getTime(); 
     model = new SpinnerDateModel(); 
     model.setValue(date); 
     spinner = new JSpinner(model); 
     spinner.addChangeListener(new ChangeListener() { 
      @Override 
      public void stateChanged(ChangeEvent e) { 
       Date date = (Date) ((JSpinner) e.getSource()).getValue(); 
       for (int i = 0; i < labels.length; i++) { 
        labels[i].setText(formats[i].format(date)); 
       } 
      } 
     }); 
     format = ((JSpinner.DateEditor) spinner.getEditor()).getFormat(); 
     format.setTimeZone(TimeZone.getTimeZone(zones[0])); 
     format.applyPattern("yyyy-MM-dd HH:mm:ss"); 
     format.applyPattern("HH:mm:ss"); 
     panel = new JPanel(new GridLayout(zones.length, 2, 10, 10)); 
     for (int i = 0; i < zones.length; i++) { 
      formats[i] = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss"); 
      formats[i] = new SimpleDateFormat("HH:mm:ss"); 
      formats[i].setTimeZone(TimeZone.getTimeZone(zones[i])); 
      JLabel label = new JLabel(zones[i]); 
      labels[i] = new JLabel(formats[i].format(date)); 
      labels[i].setHorizontalAlignment(JLabel.RIGHT); 
      panel.add(label); 
      panel.add(labels[i]); 
     } 
     frame.setLayout(new BorderLayout(10, 10)); 
     frame.add(spinner, BorderLayout.NORTH); 
     frame.add(panel, BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

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

вы должны быть в состоянии для переопределения AbstractFormatter/InternationalFormatter (example for number instance only) или для переопределения этих методов для JFormattedTextField/JSpinner и с входной мачтой и верификатором, например

import javax.swing.*; 
import javax.swing.text.DefaultFormatter; 
import javax.swing.text.InternationalFormatter; 
import java.text.DateFormat; 
import java.text.Format; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.TimeZone; 

public class DateSpinner extends JSpinner { 

    private static final long serialVersionUID = 1L; 
    public DefaultFormatter _formatter; 
    public DateEditor _timeEditor; 
    public DateFormat _format; 

    public DateSpinner() { 
     this("hh:mm:ss"); 
    } 

    public DateSpinner(String format) { 
     this(format, new Date()); 
    } 

    public DateSpinner(String format, Date date) { 
     super(new SpinnerDateModel(date, null, null, Calendar.HOUR_OF_DAY)); 
     setFormat(format); 
     customizeSpinner(); 
    } 

    private void customizeDateEditor() { 
     JFormattedTextField.AbstractFormatter formatter = _timeEditor.getTextField().getFormatter(); 
     if (formatter instanceof DefaultFormatter) { 
      _formatter = (DefaultFormatter) formatter; 
     } else { 
      throw new IllegalStateException("The formatter is not an instance of DefaultFormatter."); 
     } 
     if (formatter instanceof InternationalFormatter) { 
      Format f = ((InternationalFormatter) formatter).getFormat(); 
      if (f instanceof DateFormat) { 
       _format = ((DateFormat) f); 
      } 
     } 
     if (_format == null) { 
      throw new IllegalStateException("The format is not an instance of SimpleDateFormat."); 
     } 
    } 

    private void setFormat(String format) { 
     _timeEditor = createDateEditor(format); 
     customizeDateEditor(); 
     setEditor(_timeEditor); 
    } 

    private void customizeSpinner() { 
     setLenient(false); 
     setCommitsOnValidEdit(true); 
     setAllowsInvalid(false); 
     setOverwriteMode(true); 
    } 

    protected DateEditor createDateEditor(String format) { 
     return new DateEditor(this, format); 
    } 

    public void setCommitsOnValidEdit(boolean commit) { 
     _formatter.setCommitsOnValidEdit(commit); 
    } 

    public boolean getCommitsOnValidEdit() { 
     return _formatter.getCommitsOnValidEdit(); 
    } 

    public void setOverwriteMode(boolean overwriteMode) { 
     _formatter.setOverwriteMode(overwriteMode); 
    } 

    public boolean getOverwriteMode() { 
     return _formatter.getOverwriteMode(); 
    } 

    public void setAllowsInvalid(boolean allowsInvalid) { 
     _formatter.setAllowsInvalid(allowsInvalid); 
    } 

    public boolean getAllowsInvalid() { 
     return _formatter.getAllowsInvalid(); 
    } 

    public void setTimeZone(TimeZone zone) { 
     _format.setTimeZone(zone); 
    } 

    public TimeZone getTimeZone() { 
     return _format.getTimeZone(); 
    } 

    public void setLenient(boolean lenient) { 
     _format.setLenient(lenient); 
    } 

    public boolean isLenient() { 
     return _format.isLenient(); 
    } 
} 
+0

Дополнительный вопрос. Как получить то, что показывает DateSpinner? У меня есть DateSpinner date '18 -06-2014 ", но когда я использую getValue(), я получаю Wed Jun 18 12:41:45 CEST 2014. – rainbow

+0

Я понял это: _dateEditor.getTextField(). GetText() – rainbow

+0

у вас есть для того, чтобы нарисовать что-то вроде as/similair 'Date myDate = (Date) mySpinner/myFormattedTextField.getValue();' – mKorbel

Смежные вопросы