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 @ 2165

History | View | Annotate | Download (7 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.net.URL;
7
import java.text.DateFormat;
8
import java.text.ParseException;
9
import java.text.SimpleDateFormat;
10
import java.util.Date;
11
import java.util.Locale;
12
import javax.swing.ImageIcon;
13
import javax.swing.JButton;
14
import javax.swing.JFormattedTextField;
15
import javax.swing.JPopupMenu;
16
import javax.swing.event.DocumentEvent;
17
import javax.swing.event.DocumentListener;
18
import javax.swing.text.Document;
19
import javax.swing.text.JTextComponent;
20
import javax.swing.text.MaskFormatter;
21
import org.apache.commons.lang3.StringUtils;
22
import org.freixas.jcalendar.DateEvent;
23
import org.freixas.jcalendar.JCalendar;
24
import org.gvsig.tools.dataTypes.DataTypes;
25
import org.gvsig.tools.swing.api.ToolsSwingLocator;
26
import org.gvsig.tools.swing.api.pickercontroller.AbstractPickerController;
27
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
28
import org.gvsig.tools.swing.icontheme.IconTheme;
29
import org.gvsig.tools.swing.icontheme.IconThemeManager;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

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

    
42
  private final JButton btnDate;
43
  private final JTextComponent txtDate;
44
  private JCalendar jcalendar;
45
  private DateFormat df;
46
  private static final Logger LOG = LoggerFactory.getLogger(DatePickerControllerImpl.class);
47

    
48
  public static void selfRegister() {
49
    URL imageResource = DatePickerControllerImpl.class.getClassLoader().getResource("org/gvsig/tools/swing/picker/picker-date.png");
50
    if (imageResource != null) {
51
      IconThemeManager iconThemeManager = ToolsSwingLocator.getIconThemeManager();
52
      IconTheme theme = iconThemeManager.getCurrent();
53
      ImageIcon icon = new ImageIcon(imageResource);
54
      theme.registerDefault("tools", "picker", "picker-date", icon, imageResource);
55
    }
56
  }
57
  private final Document document;
58
  private final DocumentListener documentListener;
59
  private final Color colorOk;
60
  private final Color colorErr;
61
  private String emptyValue;
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
          MaskFormatter mask = new MaskFormatter(s);
101
          mask.setPlaceholderCharacter('_');
102
          this.emptyValue = 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.btnDate.addActionListener((ActionEvent e) -> {
140
      doShowCalendar();
141
    });
142
  }
143

    
144
  @Override
145
  public void uninstall() {
146

    
147
  }
148
  
149
  private String getText() {
150
    String s = this.txtDate.getText();
151
    if( this.emptyValue!=null && this.emptyValue.equals(s) ) {
152
      return "";
153
    }
154
    s = s.replace("_", "");
155
    return s;
156
  }
157

    
158
  private void checkContents() {
159
    if( this.isValid() ) {
160
      this.txtDate.setBackground(colorOk);
161
    } else {
162
      this.txtDate.setBackground(colorErr);
163
    }
164
  }
165

    
166
  @Override
167
  public boolean isValid() {
168
    if (StringUtils.isBlank(this.getText())) {
169
      return true;
170
    }
171
    try {
172
      Date date = this.df.parse(this.getText());
173
      return true;
174
    } catch (ParseException ex) {
175
      return false;
176
    }
177
  }
178

    
179
  @Override
180
  public boolean isEmpty() {
181
    if (StringUtils.isBlank(this.getText())) {
182
      return true;
183
    }
184
    try {
185
      Date date = this.df.parse(this.getText());
186
      return false;
187
    } catch (ParseException ex) {
188
      return true;
189
    }
190
  }
191

    
192
  @Override
193
  public Date get() {
194
    if (StringUtils.isBlank(this.getText())) {
195
      return null;
196
    }
197
    try {
198
      Date date = this.df.parse(this.getText());
199
      return date;
200
    } catch (ParseException ex) {
201
      return null;
202
    }
203
  }
204

    
205
  @Override
206
  public void set(Date date) {
207
    if( date == null ) {
208
      this.txtDate.setText("");
209
      return;
210
    }
211
    this.txtDate.setText(this.df.format(date));
212
  }
213

    
214
  @Override
215
  public void setEnabled(boolean enabled) {
216
    this.btnDate.setEnabled(enabled);
217
    this.txtDate.setEnabled(enabled);
218
  }
219

    
220
  @Override
221
  public boolean isEnabled() {
222
    return this.btnDate.isEnabled();
223
  }
224

    
225
  private void doShowCalendar() {
226
    if (!this.isEditable()) {
227
      return;
228
    }
229
    JPopupMenu menu = new JPopupMenu();
230
    menu.add(getJCalendar());
231
    Date v = this.get();
232
    if (v != null) {
233
      getJCalendar().setDate(v);
234
    }
235
    menu.show(this.txtDate, 0, this.txtDate.getY() + this.txtDate.getPreferredSize().height);
236
  }
237

    
238
  protected JCalendar getJCalendar() {
239
    if (this.jcalendar == null) {
240
      this.jcalendar = new JCalendar();
241
      this.jcalendar.addDateListener((DateEvent arg0) -> {
242
        set(getJCalendar().getDate());
243
        fireChangeEvent();
244
      });
245
    }
246
    return (JCalendar) this.jcalendar;
247
  }
248

    
249
  @Override
250
  public void coerceAndSet(Object value) {
251
    this.set((Date) this.coerce(DataTypes.DATE, value, new Date()));
252
  }
253

    
254
}