1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package coras.table;
22
23 import java.awt.Component;
24 import java.awt.Dimension;
25 import java.awt.Font;
26 import java.awt.Rectangle;
27 import java.awt.event.ComponentAdapter;
28 import java.awt.event.ComponentEvent;
29 import java.awt.event.KeyAdapter;
30 import java.awt.event.KeyEvent;
31 import java.util.Collection;
32
33 import javax.swing.AbstractCellEditor;
34 import javax.swing.Action;
35 import javax.swing.JTable;
36 import javax.swing.KeyStroke;
37 import javax.swing.event.DocumentEvent;
38 import javax.swing.event.DocumentListener;
39 import javax.swing.table.TableCellEditor;
40 import javax.swing.text.BadLocationException;
41 import javax.swing.text.JTextComponent;
42 import javax.swing.text.Keymap;
43
44 /***
45 * @author fvr
46 *
47 * To change the template for this generated type comment go to
48 * Window - Preferences - Java - Code Generation - Code and Comments
49 */
50 public class TextAreaEditor extends AbstractCellEditor implements TableCellEditor {
51
52 private ChoiceTextArea textArea = new ChoiceTextArea();
53 private Keymap keymap = null;
54 private Action prevAction = null;
55 private Action nextAction = null;
56 private Action upAction = null;
57 private Action downAction = null;
58 private CorasTable table = null;
59
60 public TextAreaEditor() {
61 super();
62 keymap = JTextComponent.addKeymap("TextAreaEditorKeymap", textArea.getKeymap());
63 textArea.setKeymap(keymap);
64 textArea.setLineWrap(true);
65 textArea.setWrapStyleWord(true);
66 textArea.setFont(new Font("SansSerif", Font.PLAIN, 12));
67
68 textArea.addKeyListener(new KeyAdapter() {
69 public void keyPressed(KeyEvent ev) {
70 int key = ev.getKeyCode();
71 if (key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN || key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
72 try {
73 int pos = textArea.getCaretPosition();
74 int lastPos = textArea.getText().length();
75 if (key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN) {
76 Rectangle rect = textArea.modelToView(pos);
77 int rowHeight = textArea.getRowHeight();
78 int row = rect.y / rowHeight;
79 int lastRow = (textArea.modelToView(lastPos).y / rowHeight);
80 if (key == KeyEvent.VK_UP && row == 0) {
81 fireUpAction();
82 } else if (key == KeyEvent.VK_DOWN && row == lastRow) {
83 fireDownAction();
84 }
85 } else {
86 if (key == KeyEvent.VK_LEFT && pos == 0) {
87 firePrevAction();
88 } else if (key == KeyEvent.VK_RIGHT && pos == lastPos) {
89 fireNextAction();
90 }
91 }
92 } catch (BadLocationException e) {
93 e.printStackTrace();
94 }
95 }
96 }
97 });
98
99 textArea.addComponentListener(new ComponentAdapter() {
100 public void componentResized(ComponentEvent e) {
101 CorasTable localTable = table;
102 if (localTable != null) {
103 localTable.updateRowHeight(localTable.getEditingRow());
104 }
105 }
106 public void componentMoved(ComponentEvent e) {
107 textArea.requestFocus();
108 }
109 });
110
111 textArea.getDocument().addDocumentListener(new DocumentListener() {
112 public void insertUpdate(DocumentEvent e) {
113 updateTableModel();
114 }
115 public void removeUpdate(DocumentEvent e) {
116 updateTableModel();
117 }
118 public void changedUpdate(DocumentEvent e) {
119 updateTableModel();
120 }
121 });
122 }
123
124
125 /***
126 *
127 */
128 protected synchronized void fireNextAction() {
129 if (nextAction != null)
130 nextAction.actionPerformed(null);
131 }
132
133 /***
134 *
135 */
136 protected synchronized void firePrevAction() {
137 if (prevAction != null)
138 prevAction.actionPerformed(null);
139 }
140
141 /***
142 *
143 */
144 protected synchronized void fireDownAction() {
145 if (downAction != null)
146 downAction.actionPerformed(null);
147 }
148
149 /***
150 *
151 */
152 protected synchronized void fireUpAction() {
153 if (upAction != null)
154 upAction.actionPerformed(null);
155 }
156
157 public synchronized void setNextAction(Action a) {
158 nextAction = a;
159 setKeyStrokeAction(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), a);
160 }
161
162 public synchronized void setPrevAction(Action a) {
163 prevAction = a;
164 setKeyStrokeAction(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_MASK), a);
165 }
166
167 public synchronized void setUpAction(Action a) {
168 upAction = a;
169 }
170
171 public synchronized void setDownAction(Action a) {
172 downAction = a;
173 }
174
175 private void setKeyStrokeAction(KeyStroke keyStroke, Action a) {
176 if (a != null)
177 keymap.addActionForKeyStroke(keyStroke, a);
178 else
179 keymap.removeKeyStrokeBinding(keyStroke);
180 }
181
182
183
184
185 public Component getTableCellEditorComponent(final JTable table, Object value,
186 boolean isSelected, final int row, final int column) {
187 if (table instanceof CorasTable) {
188 this.table = (CorasTable) table;
189 CorasTableModel tableModel = (CorasTableModel) table.getModel();
190 Collection choices = tableModel.getColumnChoices(column);
191
192 textArea.setChoices(choices);
193 textArea.setUserEditable(tableModel.isUserEditable(column));
194 } else {
195 this.table = null;
196 textArea.setChoices(null);
197 textArea.setUserEditable(true);
198 }
199 if (value instanceof String) {
200 textArea.setText((String) value);
201 } else {
202 textArea.setText(value != null ? value.toString() : "");
203 }
204 return textArea;
205 }
206
207
208
209
210 public Object getCellEditorValue() {
211 String result = textArea.getText();
212 return result;
213 }
214
215 public Dimension getPreferredSize() {
216 return textArea.getPreferredSize();
217 }
218
219 private void updateTableModel() {
220 int row = table.getEditingRow();
221 int col = table.getEditingColumn();
222 if (row == -1 || col == -1) {
223 return;
224 }
225 CorasTableModel tableModel = (CorasTableModel) table.getModel();
226 tableModel.setValueAt(getCellEditorValue(), row, col);
227 }
228 }