Hex8Spinner.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: package xeij;
22:
23: import java.awt.*;
24: import java.lang.*;
25: import java.util.*;
26: import javax.swing.*;
27: import javax.swing.border.*;
28: import javax.swing.event.*;
29: import javax.swing.text.*;
30:
31: public class Hex8Spinner extends JSpinner implements ChangeListener, DocumentListener {
32:
33: public Hex8SpinnerModel model;
34: public JTextField editor;
35:
36:
37: @SuppressWarnings ("this-escape") public Hex8Spinner (int newValue, int newMask, boolean newReverse) {
38: model = new Hex8SpinnerModel (newValue, newMask, newReverse);
39: editor = new JTextField (XEiJ.fmtHex8 (newValue & newMask), 8);
40: editor.setHorizontalAlignment (JTextField.RIGHT);
41:
42: AbstractDocument document = (AbstractDocument) editor.getDocument ();
43: document.setDocumentFilter (new Hex8DocumentFilter (newMask));
44: setBorder (new LineBorder (new Color (LnF.lnfRGB[10]), 1));
45: ComponentFactory.setFixedSize (this, 32 + (LnF.lnfFontSize * 2 / 3) * 8, LnF.lnfFontSize + 4);
46: setModel (model);
47: setEditor (editor);
48: model.addChangeListener (this);
49: document.addDocumentListener (this);
50: }
51:
52:
53:
54:
55:
56:
57:
58:
59: @Override public void stateChanged (ChangeEvent ce) {
60: try {
61: editor.setText (XEiJ.fmtHex8 (model.getIntValue ()));
62: } catch (IllegalStateException ise) {
63: }
64: }
65:
66:
67:
68:
69: @Override public void changedUpdate (DocumentEvent de) {
70: }
71: @Override public void insertUpdate (DocumentEvent de) {
72: model.setIntValue ((int) Long.parseLong (editor.getText (), 16));
73: }
74: @Override public void removeUpdate (DocumentEvent de) {
75: }
76:
77:
78: public int getIntValue () {
79: return model.getIntValue ();
80: }
81: public void setIntValue (int newValue) {
82: model.setIntValue (newValue);
83: }
84: public int getAbsoluteValue () {
85: return model.getAbsoluteValue ();
86: }
87: public void setAbsoluteValue (int newValue) {
88: model.setAbsoluteValue (newValue);
89: }
90:
91:
92: public void setHintArray (int[] array, int count) {
93: model.setHintArray (array, count);
94: }
95: public int getHintIndex () {
96: return model.getHintIndex ();
97: }
98: public void setHintIndex (int index) {
99: model.setHintIndex (index);
100: }
101:
102:
103: public void setOffset (int offset) {
104: model.setOffset (offset);
105: }
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116: public static class Hex8DocumentFilter extends DocumentFilter {
117: public int mask;
118: public char[] buffer;
119: public Hex8DocumentFilter (int newMask) {
120: mask = newMask;
121: buffer = new char[8];
122: }
123: @Override public void insertString (DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
124: replace (fb, offset, 0, string, attr);
125: }
126: @Override public void remove (DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
127: }
128: @Override public void replace (DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
129: length = text.length ();
130: int start = offset;
131: for (int i = 0; offset < 8 && i < length; i++) {
132: int x = Character.digit (text.charAt (i), 16);
133: if (x >= 0) {
134: buffer[offset] = XEiJ.fmtHexc (mask >>> (7 - offset) * 4 & x);
135: offset++;
136: }
137: }
138: fb.replace (start, offset - start, String.valueOf (buffer, start, offset - start), attrs);
139: }
140: }
141:
142:
143:
144:
145:
146:
147: public static class Hex8SpinnerModel extends AbstractSpinnerModel {
148:
149: public int value;
150: public int mask;
151: public boolean reverse;
152: public int[] hintArray;
153: public int hintCount;
154: public int hintIndex;
155: public int offset;
156:
157:
158: public Hex8SpinnerModel (int newValue, int newMask, boolean newReverse) {
159: value = newValue & newMask;
160: mask = newMask;
161: reverse = newReverse;
162: hintArray = new int[0];
163: hintCount = 0;
164: hintIndex = -1;
165: offset = 0;
166: }
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187: @Override public Object getNextValue () {
188: if (reverse) {
189: return (hintCount < 0 || hintIndex < 0 ? (value & mask) - 1 & mask :
190: hintIndex == 0 ? value :
191: hintArray[hintIndex - 1] - offset);
192: } else {
193: return (hintCount < 0 || hintIndex < 0 ? (value | ~mask) + 1 & mask :
194: hintIndex == hintCount - 1 ? value :
195: hintArray[hintIndex + 1] - offset);
196: }
197: }
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217: @Override public Object getPreviousValue () {
218: if (reverse) {
219: return (hintCount < 0 || hintIndex < 0 ? (value | ~mask) + 1 & mask :
220: hintIndex == hintCount - 1 ? value :
221: hintArray[hintIndex + 1] - offset);
222: } else {
223: return (hintCount < 0 || hintIndex < 0 ? (value & mask) - 1 & mask :
224: hintIndex == 0 ? value :
225: hintArray[hintIndex - 1] - offset);
226: }
227: }
228:
229:
230: @Override public Object getValue () {
231: return XEiJ.fmtHex8 (getIntValue ());
232: }
233:
234:
235: @Override public void setValue (Object newValue) {
236: setIntValue (newValue instanceof Integer ? ((Integer) newValue).intValue () :
237: newValue instanceof String ? (int) Long.parseLong ((String) newValue, 16) : 0);
238: }
239:
240:
241:
242: public int getIntValue () {
243: return value;
244: }
245:
246:
247:
248:
249:
250: public void setIntValue (int newValue) {
251: newValue &= mask;
252: if (value != newValue) {
253: value = newValue;
254: hintIndex = Arrays.binarySearch (hintArray, 0, hintCount, value + offset);
255: fireStateChanged ();
256: }
257: }
258:
259:
260: public int getAbsoluteValue () {
261: return getIntValue () + offset;
262: }
263:
264:
265: public void setAbsoluteValue (int newValue) {
266: setIntValue (newValue - offset);
267: }
268:
269:
270:
271:
272:
273:
274:
275: public void setHintArray (int[] array, int count) {
276: if (hintArray == null || hintArray.length < count) {
277: hintArray = new int[count];
278: }
279: System.arraycopy (array, 0, hintArray, 0, count);
280: hintCount = count;
281: hintIndex = Arrays.binarySearch (hintArray, 0, hintCount, value + offset);
282: }
283:
284:
285:
286: public int getHintIndex () {
287: return hintIndex;
288: }
289:
290:
291: public void setHintIndex (int index) {
292: if (0 <= index && index < hintCount &&
293: hintIndex != index) {
294: hintIndex = index;
295: int newValue = hintArray[index] - offset;
296: if (value != newValue) {
297: value = newValue;
298: fireStateChanged ();
299: }
300: }
301: }
302:
303:
304:
305:
306:
307: public void setOffset (int newOffset) {
308: newOffset &= mask;
309: if (offset != newOffset) {
310: value += offset - newOffset;
311: offset = newOffset;
312: fireStateChanged ();
313: }
314: }
315:
316: }
317:
318:
319:
320: }
321:
322:
323: