46 |
import java.awt.Point; |
import java.awt.Point; |
47 |
import java.awt.Rectangle; |
import java.awt.Rectangle; |
48 |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionEvent; |
49 |
|
import java.awt.event.ActionListener; |
50 |
import java.awt.event.FocusEvent; |
import java.awt.event.FocusEvent; |
51 |
import java.awt.event.FocusListener; |
import java.awt.event.FocusListener; |
52 |
import java.awt.event.InputEvent; |
import java.awt.event.InputEvent; |
55 |
import java.awt.event.MouseEvent; |
import java.awt.event.MouseEvent; |
56 |
|
|
57 |
import javax.swing.AbstractAction; |
import javax.swing.AbstractAction; |
58 |
|
import javax.swing.ActionMap; |
59 |
import javax.swing.BorderFactory; |
import javax.swing.BorderFactory; |
60 |
import javax.swing.CellRendererPane; |
import javax.swing.CellRendererPane; |
61 |
import javax.swing.InputMap; |
import javax.swing.InputMap; |
70 |
import javax.swing.event.ChangeEvent; |
import javax.swing.event.ChangeEvent; |
71 |
import javax.swing.event.MouseInputListener; |
import javax.swing.event.MouseInputListener; |
72 |
import javax.swing.plaf.ComponentUI; |
import javax.swing.plaf.ComponentUI; |
73 |
|
import javax.swing.plaf.InputMapUIResource; |
74 |
import javax.swing.plaf.TableUI; |
import javax.swing.plaf.TableUI; |
75 |
import javax.swing.table.TableCellRenderer; |
import javax.swing.table.TableCellRenderer; |
76 |
import javax.swing.table.TableColumn; |
import javax.swing.table.TableColumn; |
206 |
return new MouseInputHandler(); |
return new MouseInputHandler(); |
207 |
} |
} |
208 |
|
|
209 |
|
/** |
210 |
|
* Return the maximum size of the table. The maximum height is the row |
211 |
|
* height times the number of rows. The maximum width is the sum of |
212 |
|
* the maximum widths of each column. |
213 |
|
* |
214 |
|
* @param comp the component whose maximum size is being queried, |
215 |
|
* this is ignored. |
216 |
|
* @return a Dimension object representing the maximum size of the table, |
217 |
|
* or null if the table has no elements. |
218 |
|
*/ |
219 |
public Dimension getMaximumSize(JComponent comp) |
public Dimension getMaximumSize(JComponent comp) |
220 |
{ |
{ |
221 |
return getPreferredSize(comp); |
int maxTotalColumnWidth = 0; |
222 |
|
for (int i = 0; i < table.getColumnCount(); i++) |
223 |
|
maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth(); |
224 |
|
if (maxTotalColumnWidth == 0 || table.getRowCount() == 0) |
225 |
|
return null; |
226 |
|
return new Dimension(maxTotalColumnWidth, table.getRowCount()*table.getRowHeight()); |
227 |
} |
} |
228 |
|
|
229 |
|
/** |
230 |
|
* Return the minimum size of the table. The minimum height is the row |
231 |
|
* height times the number of rows. The minimum width is the sum of |
232 |
|
* the minimum widths of each column. |
233 |
|
* |
234 |
|
* @param comp the component whose minimum size is being queried, |
235 |
|
* this is ignored. |
236 |
|
* @return a Dimension object representing the minimum size of the table, |
237 |
|
* or null if the table has no elements. |
238 |
|
*/ |
239 |
public Dimension getMinimumSize(JComponent comp) |
public Dimension getMinimumSize(JComponent comp) |
240 |
{ |
{ |
241 |
return getPreferredSize(comp); |
int minTotalColumnWidth = 0; |
242 |
|
for (int i = 0; i < table.getColumnCount(); i++) |
243 |
|
minTotalColumnWidth += table.getColumnModel().getColumn(i).getMinWidth(); |
244 |
|
if (minTotalColumnWidth == 0 || table.getRowCount() == 0) |
245 |
|
return null; |
246 |
|
return new Dimension(minTotalColumnWidth, table.getRowCount()*table.getRowHeight()); |
247 |
} |
} |
248 |
|
|
249 |
public Dimension getPreferredSize(JComponent comp) |
public Dimension getPreferredSize(JComponent comp) |
302 |
{ |
{ |
303 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
304 |
InputMap ancestorMap = (InputMap)defaults.get("Table.ancestorInputMap"); |
InputMap ancestorMap = (InputMap)defaults.get("Table.ancestorInputMap"); |
305 |
|
InputMapUIResource parentInputMap = new InputMapUIResource(); |
306 |
|
// FIXME: The JDK uses a LazyActionMap for parentActionMap |
307 |
|
ActionMap parentActionMap = new ActionMap(); |
308 |
action = new TableAction(); |
action = new TableAction(); |
309 |
Object keys[] = ancestorMap.allKeys(); |
Object keys[] = ancestorMap.allKeys(); |
310 |
// Register the key bindings with the JTable. |
// Register key bindings in the UI InputMap-ActionMap pair |
311 |
// Note that we register key bindings with both the old and new modifier |
// Note that we register key bindings with both the old and new modifier |
312 |
// masks: InputEvent.SHIFT_MASK and InputEvent.SHIFT_DOWN_MASK and so on. |
// masks: InputEvent.SHIFT_MASK and InputEvent.SHIFT_DOWN_MASK and so on. |
313 |
for (int i = 0; i < keys.length; i++) |
for (int i = 0; i < keys.length; i++) |
314 |
{ |
{ |
315 |
table.registerKeyboardAction(action,(String)ancestorMap.get((KeyStroke)keys[i]), |
parentInputMap.put(KeyStroke.getKeyStroke |
316 |
KeyStroke.getKeyStroke |
(((KeyStroke)keys[i]).getKeyCode(), convertModifiers |
317 |
(((KeyStroke)keys[i]).getKeyCode(), convertModifiers(((KeyStroke)keys[i]).getModifiers())), |
(((KeyStroke)keys[i]).getModifiers())), |
318 |
JComponent.WHEN_FOCUSED); |
(String)ancestorMap.get((KeyStroke)keys[i])); |
319 |
|
|
320 |
table.registerKeyboardAction(action,(String)ancestorMap.get((KeyStroke)keys[i]), |
parentInputMap.put(KeyStroke.getKeyStroke |
321 |
KeyStroke.getKeyStroke |
(((KeyStroke)keys[i]).getKeyCode(), |
322 |
(((KeyStroke)keys[i]).getKeyCode(), ((KeyStroke)keys[i]).getModifiers()), |
((KeyStroke)keys[i]).getModifiers()), |
323 |
JComponent.WHEN_FOCUSED); |
(String)ancestorMap.get((KeyStroke)keys[i])); |
324 |
|
|
325 |
|
parentActionMap.put |
326 |
|
((String)ancestorMap.get((KeyStroke)keys[i]), new ActionListenerProxy |
327 |
|
(action, (String)ancestorMap.get((KeyStroke)keys[i]))); |
328 |
|
|
329 |
} |
} |
330 |
|
// Set the UI InputMap-ActionMap pair to be the parents of the |
331 |
|
// JTable's InputMap-ActionMap pair |
332 |
|
parentInputMap.setParent |
333 |
|
(table.getInputMap |
334 |
|
(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent()); |
335 |
|
parentActionMap.setParent(table.getActionMap().getParent()); |
336 |
|
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). |
337 |
|
setParent(parentInputMap); |
338 |
|
table.getActionMap().setParent(parentActionMap); |
339 |
|
} |
340 |
|
|
341 |
|
/** |
342 |
|
* This class is used to mimmic the behaviour of the JDK when registering |
343 |
|
* keyboard actions. It is the same as the private class used in JComponent |
344 |
|
* for the same reason. This class receives an action event and dispatches |
345 |
|
* it to the true receiver after altering the actionCommand property of the |
346 |
|
* event. |
347 |
|
*/ |
348 |
|
private static class ActionListenerProxy |
349 |
|
extends AbstractAction |
350 |
|
{ |
351 |
|
ActionListener target; |
352 |
|
String bindingCommandName; |
353 |
|
|
354 |
|
public ActionListenerProxy(ActionListener li, |
355 |
|
String cmd) |
356 |
|
{ |
357 |
|
target = li; |
358 |
|
bindingCommandName = cmd; |
359 |
|
} |
360 |
|
|
361 |
|
public void actionPerformed(ActionEvent e) |
362 |
|
{ |
363 |
|
ActionEvent derivedEvent = new ActionEvent(e.getSource(), |
364 |
|
e.getID(), |
365 |
|
bindingCommandName, |
366 |
|
e.getModifiers()); |
367 |
|
target.actionPerformed(derivedEvent); |
368 |
|
} |
369 |
} |
} |
370 |
|
|
371 |
/** |
/** |
385 |
{ |
{ |
386 |
ListSelectionModel rowModel = table.getSelectionModel(); |
ListSelectionModel rowModel = table.getSelectionModel(); |
387 |
ListSelectionModel colModel = table.getColumnModel().getSelectionModel(); |
ListSelectionModel colModel = table.getColumnModel().getSelectionModel(); |
388 |
|
|
389 |
int rowLead = rowModel.getLeadSelectionIndex(); |
int rowLead = rowModel.getLeadSelectionIndex(); |
390 |
int rowMax = table.getModel().getRowCount() - 1; |
int rowMax = table.getModel().getRowCount() - 1; |
391 |
|
|
599 |
colModel, colMinSelected, colMaxSelected, |
colModel, colMinSelected, colMaxSelected, |
600 |
(e.getActionCommand().equals |
(e.getActionCommand().equals |
601 |
("selectPreviousRowCell")), false); |
("selectPreviousRowCell")), false); |
|
|
|
|
table.repaint(); |
|
602 |
} |
} |
603 |
else if (e.getActionCommand().equals("selectNextColumn")) |
else if (e.getActionCommand().equals("selectNextColumn")) |
604 |
{ |
{ |
686 |
// to a keyboard input but we either want to ignore that input |
// to a keyboard input but we either want to ignore that input |
687 |
// or we just haven't implemented its action yet. |
// or we just haven't implemented its action yet. |
688 |
} |
} |
689 |
|
|
690 |
|
if (table.isEditing() && e.getActionCommand() != "startEditing") |
691 |
|
table.editingCanceled(new ChangeEvent("update")); |
692 |
|
table.repaint(); |
693 |
|
|
694 |
table.scrollRectToVisible |
table.scrollRectToVisible |
695 |
(table.getCellRect(rowModel.getLeadSelectionIndex(), |
(table.getCellRect(rowModel.getLeadSelectionIndex(), |