Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / pickercontroller / DatePickerControllerImpl.java @ 2166

History | View | Annotate | Download (7.52 KB)

1
package org.gvsig.tools.swing.impl.pickercontroller;
2

    
3
import java.awt.Color;
4
import static java.awt.Component.RIGHT_ALIGNMENT;
5
import java.awt.event.ActionEvent;
6
import java.awt.event.ActionListener;
7
import java.net.URL;
8
import java.text.DateFormat;
9
import java.text.ParseException;
10
import java.text.SimpleDateFormat;
11
import java.util.Date;
12
import java.util.Locale;
13
import javax.swing.ImageIcon;
14
import javax.swing.JButton;
15
import javax.swing.JFormattedTextField;
16
import javax.swing.JPopupMenu;
17
import javax.swing.event.DocumentEvent;
18
import javax.swing.event.DocumentListener;
19
import javax.swing.text.Document;
20
import javax.swing.text.JTextComponent;
21
import javax.swing.text.MaskFormatter;
22
import org.apache.commons.lang3.StringUtils;
23
import org.freixas.jcalendar.DateEvent;
24
import org.freixas.jcalendar.JCalendar;
25
import org.gvsig.tools.dataTypes.DataTypes;
26
import org.gvsig.tools.swing.api.ToolsSwingLocator;
27
import org.gvsig.tools.swing.api.pickercontroller.AbstractPickerController;
28
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
29
import org.gvsig.tools.swing.icontheme.IconTheme;
30
import org.gvsig.tools.swing.icontheme.IconThemeManager;
31

    
32
/**
33
 *
34
 * @author jjdelcerro
35
 */
36
@SuppressWarnings("UseSpecificCatch")
37
public class DatePickerControllerImpl
38
        extends AbstractPickerController<Date>
