EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [UiTools.java]

nameclass, %method, %block, %line, %
UiTools.java100% (1/1)95%  (21/22)92%  (1278/1386)95%  (285.3/301)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class UiTools100% (1/1)95%  (21/22)92%  (1278/1386)95%  (285.3/301)
getInvisibleCursor (): Cursor 0%   (0/1)0%   (0/28)0%   (0/5)
ifAnyMaskSetThenAppend (StringBuffer, int, int, int, String): void 100% (1/1)64%  (7/11)67%  (2/3)
<static initializer> 100% (1/1)68%  (17/25)70%  (1.4/2)
attemptToRemoveActionListener (AbstractButton, ActionListener): void 100% (1/1)71%  (10/14)88%  (3.5/4)
removeKeyStroke (JComponent, KeyStroke []): void 100% (1/1)72%  (44/61)71%  (10/14)
attemptToRemoveDocumentListener (JTextField, DocumentListener): void 100% (1/1)73%  (11/15)88%  (3.5/4)
addToKeyMap (int, String): void 100% (1/1)74%  (23/31)85%  (4.2/5)
addKeyStrokeAction (JComponent, String, Action): void 100% (1/1)81%  (21/26)93%  (4.6/5)
keyStrokeToString (KeyStroke): String 100% (1/1)88%  (132/150)93%  (20.5/22)
fillMnemonics (JMenuBar): void 100% (1/1)93%  (50/54)95%  (10.5/11)
fillMnemonics (JMenu): void 100% (1/1)95%  (73/77)97%  (17.5/18)
initColumnWidths (JTable): void 100% (1/1)97%  (152/156)98%  (24.5/25)
UiTools (): void 100% (1/1)100% (18/18)100% (6/6)
centerUp (Component): void 100% (1/1)100% (5/5)100% (2/2)
createDialogMainPanel (): JPanel 100% (1/1)100% (22/22)100% (6/6)
createRigidAreaBetweenButtons (): Component 100% (1/1)100% (4/4)100% (1/1)
getKeyText (int): String 100% (1/1)100% (69/69)100% (10/10)
instance (): UiTools 100% (1/1)100% (8/8)100% (3/3)
mnemonicable (JMenuItem): boolean 100% (1/1)100% (16/16)100% (6/6)
removeKeyStroke (InputMap, KeyStroke []): void 100% (1/1)100% (17/17)100% (4/4)
removeKeyStroke (InputMap, KeyStroke): void 100% (1/1)100% (21/21)100% (5/5)
setUpKeyMap (): void 100% (1/1)100% (558/558)100% (140/140)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.awt.BorderLayout;
19import java.awt.Component;
20import java.awt.Cursor;
21import java.awt.Dimension;
22import java.awt.Image;
23import java.awt.LayoutManager;
24import java.awt.Point;
25import java.awt.Toolkit;
26import java.awt.event.ActionListener;
27import java.awt.event.InputEvent;
28import java.awt.event.KeyEvent;
29import java.awt.image.MemoryImageSource;
30import java.util.HashMap;
31import java.util.LinkedList;
32import java.util.List;
33import java.util.Map;
34 
35import javax.swing.AbstractButton;
36import javax.swing.Action;
37import javax.swing.BorderFactory;
38import javax.swing.Box;
39import javax.swing.DefaultCellEditor;
40import javax.swing.InputMap;
41import javax.swing.JComponent;
42import javax.swing.JMenu;
43import javax.swing.JMenuBar;
44import javax.swing.JMenuItem;
45import javax.swing.JPanel;
46import javax.swing.JTable;
47import javax.swing.JTextField;
48import javax.swing.KeyStroke;
49import javax.swing.border.Border;
50import javax.swing.event.DocumentListener;
51import javax.swing.table.TableCellRenderer;
52import javax.swing.table.TableColumn;
53import javax.swing.table.TableModel;
54 
55import net.sf.jomic.common.PropertyConstants;
56import net.sf.wraplog.Logger;
57 
58/**
59 *  User interface tools.
60 *
61 * @author    Thomas Aglassinger
62 */
63public final class UiTools
64{
65 
66    /**
67     *  Inset to use at the border of a JFrame or JDialog.
68     */
69    public static final int FRAME_INSET = 16;
70    private static final int CURSOR_SIZE = 16;
71    private static final int EMPTY_PIXELS_BETWEEN_BUTTONS = 6;
72    private static final int KEY_STROKE_HEX_DIGIT_COUNT = 8;
73    private static final int KEY_STROKE_TEXT_BUFFER_SIZE = 48;
74 
75    private static UiTools instance;
76    private static Cursor invisibleCursor;
77    private static Logger logger = Logger.getLogger(UiTools.class);
78 
79    private ErrorTools errorTools;
80    private Map keyMap;
81    private Dimension rigidAreaBetweenButtonsSize;
82    private StringTools stringTools;
83 
84    private UiTools() {
85        errorTools = ErrorTools.instance();
86        stringTools = StringTools.instance();
87        rigidAreaBetweenButtonsSize =
88                new Dimension(EMPTY_PIXELS_BETWEEN_BUTTONS, EMPTY_PIXELS_BETWEEN_BUTTONS);
89        setUpKeyMap();
90    }
91 
92    private void setUpKeyMap() {
93        keyMap = new HashMap();
94        addToKeyMap(KeyEvent.VK_COMMA, "COMMA");
95        addToKeyMap(KeyEvent.VK_PERIOD, "PERIOD");
96        addToKeyMap(KeyEvent.VK_SLASH, "SLASH");
97        addToKeyMap(KeyEvent.VK_SEMICOLON, "SEMICOLON");
98        addToKeyMap(KeyEvent.VK_EQUALS, "EQUALS");
99        addToKeyMap(KeyEvent.VK_OPEN_BRACKET, "OPEN_BRACKET");
100        addToKeyMap(KeyEvent.VK_BACK_SLASH, "BACK_SLASH");
101        addToKeyMap(KeyEvent.VK_CLOSE_BRACKET, "CLOSE_BRACKET");
102        addToKeyMap(KeyEvent.VK_ENTER, "ENTER");
103        addToKeyMap(KeyEvent.VK_BACK_SPACE, "BACK_SPACE");
104        addToKeyMap(KeyEvent.VK_TAB, "TAB");
105        addToKeyMap(KeyEvent.VK_CANCEL, "CANCEL");
106        addToKeyMap(KeyEvent.VK_CLEAR, "CLEAR");
107        addToKeyMap(KeyEvent.VK_SHIFT, "SHIFT");
108        addToKeyMap(KeyEvent.VK_CONTROL, "CONTROL");
109        addToKeyMap(KeyEvent.VK_ALT, "ALT");
110        addToKeyMap(KeyEvent.VK_PAUSE, "PAUSE");
111        addToKeyMap(KeyEvent.VK_CAPS_LOCK, "CAPS_LOCK");
112        addToKeyMap(KeyEvent.VK_ESCAPE, "ESCAPE");
113        addToKeyMap(KeyEvent.VK_SPACE, "SPACE");
114        addToKeyMap(KeyEvent.VK_PAGE_UP, "PAGE_UP");
115        addToKeyMap(KeyEvent.VK_PAGE_DOWN, "PAGE_DOWN");
116        addToKeyMap(KeyEvent.VK_END, "END");
117        addToKeyMap(KeyEvent.VK_HOME, "HOME");
118        addToKeyMap(KeyEvent.VK_LEFT, "LEFT");
119        addToKeyMap(KeyEvent.VK_UP, "UP");
120        addToKeyMap(KeyEvent.VK_RIGHT, "RIGHT");
121        addToKeyMap(KeyEvent.VK_DOWN, "DOWN");
122        addToKeyMap(KeyEvent.VK_MULTIPLY, "MULTIPLY");
123        addToKeyMap(KeyEvent.VK_ADD, "ADD");
124        addToKeyMap(KeyEvent.VK_SEPARATOR, "SEPARATOR");
125        addToKeyMap(KeyEvent.VK_SUBTRACT, "SUBTRACT");
126        addToKeyMap(KeyEvent.VK_DECIMAL, "DECIMAL");
127        addToKeyMap(KeyEvent.VK_DIVIDE, "DIVIDE");
128        addToKeyMap(KeyEvent.VK_DELETE, "DELETE");
129        addToKeyMap(KeyEvent.VK_NUM_LOCK, "NUM_LOCK");
130        addToKeyMap(KeyEvent.VK_SCROLL_LOCK, "SCROLL_LOCK");
131        addToKeyMap(KeyEvent.VK_F1, "F1");
132        addToKeyMap(KeyEvent.VK_F2, "F2");
133        addToKeyMap(KeyEvent.VK_F3, "F3");
134        addToKeyMap(KeyEvent.VK_F4, "F4");
135        addToKeyMap(KeyEvent.VK_F5, "F5");
136        addToKeyMap(KeyEvent.VK_F6, "F6");
137        addToKeyMap(KeyEvent.VK_F7, "F7");
138        addToKeyMap(KeyEvent.VK_F8, "F8");
139        addToKeyMap(KeyEvent.VK_F9, "F9");
140        addToKeyMap(KeyEvent.VK_F10, "F10");
141        addToKeyMap(KeyEvent.VK_F11, "F11");
142        addToKeyMap(KeyEvent.VK_F12, "F12");
143        addToKeyMap(KeyEvent.VK_F13, "F13");
144        addToKeyMap(KeyEvent.VK_F14, "F14");
145        addToKeyMap(KeyEvent.VK_F15, "F15");
146        addToKeyMap(KeyEvent.VK_F16, "F16");
147        addToKeyMap(KeyEvent.VK_F17, "F17");
148        addToKeyMap(KeyEvent.VK_F18, "F18");
149        addToKeyMap(KeyEvent.VK_F19, "F19");
150        addToKeyMap(KeyEvent.VK_F20, "F20");
151        addToKeyMap(KeyEvent.VK_F21, "F21");
152        addToKeyMap(KeyEvent.VK_F22, "F22");
153        addToKeyMap(KeyEvent.VK_F23, "F23");
154        addToKeyMap(KeyEvent.VK_F24, "F24");
155        addToKeyMap(KeyEvent.VK_PRINTSCREEN, "PRINTSCREEN");
156        addToKeyMap(KeyEvent.VK_INSERT, "INSERT");
157        addToKeyMap(KeyEvent.VK_HELP, "HELP");
158        addToKeyMap(KeyEvent.VK_META, "META");
159        addToKeyMap(KeyEvent.VK_BACK_QUOTE, "BACK_QUOTE");
160        addToKeyMap(KeyEvent.VK_QUOTE, "QUOTE");
161        addToKeyMap(KeyEvent.VK_KP_UP, "KP_UP");
162        addToKeyMap(KeyEvent.VK_KP_DOWN, "KP_DOWN");
163        addToKeyMap(KeyEvent.VK_KP_LEFT, "KP_LEFT");
164        addToKeyMap(KeyEvent.VK_KP_RIGHT, "KP_RIGHT");
165        addToKeyMap(KeyEvent.VK_DEAD_GRAVE, "DEAD_GRAVE");
166        addToKeyMap(KeyEvent.VK_DEAD_ACUTE, "DEAD_ACUTE");
167        addToKeyMap(KeyEvent.VK_DEAD_CIRCUMFLEX, "DEAD_CIRCUMFLEX");
168        addToKeyMap(KeyEvent.VK_DEAD_TILDE, "DEAD_TILDE");
169        addToKeyMap(KeyEvent.VK_DEAD_MACRON, "DEAD_MACRON");
170        addToKeyMap(KeyEvent.VK_DEAD_BREVE, "DEAD_BREVE");
171        addToKeyMap(KeyEvent.VK_DEAD_ABOVEDOT, "DEAD_ABOVEDOT");
172        addToKeyMap(KeyEvent.VK_DEAD_DIAERESIS, "DEAD_DIAERESIS");
173        addToKeyMap(KeyEvent.VK_DEAD_ABOVERING, "DEAD_ABOVERING");
174        addToKeyMap(KeyEvent.VK_DEAD_DOUBLEACUTE, "DEAD_DOUBLEACUTE");
175        addToKeyMap(KeyEvent.VK_DEAD_CARON, "DEAD_CARON");
176        addToKeyMap(KeyEvent.VK_DEAD_CEDILLA, "DEAD_CEDILLA");
177        addToKeyMap(KeyEvent.VK_DEAD_OGONEK, "DEAD_OGONEK");
178        addToKeyMap(KeyEvent.VK_DEAD_IOTA, "DEAD_IOTA");
179        addToKeyMap(KeyEvent.VK_DEAD_VOICED_SOUND, "DEAD_VOICED_SOUND");
180        addToKeyMap(KeyEvent.VK_DEAD_SEMIVOICED_SOUND, "DEAD_SEMIVOICED_SOUND");
181        addToKeyMap(KeyEvent.VK_AMPERSAND, "AMPERSAND");
182        addToKeyMap(KeyEvent.VK_ASTERISK, "ASTERISK");
183        addToKeyMap(KeyEvent.VK_QUOTEDBL, "QUOTEDBL");
184        addToKeyMap(KeyEvent.VK_LESS, "LESS");
185        addToKeyMap(KeyEvent.VK_GREATER, "GREATER");
186        addToKeyMap(KeyEvent.VK_BRACELEFT, "BRACELEFT");
187        addToKeyMap(KeyEvent.VK_BRACERIGHT, "BRACERIGHT");
188        addToKeyMap(KeyEvent.VK_AT, "AT");
189        addToKeyMap(KeyEvent.VK_COLON, "COLON");
190        addToKeyMap(KeyEvent.VK_CIRCUMFLEX, "CIRCUMFLEX");
191        addToKeyMap(KeyEvent.VK_DOLLAR, "DOLLAR");
192        addToKeyMap(KeyEvent.VK_EURO_SIGN, "EURO_SIGN");
193        addToKeyMap(KeyEvent.VK_EXCLAMATION_MARK, "EXCLAMATION_MARK");
194        addToKeyMap(KeyEvent.VK_INVERTED_EXCLAMATION_MARK, "INVERTED_EXCLAMATION_MARK");
195        addToKeyMap(KeyEvent.VK_LEFT_PARENTHESIS, "LEFT_PARENTHESIS");
196        addToKeyMap(KeyEvent.VK_NUMBER_SIGN, "NUMBER_SIGN");
197        addToKeyMap(KeyEvent.VK_MINUS, "MINUS");
198        addToKeyMap(KeyEvent.VK_PLUS, "PLUS");
199        addToKeyMap(KeyEvent.VK_RIGHT_PARENTHESIS, "RIGHT_PARENTHESIS");
200        addToKeyMap(KeyEvent.VK_UNDERSCORE, "UNDERSCORE");
201        addToKeyMap(KeyEvent.VK_FINAL, "FINAL");
202        addToKeyMap(KeyEvent.VK_CONVERT, "CONVERT");
203        addToKeyMap(KeyEvent.VK_NONCONVERT, "NONCONVERT");
204        addToKeyMap(KeyEvent.VK_ACCEPT, "ACCEPT");
205        addToKeyMap(KeyEvent.VK_MODECHANGE, "MODECHANGE");
206        addToKeyMap(KeyEvent.VK_KANA, "KANA");
207        addToKeyMap(KeyEvent.VK_KANJI, "KANJI");
208        addToKeyMap(KeyEvent.VK_ALPHANUMERIC, "ALPHANUMERIC");
209        addToKeyMap(KeyEvent.VK_KATAKANA, "KATAKANA");
210        addToKeyMap(KeyEvent.VK_HIRAGANA, "HIRAGANA");
211        addToKeyMap(KeyEvent.VK_FULL_WIDTH, "FULL_WIDTH");
212        addToKeyMap(KeyEvent.VK_HALF_WIDTH, "HALF_WIDTH");
213        addToKeyMap(KeyEvent.VK_ROMAN_CHARACTERS, "ROMAN_CHARACTERS");
214        addToKeyMap(KeyEvent.VK_ALL_CANDIDATES, "ALL_CANDIDATES");
215        addToKeyMap(KeyEvent.VK_PREVIOUS_CANDIDATE, "PREVIOUS_CANDIDATE");
216        addToKeyMap(KeyEvent.VK_CODE_INPUT, "CODE_INPUT");
217        addToKeyMap(KeyEvent.VK_JAPANESE_KATAKANA, "JAPANESE_KATAKANA");
218        addToKeyMap(KeyEvent.VK_JAPANESE_HIRAGANA, "JAPANESE_HIRAGANA");
219        addToKeyMap(KeyEvent.VK_JAPANESE_ROMAN, "JAPANESE_ROMAN");
220        addToKeyMap(KeyEvent.VK_KANA_LOCK, "KANA_LOCK");
221        addToKeyMap(KeyEvent.VK_INPUT_METHOD_ON_OFF, "INPUT_METHOD_ON_OFF");
222        addToKeyMap(KeyEvent.VK_AGAIN, "AGAIN");
223        addToKeyMap(KeyEvent.VK_UNDO, "UNDO");
224        addToKeyMap(KeyEvent.VK_COPY, "COPY");
225        addToKeyMap(KeyEvent.VK_PASTE, "PASTE");
226        addToKeyMap(KeyEvent.VK_CUT, "CUT");
227        addToKeyMap(KeyEvent.VK_FIND, "FIND");
228        addToKeyMap(KeyEvent.VK_PROPS, "PROPS");
229        addToKeyMap(KeyEvent.VK_STOP, "STOP");
230        addToKeyMap(KeyEvent.VK_COMPOSE, "COMPOSE");
231        addToKeyMap(KeyEvent.VK_ALT_GRAPH, "ALT_GRAPH");
232    }
233 
234    /**
235     *  Get an invisible Cursor. (Based on code by R?al Gagnon, see <a
236     *  href="http://www.rgagnon.com/javadetails/java-0440.html">
237     *  http://www.rgagnon.com/javadetails/java-0440.html</a> for details.
238     */
239    public synchronized Cursor getInvisibleCursor() {
240        if (invisibleCursor == null) {
241            int[] pixels = new int[CURSOR_SIZE * CURSOR_SIZE];
242            Image image = Toolkit.getDefaultToolkit().createImage(
243                    new MemoryImageSource(CURSOR_SIZE, CURSOR_SIZE, pixels, 0, CURSOR_SIZE));
244 
245            invisibleCursor = Toolkit.getDefaultToolkit().createCustomCursor(image,
246                    new Point(0, 0), "invisiblecursor");
247        }
248        return invisibleCursor;
249    }
250 
251    /**
252     *  Get (English) text for keyboard code.
253     */
254    public String getKeyText(int keyCode) {
255        String result;
256 
257        if ((keyCode >= KeyEvent.VK_0) && (keyCode <= KeyEvent.VK_9)
258                || (keyCode >= KeyEvent.VK_A) && (keyCode <= KeyEvent.VK_Z)) {
259            result = String.valueOf((char) keyCode);
260        } else {
261            result = (String) keyMap.get(new Integer(keyCode));
262            if (result == null) {
263                if (keyCode >= KeyEvent.VK_NUMPAD0 && keyCode <= KeyEvent.VK_NUMPAD9) {
264                    char c = (char) (keyCode - KeyEvent.VK_NUMPAD0 + '0');
265 
266                    result = "NUMPAD" + c;
267                } else {
268                    result = "unknown(" + stringTools.hexString(keyCode, KEY_STROKE_HEX_DIGIT_COUNT) + ")";
269                }
270            }
271        }
272 
273        return result;
274    }
275 
276    public static synchronized UiTools instance() {
277        if (instance == null) {
278            instance = new UiTools();
279        }
280        return instance;
281    }
282 
283    public void addKeyStrokeAction(JComponent component, String keyStrokeName, Action action) {
284        String command = (String) action.getValue(Action.NAME);
285 
286        assert command != null : "action must have a name";
287        component.getInputMap().put(KeyStroke.getKeyStroke(keyStrokeName), command);
288        component.getActionMap().put(command, action);
289    }
290 
291    /**
292     *  Provided that <code>button</code> is not null, remove <code>listener</code> from it.
293     */
294    public void attemptToRemoveActionListener(AbstractButton button, ActionListener listener) {
295        assert listener != null;
296 
297        if (button != null) {
298            button.removeActionListener(listener);
299        }
300    }
301 
302    /**
303     *  Provided that <code>field</code> is not null, remove <code>listener</code> from its <code>Document</code>
304     *  .
305     */
306    public void attemptToRemoveDocumentListener(JTextField field, DocumentListener listener) {
307        assert listener != null;
308 
309        if (field != null) {
310            field.getDocument().removeDocumentListener(listener);
311        }
312    }
313 
314    /**
315     *  Center frame in upper half of the screen.
316     */
317    public void centerUp(Component frame) {
318        errorTools.centerUp(frame);
319    }
320 
321    public JPanel createDialogMainPanel() {
322        JPanel result = new JPanel();
323        Border border = BorderFactory.createEmptyBorder(FRAME_INSET, FRAME_INSET, FRAME_INSET, FRAME_INSET);
324        LayoutManager layout = new BorderLayout();
325 
326        result.setBorder(border);
327        result.setLayout(layout);
328        return result;
329    }
330 
331    /**
332     *  Create ridig area to put "some" space between two buttons in a BoxLayout.
333     *
334     * @see    Box#createRigidArea(java.awt.Dimension)
335     */
336    public Component createRigidAreaBetweenButtons() {
337        return Box.createRigidArea(rigidAreaBetweenButtonsSize);
338    }
339 
340    /**
341     *  Set mnemonics in <code>menu</code> depending on the labels of the MenuItems.
342     */
343    public void fillMnemonics(JMenu menu) {
344        assert menu != null;
345        int itemCount = menu.getItemCount();
346        List labelList = new LinkedList();
347 
348        for (int i = 0; i < itemCount; i += 1) {
349            JMenuItem item = menu.getItem(i);
350 
351            if (mnemonicable(item)) {
352                String label = item.getText();
353 
354                labelList.add(label);
355            }
356        }
357 
358        String[] labels = (String[]) labelList.toArray(new String[0]);
359        char[] mnemonics = stringTools.getMnemonics(labels, null);
360        int j = 0;
361 
362        for (int i = 0; i < itemCount; i += 1) {
363            JMenuItem item = menu.getItem(i);
364 
365            if (mnemonicable(item)) {
366                if (!Boolean.getBoolean(
367                        PropertyConstants.SYSTEM_PROPERTY_PREFIX + PropertyConstants.HIDE_MNEMONICS)) {
368                    item.setMnemonic(mnemonics[j]);
369                }
370                j += 1;
371            }
372        }
373    }
374 
375    /**
376     *  Set mnemonics in <code>bar</code> depending on the labels of the Menus and MenuItems.
377     */
378    public void fillMnemonics(JMenuBar bar) {
379        assert bar != null;
380        int menuCount = bar.getMenuCount();
381        String[] labels = new String[menuCount];
382 
383        for (int i = 0; i < menuCount; i += 1) {
384            labels[i] = bar.getMenu(i).getText();
385        }
386 
387        char[] mnemonics = stringTools.getMnemonics(labels, null);
388 
389        for (int i = 0; i < menuCount; i += 1) {
390            JMenu menu = bar.getMenu(i);
391 
392            menu.setMnemonic(mnemonics[i]);
393            fillMnemonics(menu);
394        }
395    }
396 
397    /**
398     *  This method picks good column sizes. If all column heads are wider than the column's cells'
399     *  contents, then you can just use column.sizeWidthToFit().
400     */
401    public void initColumnWidths(JTable table) {
402        assert table != null;
403        TableModel tableModel = table.getModel();
404        TableColumn columnModel = null;
405        Component componet = null;
406        int headerWidth = 0;
407        int cellWidth = 0;
408        TableCellRenderer headerRenderer = table.getTableHeader().getDefaultRenderer();
409 
410        if (logger.isDebugEnabled()) {
411            logger.debug("init widths of " + table.getColumnCount() + "x" + table.getRowCount() + " table");
412        }
413 
414        for (int column = 0; column < table.getColumnCount(); column += 1) {
415            columnModel = table.getColumnModel().getColumn(column);
416 
417            componet = headerRenderer.getTableCellRendererComponent(
418                    null, columnModel.getHeaderValue(), false, false, 0, 0);
419            headerWidth = componet.getPreferredSize().width;
420 
421            int maxCellWidth = 0;
422 
423            for (int row = 0; row < table.getRowCount(); row += 1) {
424                componet =
425                        table.getDefaultRenderer(tableModel.getColumnClass(column)).getTableCellRendererComponent(
426                        table,
427                        table.getValueAt(row, column),
428                        false,
429                        false,
430                        0,
431                        column);
432                cellWidth = componet.getPreferredSize().width;
433                if (logger.isDebugEnabled()) {
434                    logger.debug("cellwidth(" + column + "," + row + ")=" + cellWidth);
435                }
436                if (cellWidth > maxCellWidth) {
437                    maxCellWidth = cellWidth;
438                }
439            }
440 
441            if (logger.isDebugEnabled()) {
442                logger.debug(
443                        "initializing width of column "
444                        + column
445                        + ". "
446                        + "headerWidth = "
447                        + headerWidth
448                        + "; maxCellWidth = "
449                        + maxCellWidth);
450            }
451            columnModel.setPreferredWidth(Math.max(headerWidth, maxCellWidth));
452        }
453    }
454 
455    /**
456     *  <p>
457     *
458     *  Get a string that is parseably by <code>KeyStroke.getKeyStroke()</code>. (<code>KeyStroke.toString()</code>
459     *  does not return such a string.)</p> <p>
460     *
461     *  However, there is one keystroke that cannot be represented as a string that can be parsed
462     *  back to a keystroke - a typed space character. In order to bind an action to a typed space
463     *  character, <code>KeyStroke.getKeyStroke(new Character(' '), 0)</code> needs to be called.
464     *  </p> Source: <a href="http://javaalmanac.com/egs/javax.swing/Key2Str.html">The Java
465     *  Developers Almanac 1.4</a> .
466     *
467     * @see    KeyStroke#getKeyStroke(java.lang.String)
468     */
469    public String keyStrokeToString(KeyStroke keyStroke) {
470        assert keyStroke != null;
471 
472        StringBuffer result = new StringBuffer(KEY_STROKE_TEXT_BUFFER_SIZE);
473        int modifiers = keyStroke.getModifiers();
474 
475        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_MASK, "shift ");
476        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_MASK, "ctrl ");
477        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.META_DOWN_MASK, InputEvent.META_MASK, "meta ");
478        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_MASK, "alt ");
479        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON1_MASK, "button1 ");
480        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.BUTTON2_DOWN_MASK, InputEvent.BUTTON2_MASK, "button2 ");
481        ifAnyMaskSetThenAppend(result, modifiers, InputEvent.BUTTON3_DOWN_MASK, InputEvent.BUTTON3_MASK, "button3 ");
482 
483        int type = keyStroke.getKeyEventType();
484 
485        if (type == KeyEvent.KEY_TYPED) {
486            result.append("typed ");
487            result.append(keyStroke.getKeyChar() + " ");
488        } else if (type == KeyEvent.KEY_PRESSED) {
489            result.append("pressed ");
490            result.append(getKeyText(keyStroke.getKeyCode()) + " ");
491        } else if (type == KeyEvent.KEY_RELEASED) {
492            result.append("released ");
493            result.append(getKeyText(keyStroke.getKeyCode()) + " ");
494        } else {
495            assert false : "keyEventType=" + type;
496        }
497 
498        return result.toString().trim();
499    }
500 
501    /**
502     *  Remove for a JComponent all keyStrokes. Based on a suggestion in a <a
503     *  href="http://forum.java.sun.com/thread.jsp?thread=462430&forum=57&message=2121002">thread
504     *  </a> in Sun's developer forum.
505     */
506    public void removeKeyStroke(JComponent component, KeyStroke[] keyStrokes) {
507        removeKeyStroke(component.getInputMap(JComponent.WHEN_FOCUSED), keyStrokes);
508        removeKeyStroke(component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT), keyStrokes);
509        removeKeyStroke(component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW), keyStrokes);
510        if (component instanceof JTable) {
511            // HACK: Stop VK_LEFT/RIGHT from working on the cell editor.
512            JTable table = (JTable) component;
513            DefaultCellEditor editor = (DefaultCellEditor) table.getCellEditor(0, 0);
514            JComponent editorComponent = (JComponent) editor.getComponent();
515 
516            removeKeyStroke(editorComponent, keyStrokes);
517        }
518        int ub = component.getComponentCount();
519 
520        for (int i = 0; i < ub; i += 1) {
521            Component child = component.getComponent(i);
522 
523            if (child instanceof JComponent) {
524                removeKeyStroke((JComponent) child, keyStrokes);
525            }
526        }
527    }
528 
529    private void addToKeyMap(int keyCode, String text) {
530        assert text != null;
531        Integer integerKeyCode = new Integer(keyCode);
532 
533        assert !keyMap.containsKey(integerKeyCode);
534        keyMap.put(integerKeyCode, text);
535    }
536 
537    /**
538     *  If in <code>value</code> any of the bit masks <code>mask1</code> or <code>mask2</code> is
539     *  enabled, append to the buffer <code>target</code> the text <code>textToAppend</code>.
540     *
541     * @see    #keyStrokeToString(KeyStroke)
542     */
543    private void ifAnyMaskSetThenAppend(StringBuffer target, int value, int mask1, int mask2, String textToAppend) {
544        if ((value & (mask1 | mask2)) != 0) {
545            target.append(textToAppend);
546        }
547    }
548 
549    /**
550     *  Is there any point in giving a mnemonic to a JMenuItem? Possible reasons for not setting a
551     *  mnemonic:
552     *  <ol>
553     *    <li> item is a separator
554     *    <li> item has no label (but only an icon)
555     *  </ol>
556     *
557     */
558    private boolean mnemonicable(JMenuItem item) {
559        boolean result = false;
560 
561        if (item != null) {
562            String label = item.getText();
563 
564            if ((label != null) && (label.length() > 0)) {
565                result = true;
566            }
567        }
568        return result;
569    }
570 
571    private void removeKeyStroke(InputMap im, KeyStroke[] keyStrokes) {
572        for (int i = 0; i < keyStrokes.length; i += 1) {
573            KeyStroke k = keyStrokes[i];
574 
575            removeKeyStroke(im, k);
576        }
577    }
578 
579    private void removeKeyStroke(InputMap inputMap, KeyStroke keyStroke) {
580        Object key = inputMap.get(keyStroke);
581 
582        if (key != null) {
583            logger.debug("remove KeyStroke for key " + key);
584            inputMap.put(keyStroke, "none");
585        }
586    }
587}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov