1 /*
2 * Dictionary port to Java
3 * Copyright (C) 2000 Kaloian Doganov
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 package net.sourceforge.dictport.ui;
20
21 import java.awt;
22 import java.awt.event;
23 import javax.swing;
24 import javax.swing.text;
25 import javax.swing.event;
26 import javax.swing.border;
27 import net.sourceforge.dictport;
28
29 /** Dictionary user interface as single Swing component. */
30 public class Dict extends JPanel {
31
32 private DatabaseRegistry fRegistry;
33 private Database fDatabase;
34 private UserPrefsModel fPrefs;
35 private String fTitle;
36 private boolean fPluginMode;
37
38 /** Default view position. */
39 private Point fTop = new Point(0, 0);
40
41 private JToolBar fToolbar;
42 private JTextField fInput;
43 private JButton fFindButton;
44 private JTextArea fOutput;
45 private JScrollPane fOutputScroll;
46
47 // Actions
48 private Action fInfoAction;
49 private Action fQuitAction;
50 private Action fMinimizeAction;
51 private Action fFindAction;
52 private Action fFindShortcutAction;
53 private Action fSimilarWordsAction;
54 private Action fPreviousWordAction;
55 private Action fOptionsAction;
56 private Action fNextWordAction;
57 private Action fNext20WordAction;
58 private Action fHistoryAction;
59 private Action fHistoryPreviousAction;
60 private Action fHistoryNextAction;
61
62 // Plugin/non-plugin action listeners
63 private ActionListener fPrefsActionListener;
64 private ActionListener fQuitActionListener;
65 private ActionListener fMinimizeActionListener;
66
67 // State
68 /** If this is true, frame is not minimized when lose focus. */
69 private boolean fShowingDialog = false;
70
71 /** Frmae bounds properties prefix. */
72 private static final String kBounds = "frame.bounds.";
73
74 /**
75 * Create new Dict component instance.
76 *
77 * @param aRegistry Database registry to use.
78 * @param aProps Current properties.
79 * @param aPluginMode Plugin mode hides windowing-related components and
80 * properties, e.g. minimize and exit buttons, disable start
81 * minimized property and options dialog checkbox, etc. Also,
82 * scrollbar policy is slightly changed for meaning text box --
83 * <code>VERTICAL_SCROLLBAR_AS_NEEDED</code> instead of
84 * <code>VERTICAL_SCROLLBAR_ALWAYS</code>.
85 * @see #setPrefsActionListener
86 * @see #setQuitActionListener
87 * @see #setMinimizeActionListener
88 */
89 public Dict(DatabaseRegistry aRegistry, UserPrefsModel aPrefs,
90 boolean aPluginMode) {
91
92 super(new BorderLayout());
93 fRegistry = aRegistry;
94 fTitle = "Dictionary";
95 fPrefs = new UserPrefsModel(aPrefs);
96 fPluginMode = aPluginMode;
97 fShowingDialog = false;
98
99 initActions();
100 initComponents();
101 }
102
103
104 /** Set up all actions. */
105 private void initActions() {
106 // Initialize actions
107 fQuitAction = new QuitAction();
108 fMinimizeAction = new MinimizeAction();
109 fFindAction = new FindAction();
110 fFindShortcutAction = new FindShortcutAction();
111 fSimilarWordsAction = new SimilarWordsAction();
112 fPreviousWordAction = new PreviousWordAction();
113 fNextWordAction = new NextWordAction();
114 fNext20WordAction = new Next20WordAction();
115 fOptionsAction = new OptionsAction();
116 fInfoAction = new InfoAction();
117 fHistoryAction = new HistoryAction();
118 fHistoryPreviousAction = new HistoryPreviousAction();
119 fHistoryNextAction = new HistoryNextAction();
120
121 fPrefsActionListener = null;
122 fQuitActionListener = null;
123 fMinimizeActionListener = null;
124 }
125
126 /** Set up all components. */
127 private void initComponents() {
128
129 Container root = this;
130 root.setLayout(new BorderLayout());
131
132 // Find
133 JPanel content = new JPanel();
134 content.setLayout(new BorderLayout());
135 JPanel find = new JPanel();
136 content.add(find, "North");
137 root.add(content, "Center");
138 find.setLayout(new BorderLayout());
139 Insets margin = new Insets(1, 6, 1, 6);
140 fInput = new JTextField();
141 fInput.setMargin(margin);
142 fInput.setDocument(new AutoCompleteDocument());
143 fFindButton = new JButton(fFindAction);
144 JPanel inputPanel = new JPanel(new InputLayout());
145 inputPanel.add(fInput);
146 find.add(inputPanel, "Center");
147 JPanel btnPanel = new JPanel();
148 btnPanel.add(fFindButton);
149 find.add(btnPanel, "East");
150 fInput.getDocument().addDocumentListener(new InputHandler());
151 fInput.setAction(fFindShortcutAction);
152
153 //getRootPane().setDefaultButton(fFindButton);
154
155 // Toolbar
156 fToolbar = new JToolBar();
157 fToolbar.setFloatable(false);
158 root.add(fToolbar, "North");
159
160 // add toolbar buttons
161 /*
162 fToolbar.add(new JButton(createImageIcon("NewFolder.gif")));
163 fToolbar.add(new JButton(createImageIcon("OpenArrow.gif")));
164 */
165 fToolbar.add(new ToolButton(fInfoAction,
166 "Dictionary information"));
167 fToolbar.addSeparator();
168 fToolbar.add(new ToolButton(fPreviousWordAction,
169 "Previous word (Up Arrow)", "UP"));
170 fToolbar.add(new ToolButton(fNext20WordAction,
171 "Next 20 words (Ctrl+Down Arrow)", "control DOWN"));
172 fToolbar.add(new ToolButton(fNextWordAction, "Next word (Down Arrow)",
173 "DOWN"));
174 fToolbar.addSeparator();
175 fToolbar.add(new ToolButton(fSimilarWordsAction,
176 "Find similar words", "control S"));
177 fToolbar.addSeparator();
178 fToolbar.add(new ToolButton(fHistoryPreviousAction,
179 "Previous word in the history list"));
180 fToolbar.add(new ToolButton(fHistoryAction,
181 "Display all the words in the history"));
182 fToolbar.add(new ToolButton(fHistoryNextAction,
183 "Next word in the history list"));
184 /*
185 fToolbar.addSeparator();
186 fToolbar.add(new JButton(createImageIcon("Plus.gif")));
187 fToolbar.add(new JButton(createImageIcon("Minus.gif")));
188 */
189 fToolbar.addSeparator();
190 fToolbar.add(new ToolButton(fOptionsAction, "Program settings"));
191 if (!fPluginMode) {
192 fToolbar.addSeparator();
193 fToolbar.add(new ToolButton(fMinimizeAction, "Hide program"));
194 fToolbar.addSeparator();
195 fToolbar.add(new ToolButton(fQuitAction, "Quit program"));
196 }
197
198 // Meaning
199 fOutput = new JTextArea(5, 5);
200 fOutput.setLineWrap(true);
201 fOutput.setWrapStyleWord(true);
202 fOutput.setEditable(false);
203 fOutput.setMargin(margin);
204 int vpolicy = fPluginMode ?
205 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED :
206 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS;
207 fOutputScroll = new JScrollPane(fOutput,
208 vpolicy,
209 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
210 content.add(fOutputScroll, "Center");
211
212 // Tooltips status
213 applyPrefs();
214 }
215
216 /** Create image icon from a file. */
217 private Icon createImageIcon(String aFilename) {
218 Class c = this.getClass();
219 return new ImageIcon(c.getResource(aFilename));
220 }
221
222 /** Open registered database. */
223 public void open(String aDictID) {
224 fDatabase = fRegistry.open(aDictID);
225 String title = "Dictionary - [" + fDatabase.getInfo().getName() + "]";
226 fTitle = title;
227 }
228
229 /** Get dictionary component string, suitable for application frame title. */
230 public String getTitle() {
231 return fTitle;
232 }
233
234 /**
235 * @returns The Frame ancestor of this component, or null if component is
236 * not contained inside a Frame.
237 */
238 public Frame getFrame() {
239 return (Frame) SwingUtilities.getWindowAncestor(this);
240 }
241
242 /**
243 * Return current user preferences.
244 */
245 public UserPrefsModel getPreferences() {
246 return fPrefs;
247 }
248
249 /**
250 * Assign and apply user preferences.
251 */
252 public void setPreferences(UserPrefsModel aPrefs) {
253 fPrefs.assign(aPrefs);
254 applyPrefs();
255 }
256
257 /**
258 * Set action listener to handle modified preferences action
259 * (in plugin mode). The new preferences are automatically applied to Dict
260 * instance that generates the event. But plugin may want to propagate this
261 * properties to all Dict instances.
262 *
263 * <p>This method is ignored in non-plugin mode.</p>
264 *
265 * @see #Dict
266 */
267 public void setPrefsActionListener(ActionListener aListener) {
268 fPrefsActionListener = aListener;
269 }
270
271
272 /**
273 * Set action listener to handle quit action (in non-plugin mode).
274 * This method is ignored in plugin mode.
275 *
276 * @see #Dict
277 */
278 public void setQuitActionListener(ActionListener aListener) {
279 fQuitActionListener = aListener;
280 }
281
282 /**
283 * Set action listener to handle minimize action (in non-plugin mode).
284 * This method is ignored in plugin mode.
285 *
286 * @see #Dict
287 */
288 public void setMinimizeActionListener(ActionListener aListener) {
289 fMinimizeActionListener = aListener;
290 }
291
292 /**
293 * Determine whether child dialog is opened. Useful when figuring out if
294 * iconized state must be set in "minimize when lose focus" option.
295 *
296 * @return <code>true</code> if child dialog is opened and application
297 * window must not be iconified.
298 */
299 public boolean isShowingDialog() {
300 return fShowingDialog;
301 }
302
303 /** Display entry. */
304 private void showEntry(Chapter.Entry aEntry) {
305 fInput.setText(aEntry.getKeyDisplay());
306 fOutput.setText(aEntry.getValue());
307 fOutput.setCaretPosition(0);
308 }
309
310 /** Apply user preferences - such as font, etc. */
311 private void applyPrefs() {
312 ToolTipManager.sharedInstance().setEnabled(fPrefs.isShowToolTips());
313 fInput.setFont(fPrefs.getFont());
314 fOutput.setFont(fPrefs.getFont());
315 }
316
317 /** Dictionary info action. */
318 private final class InfoAction extends DictAction {
319 public InfoAction() {
320 super("", "Information");
321 }
322
323 public void actionPerformed(ActionEvent aEvent) {
324 fShowingDialog = true;
325 InfoDialog dialog = new InfoDialog(getFrame(), fDatabase);
326 dialog.show();
327 fShowingDialog = false;
328 }
329 }
330
331 /** Find action. */
332 private final class FindAction extends DictAction {
333 public FindAction() {
334 super("Find");
335 setEnabled(false);
336 }
337
338 public void actionPerformed(ActionEvent aEvent) {
339 try {
340 Chapter.Entry entry = fDatabase.findExact(fInput.getText());
341 showEntry(entry);
342 }
343 catch (ItemNotFoundException e) {
344 if (fPrefs.isShowSimilarAtNotFound())
345 fSimilarWordsAction.actionPerformed(aEvent);
346 }
347 }
348 }
349
350 /** Find action to be used in fInput JTextField. */
351 private final class FindShortcutAction extends DictAction {
352 public FindShortcutAction() {
353 super("Find Shortcut");
354 }
355
356 public void actionPerformed(ActionEvent aEvent) {
357 if (fFindAction.isEnabled())
358 fFindAction.actionPerformed(aEvent);
359 }
360 }
361
362 /** Similar words action. */
363 private final class SimilarWordsAction extends DictAction {
364 public SimilarWordsAction() {
365 super("", "Search");
366 setEnabled(false);
367 }
368
369 public void actionPerformed(ActionEvent aEvent) {
370 //Chapter.Entry entry = fDatabase.findExact(fInput.getText());
371 //showEntry(entry);
372 SimilarDialog dialog = new SimilarDialog(getFrame(),
373 fDatabase.findSimilar(fInput.getText()));
374 dialog.show();
375 if (dialog.isCanceled()) return;
376 try {
377 Chapter.Entry entry = fDatabase.findExact(dialog.getWord());
378 showEntry(entry);
379 fInput.selectAll();
380 }
381 catch (ItemNotFoundException e) {
382 }
383 }
384 }
385
386 /** Previous word action. */
387 private final class PreviousWordAction extends DictAction {
388 public PreviousWordAction() {
389 super("", "Back");
390 setEnabled(false);
391 }
392
393 public void actionPerformed(ActionEvent aEvent) {
394 Chapter.Entry entry = fDatabase.getPrevious(fInput.getText());
395 showEntry(entry);
396 fInput.selectAll();
397 }
398 }
399
400 /** Next word action. */
401 private final class NextWordAction extends DictAction {
402 public NextWordAction() {
403 super("", "Forward");
404 setEnabled(false);
405 }
406
407 public void actionPerformed(ActionEvent aEvent) {
408 Chapter.Entry entry = fDatabase.getNext(fInput.getText());
409 showEntry(entry);
410 fInput.selectAll();
411 }
412 }
413
414 /** Next 20 word action. */
415 private final class Next20WordAction extends DictAction {
416 public Next20WordAction() {
417 super("", "Down");
418 setEnabled(false);
419 }
420
421 public void actionPerformed(ActionEvent aEvent) {
422 JPopupMenu popup = new Next20Menu(fInput.getText());
423 Component source = (Component) aEvent.getSource();
424 Dimension size = source.getSize();
425 popup.show(source, 0, size.height);
426 }
427 }
428
429 /** History action. */
430 private final class HistoryAction extends DictAction {
431 public HistoryAction() {
432 super("", "HistoryDown");
433 }
434
435 public void actionPerformed(ActionEvent aEvent) {
436 JPopupMenu popup = new HistoryMenu();
437 Component source = (Component) aEvent.getSource();
438 Dimension size = source.getSize();
439 popup.show(source, 0, size.height);
440 }
441 }
442
443 /** History previous word action. */
444 private final class HistoryPreviousAction extends DictAction {
445 public HistoryPreviousAction() {
446 super("", "HistoryBack");
447 }
448
449 public void actionPerformed(ActionEvent aEvent) {
450 Chapter.Entry entry = fDatabase.getHistoryPrevious();
451 showEntry(entry);
452 fInput.selectAll();
453 }
454 }
455
456 /** History next word action. */
457 private final class HistoryNextAction extends DictAction {
458 public HistoryNextAction() {
459 super("", "HistoryForward");
460 }
461
462 public void actionPerformed(ActionEvent aEvent) {
463 Chapter.Entry entry = fDatabase.getHistoryNext();
464 showEntry(entry);
465 fInput.selectAll();
466 }
467 }
468
469 /** User options action. */
470 private final class OptionsAction extends DictAction {
471 public OptionsAction() {
472 super("", "Preferences");
473 }
474
475 public void actionPerformed(ActionEvent aEvent) {
476 fShowingDialog = true;
477 OptionsDialog dialog = new OptionsDialog(getFrame(), fPrefs,
478 fPluginMode);
479 dialog.show();
480 if (dialog.isApproved()) {
481 fPrefs = dialog.getUserPrefs();
482 applyPrefs();
483 if (fPluginMode && (fPrefsActionListener != null))
484 fPrefsActionListener.actionPerformed(aEvent);
485 }
486 fShowingDialog = false;
487 }
488 }
489
490 /** Minimize window action. */
491 private final class MinimizeAction extends DictAction {
492 public MinimizeAction() {
493 super("", "Pause");
494 }
495
496 public void actionPerformed(ActionEvent aEvent) {
497 if ((!fPluginMode) && (fMinimizeActionListener != null))
498 fMinimizeActionListener.actionPerformed(aEvent);
499 }
500 }
501
502 /** Quit application action. */
503 private final class QuitAction extends DictAction {
504 public QuitAction() {
505 super("", "Stop");
506 }
507
508 public void actionPerformed(ActionEvent aEvent) {
509 if ((!fPluginMode) && (fQuitActionListener != null))
510 fQuitActionListener.actionPerformed(aEvent);
511 }
512 }
513
514 /** Handle input method events from fInput JTextField. */
515 private final class InputHandler implements DocumentListener {
516
517 private void update(String aText) {
518 boolean enabled = aText.trim().length() > 0;
519 fPreviousWordAction.setEnabled(enabled);
520 fNextWordAction.setEnabled(enabled);
521 fNext20WordAction.setEnabled(enabled);
522 fFindAction.setEnabled(enabled);
523 fSimilarWordsAction.setEnabled(enabled);
524 }
525
526 private void update(DocumentEvent aEvent) {
527 Document doc = aEvent.getDocument();
528 String text = null;
529 try {
530 text = doc.getText(0, doc.getLength());
531 }
532 catch (BadLocationException e) {
533 text = "";
534 }
535 update(text);
536 }
537
538 public void changedUpdate(DocumentEvent aEvent) {
539 update(aEvent);
540 }
541
542 public void insertUpdate(DocumentEvent aEvent) {
543 update(aEvent);
544 }
545
546 public void removeUpdate(DocumentEvent aEvent) {
547 update(aEvent);
548 }
549 }
550
551 /** Implement next 20 words popup menu. */
552 private final class Next20Menu extends JPopupMenu {
553
554 private Next20MenuHandler fNext20MenuHandler;
555
556 /** Create popup menu. */
557 Next20Menu(String aWord) {
558 super();
559 fNext20MenuHandler = new Next20MenuHandler();
560 java.util.List list = fDatabase.getNext20(aWord);
561 java.util.Iterator iterator = list.iterator();
562 while (iterator.hasNext()) {
563 Chapter.Entry entry = (Chapter.Entry) iterator.next();
564 JMenuItem menu = new EntryMenuItem(entry);
565 menu.addActionListener(fNext20MenuHandler);
566 add(menu);
567 }
568 }
569
570 private final class Next20MenuHandler implements ActionListener {
571 public void actionPerformed(ActionEvent aEvent) {
572 EntryMenuItem source = (EntryMenuItem) aEvent.getSource();
573 showEntry(source.getEntry());
574 fInput.selectAll();
575 }
576 }
577
578 private final class EntryMenuItem extends JMenuItem {
579
580 private Chapter.Entry fEntry;
581
582 EntryMenuItem(Chapter.Entry aEntry) {
583 super(aEntry.getKeyDisplay());
584 setFont(fPrefs.getFont());
585 fEntry = aEntry;
586 }
587
588 public Chapter.Entry getEntry() {
589 return fEntry;
590 }
591 }
592 }
593
594 /** Implement next 20 words popup menu. */
595 private final class HistoryMenu extends JPopupMenu {
596
597 private HistoryMenuHandler fHistoryMenuHandler;
598
599 /** Create popup menu. */
600 HistoryMenu() {
601 super();
602 fHistoryMenuHandler = new HistoryMenuHandler();
603 java.util.List list = fDatabase.getHistory();
604 java.util.Iterator iterator = list.iterator();
605 while (iterator.hasNext()) {
606 String key = (String) iterator.next();
607 JMenuItem menu = new HistoryMenuItem(key);
608 menu.addActionListener(fHistoryMenuHandler);
609 add(menu);
610 }
611 }
612
613 private final class HistoryMenuHandler implements ActionListener {
614 public void actionPerformed(ActionEvent aEvent) {
615 HistoryMenuItem source = (HistoryMenuItem) aEvent.getSource();
616 String key = source.getDisplayKey();
617 try {
618 Chapter.Entry entry = fDatabase.findExact(key);
619 showEntry(entry);
620 fInput.selectAll();
621 }
622 catch (ItemNotFoundException e) {
623 }
624 }
625 }
626
627 private final class HistoryMenuItem extends JMenuItem {
628
629 private String fDisplayKey;
630
631 HistoryMenuItem(String aDisplayKey) {
632 super(aDisplayKey);
633 fDisplayKey = aDisplayKey;
634 setFont(fPrefs.getFont());
635 }
636
637 public String getDisplayKey() {
638 return fDisplayKey;
639 }
640 }
641 }
642
643 /**
644 * Provides hard recoding for high 8-bit characters. All ISO-8859-1
645 * (aka Latin-1) chars are interpreted as Cp1251. All cyrillic chars are
646 * converted to Cp1251.
647 */
648 private class CyrillicDocument extends PlainDocument {
649
650 public CyrillicDocument() {
651 super();
652 }
653
654 public void insertString(int aOffset, String aString, AttributeSet anAttr)
655 throws BadLocationException {
656
657 StringBuffer buffer = new StringBuffer(aString.length());
658 Character.UnicodeBlock cyr = Character.UnicodeBlock.CYRILLIC;
659
660 char[] chars = aString.toCharArray();
661 for (int i = 0; i < chars.length; i++) {
662 if (Character.UnicodeBlock.of(chars[i]).equals(cyr)) {
663 buffer.append(chars[i]);
664 }
665 else {
666 try {
667 String c = new Character(chars[i]).toString();
668 byte[] b = c.getBytes("ISO-8859-1");
669 buffer.append(new String(b, "Cp1251"));
670 }
671 catch (java.io.UnsupportedEncodingException e) {
672 e.printStackTrace();
673 }
674 }
675 }
676
677 super.insertString(aOffset, buffer.toString(), anAttr);
678 }
679 }
680
681 /** Document for AutoComplete enabled JTextField. */
682 private final class AutoCompleteDocument extends CyrillicDocument {
683
684 public AutoCompleteDocument() {
685 super();
686 }
687
688 public void insertString(int aOffset, String aString, AttributeSet anAttr)
689 throws BadLocationException {
690
691 // Do not auto complete words.
692 if (!fPrefs.isAutoCompleteWords()) {
693 super.insertString(aOffset, aString, anAttr);
694 return;
695 }
696
697 if (fDatabase == null) {
698 super.insertString(aOffset, aString, anAttr);
699 return;
700 }
701
702 // Let's auto complete words.
703 StringBuffer word = new StringBuffer();
704 word.append(getText(0, getLength()));
705 word.insert(aOffset, aString);
706 String sWord = word.toString();
707
708 // return if empty; don't try to auto complete
709 if (sWord.length() == 0) {
710 super.remove(0, getLength());
711 return;
712 }
713
714 Chapter.Entry entry = null;
715 try {
716 entry = fDatabase.findAutoComplete(sWord);
717 super.remove(0, getLength());
718 super.insertString(0, entry.getKeyDisplay(), null);
719 fInput.setSelectionStart(sWord.length());
720 fInput.setSelectionEnd(getLength());
721 }
722 catch (ItemNotFoundException e) {
723 super.insertString(aOffset, aString, anAttr);
724 return;
725 }
726 }
727 }
728
729 /** Layout manager for the input text field. */
730 private final static class InputLayout implements LayoutManager {
731 private static final int kGap = 3; // pixels
732
733 public void addLayoutComponent(String name, Component comp) {
734 }
735
736 public void removeLayoutComponent(Component comp) {
737 }
738
739 public Dimension preferredLayoutSize(Container target) {
740 synchronized (target.getTreeLock()) {
741 int nmembers = target.getComponentCount();
742 /*
743 if (AS.S)ER.T (nmembers == 1,
744 "This layout manager can manage only 1 component.",
745 "preferredLayoutSize", this);
746 */
747 Component m = target.getComponent(0);
748 Dimension size = m.getPreferredSize();
749 size.setSize(target.getWidth() - (kGap * 2), size.height);
750 return size;
751 }
752 }
753
754 public Dimension minimumLayoutSize(Container target) {
755 return preferredLayoutSize(target);
756 }
757
758 public void layoutContainer(Container target) {
759 Insets insets = target.getInsets();
760 int nmembers = target.getComponentCount();
761 /*
762 if (AS.S)ER.T (nmembers == 1,
763 "This layout manager can manage only 1 component.",
764 "layoutContainer", this);
765 */
766 int vinsets = insets.top + insets.bottom;
767 int hinsets = insets.left + insets.right;
768
769 Dimension size = target.getSize();
770 //System.err.println("Target size: " + size);
771 //size.setSize(size.width, size.height);
772
773 JComponent m = (JComponent) target.getComponent(0);
774
775 Dimension msize = m.getPreferredSize();
776 msize.width = target.getWidth() - (kGap * 2);
777 m.setSize(msize);
778 int xcenter = (size.width - msize.width) / 2;
779 int ycenter = (size.height - msize.height) / 2;
780 m.setLocation(xcenter, ycenter);
781 }
782 }
783
784 /**
785 * Action that provides different icon size for both normal and plugin mode.
786 */
787 private abstract class DictAction extends AbstractAction {
788
789 /**
790 * @param aName action name.
791 */
792 DictAction(String aName) {
793 super(aName);
794 }
795
796 /**
797 * @param aName action name.
798 * @param aIcon logical name of the icon - "Back", "Forward", "Search",
799 * etc. For example
800 * <code>"Back"</code> is resolved to <code>"Back24.gif"</code>
801 * in normal (application) mode, and to <code>"Back16.gif"</code>
802 * in plugin mode.
803 */
804 DictAction(String aName, String aIcon) {
805 super(aName, createImageIcon(fPluginMode ?
806 aIcon + "16.gif" : aIcon + "24.gif"));
807 }
808 }
809
810 /** JButton that can not get focus. */
811 private static final class ToolButton extends JButton {
812
813 private ToolButton(Action anAction, String aToolTip) {
814 super(anAction);
815 setRequestFocusEnabled(false);
816 setToolTipText(aToolTip);
817 }
818
819 private ToolButton(Action anAction, String aToolTip, String aKeyStroke) {
820 super(anAction);
821 setRequestFocusEnabled(false);
822 setToolTipText(aToolTip);
823 KeyStroke key = KeyStroke.getKeyStroke(aKeyStroke);
824 InputMap input = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
825 input.put(key, aKeyStroke);
826 ActionMap action = getActionMap();
827 action.put(aKeyStroke, anAction);
828 }
829
830 private ToolButton(Icon anIcon, String aToolTip) {
831 super(anIcon);
832 setRequestFocusEnabled(false);
833 setToolTipText(aToolTip);
834 }
835
836 public boolean isFocusTraversable() {
837 return false;
838 }
839 }
840 }