1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package net.sf.magicproject.ui;
20  
21  import java.awt.event.ActionEvent;
22  import java.awt.event.ActionListener;
23  import java.awt.event.KeyAdapter;
24  import java.awt.event.KeyEvent;
25  import java.awt.event.MouseEvent;
26  import java.awt.event.MouseListener;
27  
28  import javax.swing.JButton;
29  import javax.swing.JComponent;
30  import javax.swing.JList;
31  import javax.swing.JTextField;
32  import javax.swing.text.AttributeSet;
33  import javax.swing.text.BadLocationException;
34  import javax.swing.text.PlainDocument;
35  
36  import net.sf.magicproject.tools.MCardCompare;
37  
38  /***
39   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
40   * @since 0.2
41   */
42  public class HireListener extends PlainDocument implements ActionListener,
43  		MouseListener {
44  
45  	/***
46  	 * Creates a new instance of HireListener <br>
47  	 * 
48  	 * @param editor
49  	 *          the textField
50  	 * @param hireComponent
51  	 *          is component to enable/disable when an element is [de]selected
52  	 * @param toRefresh
53  	 * @param mappedList
54  	 *          the list to synchronize with the content of the textfield.
55  	 */
56  	public HireListener(final JTextField editor, JButton hireComponent,
57  			RefreshableAdd toRefresh, JList mappedList) {
58  		this.hireComponent = hireComponent;
59  		this.toRefresh = toRefresh;
60  		this.mappedList = mappedList;
61  		this.editor = editor;
62  		editor.addActionListener(this);
63  		editor.setDocument(this);
64  		editor.addMouseListener(this);
65  		hireComponent.addActionListener(this);
66  
67  		editor.addKeyListener(new KeyAdapter() {
68  			@Override
69  			public void keyPressed(KeyEvent e) {
70  				hitBackspace = false;
71  				
72  				
73  				switch (e.getKeyCode()) {
74  				case KeyEvent.VK_BACK_SPACE:
75  					hitBackspace = true;
76  					hitBackspaceOnSelection = editor.getSelectionStart() != editor
77  							.getSelectionEnd();
78  					break;
79  				
80  				case KeyEvent.VK_DELETE:
81  					e.consume();
82  					break;
83  				default:
84  					
85  				}
86  			}
87  		});
88  	}
89  
90  	public void actionPerformed(ActionEvent e) {
91  		toRefresh.refreshAddComponent(false);
92  	}
93  
94  	@Override
95  	public void remove(int offs, int len) throws BadLocationException {
96  		
97  		if (selecting)
98  			return;
99  		if (hitBackspace) {
100 			
101 			int workinOffs = offs;
102 			
103 			if (workinOffs > 0) {
104 				if (hitBackspaceOnSelection)
105 					workinOffs--;
106 			} else {
107 				
108 				
109 				
110 			}
111 			highlightCompletedText(workinOffs);
112 		} else {
113 			super.remove(offs, len);
114 		}
115 	}
116 
117 	@Override
118 	public void insertString(int offs, String str, AttributeSet a)
119 			throws BadLocationException {
120 		
121 		if (selecting)
122 			return;
123 		
124 		int workingOffs = offs;
125 		super.insertString(workingOffs, str, a);
126 		
127 		Object item = updateSelectedValue(getText(0, getLength()));
128 		if (item == null) {
129 			
130 			item = this.mappedList.getSelectedValue();
131 			workingOffs = workingOffs - str.length();
132 		}
133 		setText(item.toString());
134 		
135 		highlightCompletedText(workingOffs + str.length());
136 	}
137 
138 	private void setText(String text) {
139 		try {
140 			
141 			super.remove(0, getLength());
142 			super.insertString(0, text, null);
143 		} catch (BadLocationException e) {
144 			throw new RuntimeException(e.toString());
145 		}
146 	}
147 
148 	private void highlightCompletedText(int start) {
149 		editor.setCaretPosition(getLength());
150 		editor.moveCaretPosition(start);
151 	}
152 
153 	/***
154 	 * @param select
155 	 *          the text to find.
156 	 * @return the selected value.
157 	 */
158 	private Object updateSelectedValue(String pattern) {
159 
160 		
161 		if (pattern.length() == 0) {
162 			hireComponent.setEnabled(false);
163 		} else {
164 			try {
165 				final String selectedItem;
166 				if (mappedList.getSelectedValue() == null)
167 					selectedItem = null;
168 				else
169 					selectedItem = mappedList.getSelectedValue().toString().toLowerCase();
170 				String workingText = pattern.toLowerCase();
171 				String currentText = getText(0, getLength()).toLowerCase();
172 				
173 				
174 				if (selectedItem != null && selectedItem.startsWith(pattern)) {
175 					return mappedList.getSelectedValue();
176 				}
177 
178 				MListModel<MCardCompare> model = ((MListModel<MCardCompare>) mappedList
179 						.getModel());
180 				for (int index = 0, n = model.getSize(); index < n; index++) {
181 					String value = model.getElementAt(index).toString().toLowerCase();
182 					if (value.startsWith(workingText)) {
183 						mappedList.setSelectedIndex(index);
184 						mappedList.ensureIndexIsVisible(index);
185 						remove(0, currentText.length());
186 						super.insertString(0, model.get(index).getName(), null);
187 						editor.setCaretPosition(value.length());
188 						editor.moveCaretPosition(workingText.length());
189 						return model.getElementAt(index);
190 					}
191 				}
192 			} catch (BadLocationException e1) {
193 				
194 			}
195 		}
196 		return mappedList.getSelectedValue();
197 	}
198 
199 	public void mouseClicked(MouseEvent e) {
200 		if (e.getSource() == editor) {
201 			editor.selectAll();
202 		}
203 	}
204 
205 	public void mouseEntered(MouseEvent e) {
206 		
207 		return;
208 	}
209 
210 	public void mouseExited(MouseEvent e) {
211 		
212 		return;
213 	}
214 
215 	public void mousePressed(MouseEvent e) {
216 		
217 		return;
218 	}
219 
220 	public void mouseReleased(MouseEvent e) {
221 		
222 		return;
223 	}
224 
225 	/***
226 	 * Hire component used with this HireListener
227 	 */
228 	private JComponent hireComponent;
229 
230 	/***
231 	 * The component to refresh on active selection of an element of this list or
232 	 * on clic on the given JButton.
233 	 */
234 	private final RefreshableAdd toRefresh;
235 
236 	private final JList mappedList;
237 
238 	private final JTextField editor;
239 
240 	boolean hitBackspace = false;
241 
242 	boolean hitBackspaceOnSelection;
243 
244 	boolean selecting = false;
245 
246 }