~ubuntu-branches/ubuntu/utopic/figtree/utopic

« back to all changes in this revision

Viewing changes to src/figtree/ui/components/RealNumberField.java

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-02-21 08:17:38 UTC
  • Revision ID: james.westby@ubuntu.com-20110221081738-80pe2ulo8rg7up10
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * RealNumberField.java
 
3
 *
 
4
 * Copyright (c) 2009 JAM Development Team
 
5
 *
 
6
 * This package is distributed under the Lesser Gnu Public Licence (LGPL)
 
7
 *
 
8
 */
 
9
 
 
10
package figtree.ui.components;
 
11
 
 
12
import javax.swing.*;
 
13
import javax.swing.event.*;
 
14
import javax.swing.text.AttributeSet;
 
15
import javax.swing.text.BadLocationException;
 
16
import javax.swing.text.Document;
 
17
import javax.swing.text.PlainDocument;
 
18
import java.awt.*;
 
19
import java.awt.event.FocusEvent;
 
20
import java.awt.event.FocusListener;
 
21
 
 
22
 
 
23
public class RealNumberField extends JTextField
 
24
        implements FocusListener, DocumentListener {
 
25
 
 
26
    protected static char MINUS = '-';
 
27
    protected static char PERIOD = '.';
 
28
    protected EventListenerList changeListeners = new EventListenerList();
 
29
    protected double min;
 
30
    protected double max;
 
31
    protected boolean range_check = false;
 
32
    protected boolean range_checked = false;
 
33
 
 
34
    public RealNumberField() {
 
35
        super();
 
36
    }
 
37
 
 
38
    public RealNumberField(double min, double max) {
 
39
        this();
 
40
        this.min = min;
 
41
        this.max = max;
 
42
        range_check = true;
 
43
        this.addFocusListener(this);
 
44
    }
 
45
 
 
46
    public void focusGained(FocusEvent evt) {
 
47
    }
 
48
 
 
49
    public void focusLost(FocusEvent evt) {
 
50
        if (range_check && !range_checked) {
 
51
            range_checked = true;
 
52
            try {
 
53
                double value = (Double.valueOf(getText())).doubleValue();
 
54
                if (value < min || value > max) {
 
55
                    errorMsg();
 
56
                    return;
 
57
                }
 
58
            } catch (NumberFormatException e) {
 
59
                errorMsg();
 
60
                return;
 
61
            }
 
62
        }
 
63
    }
 
64
 
 
65
    public void setText(Double obj) {
 
66
        setText(obj.toString());
 
67
    }
 
68
 
 
69
    public void setText(Integer obj) {
 
70
        setText(obj.toString());
 
71
    }
 
72
 
 
73
    public void setText(Long obj) {
 
74
        setText(obj.toString());
 
75
    }
 
76
 
 
77
    protected void errorMsg() {
 
78
        JOptionPane.showMessageDialog(this,
 
79
                "Illegal entry\nValue must be between " + min + " and " +
 
80
                max + " inclusive", "Error", JOptionPane.ERROR_MESSAGE);
 
81
    }
 
82
 
 
83
    public void setRange(double min, double max) {
 
84
        this.min = min;
 
85
        this.max = max;
 
86
        range_check = true;
 
87
    }
 
88
 
 
89
    public void setValue(double value) {
 
90
        if (range_check) {
 
91
            if (value < min || value > max) {
 
92
                errorMsg();
 
93
                return;
 
94
            }
 
95
        }
 
96
        setText(Double.toString(value));
 
97
    }
 
98
 
 
99
    public Double getValue() {
 
100
        try {
 
101
            return new Double(getText());
 
102
        } catch (NumberFormatException e) {
 
103
            return null;
 
104
        }
 
105
    }
 
106
 
 
107
    public Double getValue(double def) {
 
108
        try {
 
109
            return new Double(getText());
 
110
        } catch (NumberFormatException e) {
 
111
            return new Double(def);
 
112
        }
 
113
    }
 
114
 
 
115
    protected Document createDefaultModel() {
 
116
        Document doc = new RealNumberFieldDocument();
 
117
        doc.addDocumentListener(this);
 
118
        return doc;
 
119
    }
 
120
 
 
121
    public void insertUpdate(DocumentEvent e) {
 
122
        range_checked = false;
 
123
        fireChanged();
 
124
    }
 
125
 
 
126
    public void removeUpdate(DocumentEvent e) {
 
127
        range_checked = false;
 
128
        fireChanged();
 
129
    }
 
130
 
 
131
    public void changedUpdate(DocumentEvent e) {
 
132
        range_checked = false;
 
133
        fireChanged();
 
134
    }
 
135
 
 
136
    static char[] numberSet = {
 
137
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
 
138
    };
 
139
 
 
140
    class RealNumberFieldDocument extends PlainDocument {
 
141
        public void insertString(int offs, String str, AttributeSet a)
 
142
                throws BadLocationException {
 
143
 
 
144
            if (str == null) return;
 
145
            str = str.trim();
 
146
 
 
147
            int length = getLength();
 
148
            String buf = getText(0, offs) + str + getText(offs, length - offs);
 
149
            buf = buf.trim().toUpperCase();
 
150
            char[] array = buf.toCharArray();
 
151
 
 
152
            if (array.length > 0) {
 
153
                if (array[0] != MINUS && !member(array[0], numberSet) &&
 
154
                        array[0] != PERIOD) {
 
155
                    Toolkit.getDefaultToolkit().beep();
 
156
                    return;
 
157
                }
 
158
            }
 
159
 
 
160
            boolean period_found = (array.length > 0 && array[0] == PERIOD);
 
161
            boolean exponent_found =  false;
 
162
            int exponent_index = -1;
 
163
            boolean exponent_sign_found =  false;
 
164
 
 
165
            for (int i = 1; i < array.length; i++) {
 
166
                if (!member(array[i], numberSet)) {
 
167
                    if (!period_found && array[i] == PERIOD) {
 
168
                        period_found = true;
 
169
                    } else if (!exponent_found && array[i] == 'E') {
 
170
                        exponent_found = true;
 
171
                        exponent_index = i;
 
172
                    } else if (exponent_found && i == (exponent_index + 1) && !exponent_sign_found && array[i] == '-') {
 
173
                        exponent_sign_found = true;
 
174
                    } else {
 
175
                        Toolkit.getDefaultToolkit().beep();
 
176
                        return;
 
177
                    }
 
178
                }
 
179
            }
 
180
            super.insertString(offs, str, a);
 
181
        }
 
182
    }
 
183
 
 
184
    static boolean member(char item, char[] array) {
 
185
        for (int i = 0; i < array.length; i++)
 
186
            if (array[i] == item) return true;
 
187
        return false;
 
188
    }
 
189
    //------------------------------------------------------------------------
 
190
    // Event Methods
 
191
    //------------------------------------------------------------------------
 
192
 
 
193
    public void addChangeListener(ChangeListener x) {
 
194
        changeListeners.add(ChangeListener.class, x);
 
195
    }
 
196
 
 
197
    public void removeChangeListener(ChangeListener x) {
 
198
        changeListeners.remove(ChangeListener.class, x);
 
199
    }
 
200
 
 
201
    protected void fireChanged() {
 
202
        ChangeEvent c = new ChangeEvent(this);
 
203
        Object[] listeners = changeListeners.getListenerList();
 
204
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
 
205
            if (listeners[i] == ChangeListener.class) {
 
206
                ChangeListener cl = (ChangeListener) listeners[i + 1];
 
207
                cl.stateChanged(c);
 
208
            }
 
209
        }
 
210
    }
 
211
}