39
        implements DatePickerController {
40

    
41
  private final JButton btnDate;
42
  private final JTextComponent txtDate;
43
  private JCalendar jcalendar;
44
  private DateFormat df;
45

    
46
  public static void selfRegister() {
47
    URL imageResource = DatePickerControllerImpl.class.getClassLoader().getResource("org/gvsig/tools/swing/picker/picker-date.png");
48
    if (imageResource != null) {
49
      IconThemeManager iconThemeManager = ToolsSwingLocator.getIconThemeManager();
50
      IconTheme theme = iconThemeManager.getCurrent();
51
      ImageIcon icon = new ImageIcon(imageResource);
52
      theme.registerDefault("tools", "picker", "picker-date", icon, imageResource);
53
    }
54
  }
55
  private final Document document;
56
  private final DocumentListener documentListener;
57
  private final Color colorOk;
58
  private final Color colorErr;
59
  private String emptyText;
60
  private MaskFormatter mask;
61
  private final ActionListener buttonListener;
62

    
63
  public DatePickerControllerImpl(JTextComponent txtDate, JButton btnDate) {
64
    this.txtDate = txtDate;
65
    if (btnDate == null) {
66
      btnDate = new JButton();
67
    }
68
    ToolsSwingLocator.getToolsSwingManager().addClearButton(txtDate, (ActionEvent e) -> {
69
      set(null);
70
    });
71
    this.df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
72
    this.df.setLenient(false);
73
    if (this.txtDate instanceof JFormattedTextField) {
74
      JFormattedTextField ftf = (JFormattedTextField) this.txtDate;
75
      if (df instanceof SimpleDateFormat) {
76
        try {
77
          SimpleDateFormat sdf = (SimpleDateFormat) this.df;
78
          String s = sdf.toPattern(); 
79
          if( !s.contains("yyyy") ) {
80
            if( s.contains("yy") ) {
81
              s = s.replace("yy", "yyyy");
82
            } else if( s.contains("y") ) {
83
              s = s.replace("y", "yyyy");
84
            }
85
          }
86
          if( !s.contains("dd") ) {
87
            if( s.contains("d") ) {
88
              s = s.replace("d", "dd");
89
            }
90
          }
91
          if( !s.contains("MM") ) {
92
            if( s.contains("M") ) {
93
              s = s.replace("M", "MM");
94
            }
95
          }
96
          sdf.applyPattern(s);
97
          s = s.replace("y", "#");
98
          s = s.replace("d", "#");
99
          s = s.replace("M", "#");
100
          this.mask = new MaskFormatter(s);
101
          mask.setPlaceholderCharacter('_');
102
          this.emptyText = s.replace("#","_");
103
          mask.setAllowsInvalid(false);
104
          mask.install(ftf);
105
        } catch (Exception ex) {
106
          LOG.warn("Not been able to create mask", ex);
107
        }
108
      }
109
    }
110
    this.colorOk = this.txtDate.getBackground();
111
    this.colorErr = new Color(255,225,232);
112
    this.btnDate = btnDate;
113
    this.txtDate.setAlignmentX(RIGHT_ALIGNMENT);
114
    this.txtDate.setEditable(true);
115
    this.document = this.txtDate.getDocument();
116
    this.documentListener = new DocumentListener() {
117
      @Override
118
      public void insertUpdate(DocumentEvent e) {
119
        checkContents();
120
      }
121

    
122
      @Override
123
      public void removeUpdate(DocumentEvent e) {
124
        checkContents();
125
      }
126

    
127
      @Override
128
      public void changedUpdate(DocumentEvent e) {
129
        checkContents();
130
      }
131
    };
132
    document.addDocumentListener(this.documentListener);
133

    
134
    this.btnDate.setIcon(this.getIcon("picker-date"));
135
    if (this.btnDate.getText().equals("...")) {
136
      this.btnDate.setText("");
137
    }
138

    
139
    this.buttonListener = (ActionEvent e) -> {
140
      doShowCalendar();
141
    };
142
    this.btnDate.addActionListener(this.buttonListener);
143
  }
144

    
145
  @Override
146
  public void uninstall() {
147
    this.document.removeDocumentListener(documentListener);
148
    if( this.mask!=null ) {
149
      this.mask.uninstall();
150
    }
151
    this.txtDate.setBackground(colorOk);
152
    this.btnDate.removeActionListener(buttonListener);    
153
  }
154
  
155
  protected String getText() {
156
    String s = this.txtDate.getText();
157
    if( this.emptyText!=null && this.emptyText.equals(s) ) {
158
      return "";
159
    }
160
    s = s.replace("_", "");
161
    return s;
162
  }
163

    
164
  protected void checkContents() {
165
    if( this.isValid() ) {
166
      this.txtDate.setBackground(colorOk);
167
    } else {
168
      this.txtDate.setBackground(colorErr);
169
    }
170
  }
171

    
172
  @Override
173
  public boolean isValid() {
174
    if (StringUtils.isBlank(this.getText())) {
175
      return true;
176
    }
177
    try {
178
      Date date = this.df.parse(this.getText());
179
      return true;
180
    } catch (ParseException ex) {
181
      return false;
182
    }
183
  }
184

    
185
  @Override
186
  public boolean isEmpty() {
187
    if (StringUtils.isBlank(this.getText())) {
188
      return true;
189
    }
190
    try {
191
      Date date = this.df.parse(this.getText());
192
      return false;
193
    } catch (ParseException ex) {
194
      return true;
195
    }
196
  }
197

    
198
  @Override
199
  public Date get() {
200
    if (StringUtils.isBlank(this.getText())) {
201
      return null;
202
    }
203
    try {
204
      Date date = this.df.parse(this.getText());
205
      return date;
206
    } catch (ParseException ex) {
207
      return null;
208
    }
209
  }
210

    
211
  @Override
212
  public void set(Date date) {
213
    if( date == null ) {
214
      this.txtDate.setText("");
215
      return;
216
    }
217
    this.txtDate.setText(this.df.format(date));
218
  }
219

    
220
  @Override
221
  public void setEnabled(boolean enabled) {
222
    this.btnDate.setEnabled(enabled);
223
    this.txtDate.setEnabled(enabled);
224
  }
225

    
226
  @Override
227
  public boolean isEnabled() {
228
    return this.btnDate.isEnabled();
229
  }
230

    
231
  private void doShowCalendar() {
232
    if (!this.isEditable()) {
233
      return;
234
    }
235
    JPopupMenu menu = new JPopupMenu();
236
    menu.add(getJCalendar());
237
    Date v = new Date();
238
    if( !isEmpty() ) {
239
      v = this.get();
240
    }
241
    if (v != null) {
242
      getJCalendar().setDate(v);
243
    }
244
    menu.show(this.txtDate, 0, this.txtDate.getY() + this.txtDate.getPreferredSize().height);
245
  }
246

    
247
  protected JCalendar getJCalendar() {
248
    if (this.jcalendar == null) {
249
      this.jcalendar = new JCalendar();
250
      this.jcalendar.addDateListener((DateEvent arg0) -> {
251
        set(getJCalendar().getDate());
252
        fireChangeEvent();
253
      });
254
    }
255
    return (JCalendar) this.jcalendar;
256
  }
257

    
258
  @Override
259
  public void coerceAndSet(Object value) {
260
    this.set((Date) this.coerce(DataTypes.DATE, value, new Date()));
261
  }
262

    
263
  @Override
264
  public DateFormat getDateFormat() {
265
    return this.df;
266
  }
267

    
268
  @Override
269
  public MaskFormatter  getMask() {
270
      return this.mask;
271
  }
272

    
273
  @Override
274
  public void setEmptyText(String emptyText) {
275
    this.emptyText = emptyText;
276
  }
277

    
278
}