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