You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MainFrame.java 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /*
  2. * Copyright (c) 2006-2007 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.ui;
  23. import com.dmdirc.Config;
  24. import com.dmdirc.FrameContainer;
  25. import com.dmdirc.Main;
  26. import com.dmdirc.ServerManager;
  27. import com.dmdirc.actions.ActionManager;
  28. import com.dmdirc.actions.CoreActionType;
  29. import com.dmdirc.logger.ErrorLevel;
  30. import com.dmdirc.logger.Logger;
  31. import com.dmdirc.ui.components.Frame;
  32. import com.dmdirc.ui.components.StatusBar;
  33. import com.dmdirc.ui.dialogs.AboutDialog;
  34. import com.dmdirc.ui.dialogs.ActionsManagerDialog;
  35. import com.dmdirc.ui.dialogs.NewServerDialog;
  36. import com.dmdirc.ui.dialogs.PluginDialog;
  37. import com.dmdirc.ui.dialogs.PreferencesDialog;
  38. import com.dmdirc.ui.dialogs.ProfileEditorDialog;
  39. import com.dmdirc.ui.framemanager.FrameManager;
  40. import com.dmdirc.ui.framemanager.FramemanagerPosition;
  41. import com.dmdirc.ui.framemanager.MainFrameManager;
  42. import com.dmdirc.ui.framemanager.windowmenu.WindowMenuFrameManager;
  43. import com.dmdirc.ui.interfaces.Window;
  44. import static com.dmdirc.ui.UIUtilities.SMALL_BORDER;
  45. import java.awt.BorderLayout;
  46. import java.awt.Color;
  47. import java.awt.Dimension;
  48. import java.awt.Font;
  49. import java.awt.GraphicsConfiguration;
  50. import java.awt.GraphicsDevice;
  51. import java.awt.Insets;
  52. import java.awt.MouseInfo;
  53. import java.awt.PointerInfo;
  54. import java.awt.Rectangle;
  55. import java.awt.event.ActionEvent;
  56. import java.awt.event.ActionListener;
  57. import java.awt.event.KeyEvent;
  58. import java.awt.event.WindowEvent;
  59. import java.awt.event.WindowListener;
  60. import java.beans.PropertyVetoException;
  61. import java.net.URL;
  62. import java.util.Collection;
  63. import java.util.HashMap;
  64. import java.util.Map;
  65. import javax.swing.AbstractAction;
  66. import javax.swing.BorderFactory;
  67. import javax.swing.ImageIcon;
  68. import javax.swing.JComponent;
  69. import javax.swing.JDesktopPane;
  70. import javax.swing.JFrame;
  71. import javax.swing.JInternalFrame;
  72. import javax.swing.JMenu;
  73. import javax.swing.JMenuBar;
  74. import javax.swing.JMenuItem;
  75. import javax.swing.JPanel;
  76. import javax.swing.JSeparator;
  77. import javax.swing.JSplitPane;
  78. import javax.swing.KeyStroke;
  79. import javax.swing.UIManager;
  80. import javax.swing.UIManager.LookAndFeelInfo;
  81. import javax.swing.UnsupportedLookAndFeelException;
  82. import javax.swing.WindowConstants;
  83. import javax.swing.border.EtchedBorder;
  84. import javax.swing.plaf.FontUIResource;
  85. /**
  86. * The main application frame.
  87. */
  88. public final class MainFrame extends JFrame implements WindowListener,
  89. ActionListener {
  90. /**
  91. * A version number for this class. It should be changed whenever the class
  92. * structure is changed (or anything else that would prevent serialized
  93. * objects being unserialized with the new class).
  94. */
  95. private static final long serialVersionUID = 7;
  96. /**
  97. * The number of pixels each new internal frame is offset by.
  98. */
  99. private static final int FRAME_OPENING_OFFSET = 30;
  100. /**
  101. * Singleton instance of MainFrame.
  102. */
  103. private static MainFrame me;
  104. /**
  105. * Whether the internal frames are maximised or not.
  106. */
  107. private boolean maximised;
  108. /**
  109. * The current number of pixels to displace new frames in the X direction.
  110. */
  111. private int xOffset;
  112. /**
  113. * The current number of pixels to displace new frames in the Y direction.
  114. */
  115. private int yOffset;
  116. /**
  117. * The main application icon.
  118. */
  119. private final ImageIcon imageIcon;
  120. /**
  121. * The frame manager that's being used.
  122. */
  123. private final MainFrameManager mainFrameManager;
  124. /**
  125. * The window menu frame manager that's being used.
  126. */
  127. private final WindowMenuFrameManager windowListFrameManager;
  128. /** Dekstop pane. */
  129. private JDesktopPane desktopPane;
  130. /** Plugin menu item. */
  131. private JMenu pluginsMenu;
  132. /** Windows menu item. */
  133. private JMenu windowsMenu;
  134. /** Main panel. */
  135. private JPanel frameManagerPanel;
  136. /** Add server menu item. */
  137. private JMenuItem miAddServer;
  138. /** Preferences menu item. */
  139. private JMenuItem miPreferences;
  140. /** Toggle state menu item. */
  141. private JMenuItem toggleStateMenuItem;
  142. /** status bar. */
  143. private StatusBar statusBar;
  144. /** Frame manager position. */
  145. private FramemanagerPosition position;
  146. /**
  147. * Creates new form MainFrame.
  148. */
  149. private MainFrame() {
  150. super();
  151. windowListFrameManager = new WindowMenuFrameManager();
  152. mainFrameManager = new MainFrameManager();
  153. initComponents();
  154. initKeyHooks();
  155. setTitle(getTitlePrefix());
  156. // Load an icon
  157. final ClassLoader cldr = this.getClass().getClassLoader();
  158. final URL imageURL = cldr.getResource("com/dmdirc/res/icon.png");
  159. imageIcon = new ImageIcon(imageURL);
  160. setIconImage(imageIcon.getImage());
  161. mainFrameManager.setParent(frameManagerPanel);
  162. // Get the Location of the mouse pointer
  163. final PointerInfo myPointerInfo = MouseInfo.getPointerInfo();
  164. // Get the Device (screen) the mouse pointer is on
  165. final GraphicsDevice myDevice = myPointerInfo.getDevice();
  166. // Get the configuration for the device
  167. final GraphicsConfiguration myGraphicsConfig = myDevice.getDefaultConfiguration();
  168. // Get the bounds of the device
  169. final Rectangle gcBounds = myGraphicsConfig.getBounds();
  170. // Calculate the center of the screen
  171. // gcBounds.x and gcBounds.y give the co ordinates where the screen
  172. // starts. gcBounds.width and gcBounds.height return the size in pixels
  173. // of the screen.
  174. final int xPos = gcBounds.x + ((gcBounds.width - getWidth()) / 2);
  175. final int yPos = gcBounds.y + ((gcBounds.height - getHeight()) / 2);
  176. // Set the location of the window
  177. setLocation(xPos, yPos);
  178. setVisible(true);
  179. miAddServer.addActionListener(new ActionListener() {
  180. public void actionPerformed(final ActionEvent actionEvent) {
  181. NewServerDialog.showNewServerDialog();
  182. }
  183. });
  184. miPreferences.addActionListener(new ActionListener() {
  185. public void actionPerformed(final ActionEvent actionEvent) {
  186. PreferencesDialog.showPreferencesDialog();
  187. }
  188. });
  189. toggleStateMenuItem.addActionListener(new ActionListener() {
  190. public void actionPerformed(final ActionEvent actionEvent) {
  191. try {
  192. getActiveFrame().setMaximum(!getActiveFrame().isMaximum());
  193. } catch (PropertyVetoException ex) {
  194. Logger.error(ErrorLevel.WARNING, "Unable to maximise window", ex);
  195. }
  196. }
  197. });
  198. addWindowListener(this);
  199. checkWindowState();
  200. }
  201. /**
  202. * Returns the singleton instance of MainFrame.
  203. * @return MainFrame instance
  204. */
  205. public static synchronized MainFrame getMainFrame() {
  206. if (me == null) {
  207. me = new MainFrame();
  208. }
  209. return me;
  210. }
  211. /**
  212. * Indicates whether the main frame has been initialised or not.
  213. * @return True iff the main frame exists
  214. */
  215. public static boolean hasMainFrame() {
  216. return me != null;
  217. }
  218. /**
  219. * Adds the specified window as a child of the main frame.
  220. *
  221. * @param window the window to be added
  222. */
  223. public void addChild(final Window window) {
  224. final JInternalFrame frame = (JInternalFrame) window;
  225. // Add the frame
  226. desktopPane.add(frame);
  227. // Make sure it'll fit with our offsets
  228. if (frame.getWidth() + xOffset > desktopPane.getWidth()) {
  229. xOffset = 0;
  230. }
  231. if (frame.getHeight() + yOffset > desktopPane.getHeight()) {
  232. yOffset = 0;
  233. }
  234. // Position the frame
  235. frame.setLocation(xOffset, yOffset);
  236. frame.moveToFront();
  237. // Increase the offsets
  238. xOffset += FRAME_OPENING_OFFSET;
  239. yOffset += FRAME_OPENING_OFFSET;
  240. }
  241. /**
  242. * Removes the specified window from our desktop pane.
  243. *
  244. * @param window The window to be removed
  245. */
  246. public void delChild(final Window window) {
  247. desktopPane.remove((JInternalFrame) window);
  248. if (desktopPane.getAllFrames().length == 0) {
  249. setTitle(getTitlePrefix());
  250. }
  251. }
  252. /**
  253. * Sets the active internal frame to the one specified.
  254. * @param frame The frame to be activated
  255. */
  256. public void setActiveFrame(final Window frame) {
  257. try {
  258. ((JInternalFrame) frame).setVisible(true);
  259. ((JInternalFrame) frame).setIcon(false);
  260. ((JInternalFrame) frame).moveToFront();
  261. ((JInternalFrame) frame).setSelected(true);
  262. } catch (PropertyVetoException ex) {
  263. Logger.error(ErrorLevel.ERROR, "Unable to set active window", ex);
  264. }
  265. if (maximised) {
  266. setTitle(getTitlePrefix() + " - " + frame.getTitle());
  267. }
  268. ActionManager.processEvent(CoreActionType.CLIENT_FRAME_CHANGED, null, frame.getContainer());
  269. }
  270. /**
  271. * Retrieves the frame manager that's currently in use.
  272. * @return The current frame manager
  273. */
  274. public FrameManager getFrameManager() {
  275. return mainFrameManager;
  276. }
  277. /**
  278. * Returns the size of the frame manager.
  279. *
  280. * @return Frame manager size.
  281. */
  282. public int getFrameManagerSize() {
  283. if (position == FramemanagerPosition.LEFT
  284. || position == FramemanagerPosition.RIGHT) {
  285. return frameManagerPanel.getWidth();
  286. } else {
  287. return frameManagerPanel.getHeight();
  288. }
  289. }
  290. /**
  291. * Retrieves the application icon.
  292. * @return The application icon
  293. */
  294. public ImageIcon getIcon() {
  295. return imageIcon;
  296. }
  297. /**
  298. * Returns the window that is currently active.
  299. * @return The active window
  300. */
  301. public Window getActiveFrame() {
  302. if (desktopPane.getSelectedFrame() instanceof Window) {
  303. return (Window) desktopPane.getSelectedFrame();
  304. } else {
  305. return null;
  306. }
  307. }
  308. /**
  309. * Adds a JMenuItem to the plugin menu.
  310. * @param menuItem The menu item to be added.
  311. */
  312. public void addPluginMenu(final JMenuItem menuItem) {
  313. if (pluginsMenu.getComponents().length == 1) {
  314. final JSeparator seperator = new JSeparator();
  315. pluginsMenu.add(seperator);
  316. }
  317. pluginsMenu.add(menuItem);
  318. }
  319. /**
  320. * Removes a JMenuItem from the plugin menu.
  321. * @param menuItem The menu item to be removed.
  322. */
  323. public void removePluginMenu(final JMenuItem menuItem) {
  324. pluginsMenu.remove(menuItem);
  325. if (pluginsMenu.getComponents().length == 2) {
  326. pluginsMenu.remove(2);
  327. }
  328. }
  329. /**
  330. * Sets whether or not the internal frame state is currently maximised.
  331. * @param max whether the frame is maxomised
  332. */
  333. public void setMaximised(final boolean max) {
  334. maximised = max;
  335. if (max) {
  336. if (getActiveFrame() != null) {
  337. setTitle(getTitlePrefix() + " - " + getActiveFrame().getTitle());
  338. }
  339. } else {
  340. setTitle(getTitlePrefix());
  341. for (JInternalFrame frame : desktopPane.getAllFrames()) {
  342. try {
  343. frame.setMaximum(false);
  344. } catch (PropertyVetoException ex) {
  345. Logger.error(ErrorLevel.ERROR, "Unable to maximise window", ex);
  346. }
  347. }
  348. }
  349. checkWindowState();
  350. }
  351. /**
  352. * Returns a prefix for use in the titlebar. Includes the version number
  353. * if the config option is set.
  354. * @return Titlebar prefix
  355. */
  356. public String getTitlePrefix() {
  357. if (Config.getOptionBool("ui", "showversion")) {
  358. return "DMDirc " + Main.VERSION;
  359. } else {
  360. return "DMDirc";
  361. }
  362. }
  363. /**
  364. * Gets whether or not the internal frame state is currently maximised.
  365. * @return True iff frames should be maximised, false otherwise
  366. */
  367. public boolean getMaximised() {
  368. return maximised;
  369. }
  370. /**
  371. * Checks the current state of the internal frames, and configures the
  372. * window menu to behave appropriately.
  373. */
  374. private void checkWindowState() {
  375. if (getActiveFrame() == null) {
  376. toggleStateMenuItem.setEnabled(false);
  377. return;
  378. }
  379. toggleStateMenuItem.setEnabled(true);
  380. if (maximised) {
  381. toggleStateMenuItem.setText("Restore");
  382. toggleStateMenuItem.setMnemonic('r');
  383. toggleStateMenuItem.invalidate();
  384. } else {
  385. toggleStateMenuItem.setText("Maximise");
  386. toggleStateMenuItem.setMnemonic('m');
  387. toggleStateMenuItem.invalidate();
  388. }
  389. }
  390. /**
  391. * Returns the status bar instance.
  392. *
  393. * @return StatusBar instance
  394. */
  395. public StatusBar getStatusBar() {
  396. return statusBar;
  397. }
  398. /** {@inheritDoc}. */
  399. public void windowOpened(final WindowEvent windowEvent) {
  400. //ignore
  401. }
  402. /**
  403. * Called when the window is closing. Saves the config and has all servers
  404. * disconnect with the default close method
  405. * @param windowEvent The event associated with this callback
  406. */
  407. public void windowClosing(final WindowEvent windowEvent) {
  408. ServerManager.getServerManager().closeAll(Config.getOption("general", "closemessage"));
  409. quit();
  410. }
  411. /** {@inheritDoc}. */
  412. public void windowClosed(final WindowEvent windowEvent) {
  413. //ignore
  414. }
  415. /** {@inheritDoc}. */
  416. public void windowIconified(final WindowEvent windowEvent) {
  417. //ignore
  418. }
  419. /** {@inheritDoc}. */
  420. public void windowDeiconified(final WindowEvent windowEvent) {
  421. //ignore
  422. }
  423. /** {@inheritDoc}. */
  424. public void windowActivated(final WindowEvent windowEvent) {
  425. //ignore
  426. }
  427. /** {@inheritDoc}. */
  428. public void windowDeactivated(final WindowEvent windowEvent) {
  429. //ignore
  430. }
  431. /**
  432. * Initialises the components for this frame.
  433. */
  434. private void initComponents() {
  435. final JSplitPane mainSplitPane = new JSplitPane();
  436. frameManagerPanel = new JPanel();
  437. desktopPane = new JDesktopPane();
  438. desktopPane.setBackground(new Color(238, 238, 238));
  439. statusBar = new StatusBar();
  440. initSplitPane(mainSplitPane);
  441. initMenuBar();
  442. setPreferredSize(new Dimension(800, 600));
  443. getContentPane().setLayout(new BorderLayout(SMALL_BORDER, SMALL_BORDER));
  444. getContentPane().add(mainSplitPane, BorderLayout.CENTER);
  445. getContentPane().add(statusBar, BorderLayout.SOUTH);
  446. setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
  447. setTitle("DMDirc");
  448. frameManagerPanel.setBorder(
  449. BorderFactory.createEmptyBorder(0, SMALL_BORDER, 0, 0));
  450. desktopPane.setBorder(
  451. BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
  452. pack();
  453. }
  454. /**
  455. * Initialises the split pane.
  456. *
  457. * @param mainSplitPane JSplitPane to initialise
  458. */
  459. private void initSplitPane(final JSplitPane mainSplitPane) {
  460. mainSplitPane.setBorder(null);
  461. mainSplitPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0,
  462. SMALL_BORDER));
  463. mainSplitPane.setDividerSize(SMALL_BORDER);
  464. mainSplitPane.setOneTouchExpandable(false);
  465. position = FramemanagerPosition.getPosition(
  466. Config.getOption("ui", "framemanagerPosition"));
  467. if (position == FramemanagerPosition.UNKNOWN) {
  468. position = FramemanagerPosition.LEFT;
  469. }
  470. if (!mainFrameManager.canPositionVertically()
  471. && (position == FramemanagerPosition.LEFT
  472. || position == FramemanagerPosition.RIGHT)) {
  473. position = FramemanagerPosition.BOTTOM;
  474. }
  475. if (!mainFrameManager.canPositionHorizontally()
  476. && (position == FramemanagerPosition.TOP
  477. || position == FramemanagerPosition.BOTTOM)) {
  478. position = FramemanagerPosition.LEFT;
  479. }
  480. switch (position) {
  481. case TOP:
  482. mainSplitPane.setTopComponent(frameManagerPanel);
  483. mainSplitPane.setBottomComponent(desktopPane);
  484. mainSplitPane.setResizeWeight(0.0);
  485. mainSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  486. frameManagerPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE,
  487. Config.getOptionInt("ui", "frameManagerSize", 50)));
  488. frameManagerPanel.setMinimumSize(new Dimension(Integer.MAX_VALUE, 50));
  489. desktopPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  490. desktopPane.setMinimumSize(new Dimension(Integer.MAX_VALUE, 300));
  491. break;
  492. case LEFT:
  493. mainSplitPane.setLeftComponent(frameManagerPanel);
  494. mainSplitPane.setRightComponent(desktopPane);
  495. mainSplitPane.setResizeWeight(0.0);
  496. mainSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
  497. frameManagerPanel.setPreferredSize(new Dimension(
  498. Config.getOptionInt("ui", "frameManagerSize", 150),
  499. Integer.MAX_VALUE));
  500. frameManagerPanel.setMinimumSize(new Dimension(150, Integer.MAX_VALUE));
  501. desktopPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  502. desktopPane.setMinimumSize(new Dimension(300, Integer.MAX_VALUE));
  503. break;
  504. case BOTTOM:
  505. mainSplitPane.setTopComponent(desktopPane);
  506. mainSplitPane.setBottomComponent(frameManagerPanel);
  507. mainSplitPane.setResizeWeight(1.0);
  508. mainSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  509. frameManagerPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE,
  510. Config.getOptionInt("ui", "frameManagerSize", 50)));
  511. frameManagerPanel.setMinimumSize(new Dimension(Integer.MAX_VALUE,
  512. 50));
  513. desktopPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  514. desktopPane.setMinimumSize(new Dimension(Integer.MAX_VALUE, 300));
  515. break;
  516. case RIGHT:
  517. mainSplitPane.setLeftComponent(desktopPane);
  518. mainSplitPane.setRightComponent(frameManagerPanel);
  519. mainSplitPane.setResizeWeight(1.0);
  520. mainSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
  521. frameManagerPanel.setPreferredSize(new Dimension(
  522. Config.getOptionInt("ui", "frameManagerSize", 50),
  523. Integer.MAX_VALUE));
  524. frameManagerPanel.setMinimumSize(new Dimension(50, Integer.MAX_VALUE));
  525. desktopPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  526. desktopPane.setMinimumSize(new Dimension(300, Integer.MAX_VALUE));
  527. break;
  528. default:
  529. break;
  530. }
  531. mainSplitPane.setContinuousLayout(true);
  532. }
  533. /** Initialises the key hooks. */
  534. private void initKeyHooks() {
  535. final KeyStroke[] keyStrokes = new KeyStroke[12];
  536. keyStrokes[0] = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0);
  537. keyStrokes[1] = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0);
  538. keyStrokes[2] = KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0);
  539. keyStrokes[3] = KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0);
  540. keyStrokes[4] = KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0);
  541. keyStrokes[5] = KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0);
  542. keyStrokes[6] = KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0);
  543. keyStrokes[7] = KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0);
  544. keyStrokes[8] = KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0);
  545. keyStrokes[9] = KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0);
  546. keyStrokes[10] = KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0);
  547. keyStrokes[11] = KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0);
  548. for (final KeyStroke keyStroke : keyStrokes) {
  549. getRootPane().getActionMap().put(
  550. KeyEvent.getKeyText(keyStroke.getKeyCode()) + "Action",
  551. new AbstractAction(
  552. KeyEvent.getKeyText(keyStroke.getKeyCode()) + "Action") {
  553. private static final long serialVersionUID = 5;
  554. public void actionPerformed(final ActionEvent evt) {
  555. ActionManager.processEvent(CoreActionType.CLIENT_FKEY_PRESSED,
  556. null, KeyStroke.getKeyStroke(keyStroke.getKeyCode(),
  557. evt.getModifiers()));
  558. }
  559. }
  560. );
  561. getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
  562. KeyStroke.getKeyStroke(keyStroke.getKeyCode(), 0),
  563. KeyEvent.getKeyText(keyStroke.getKeyCode()) + "Action");
  564. }
  565. }
  566. /** Initialises the menu bar. */
  567. private void initMenuBar() {
  568. final JMenuBar menuBar = new JMenuBar();
  569. JMenuItem menuItem;
  570. final JMenu fileMenu = new JMenu();
  571. miAddServer = new JMenuItem();
  572. miPreferences = new JMenuItem();
  573. final JMenu settingsMenu = new JMenu();
  574. final JMenu helpMenu = new JMenu();
  575. toggleStateMenuItem = new JMenuItem();
  576. settingsMenu.setText("Settings");
  577. settingsMenu.setMnemonic('s');
  578. fileMenu.setMnemonic('f');
  579. fileMenu.setText("File");
  580. miAddServer.setText("New Server...");
  581. miAddServer.setMnemonic('n');
  582. fileMenu.add(miAddServer);
  583. miPreferences.setText("Preferences");
  584. miPreferences.setMnemonic('p');
  585. settingsMenu.add(miPreferences);
  586. menuItem = new JMenuItem();
  587. menuItem.setMnemonic('m');
  588. menuItem.setText("Profile Manager");
  589. menuItem.setActionCommand("Profile");
  590. menuItem.addActionListener(this);
  591. settingsMenu.add(menuItem);
  592. menuItem = new JMenuItem();
  593. menuItem.setMnemonic('a');
  594. menuItem.setText("Actions Manager");
  595. menuItem.setActionCommand("Actions");
  596. menuItem.addActionListener(this);
  597. settingsMenu.add(menuItem);
  598. menuItem = new JMenuItem();
  599. menuItem.setMnemonic('x');
  600. menuItem.setText("Exit");
  601. menuItem.setActionCommand("Exit");
  602. menuItem.addActionListener(this);
  603. fileMenu.add(menuItem);
  604. populateWindowMenu(new HashMap<FrameContainer, JMenuItem>());
  605. helpMenu.setMnemonic('h');
  606. helpMenu.setText("Help");
  607. menuItem = new JMenuItem();
  608. menuItem.setMnemonic('a');
  609. menuItem.setText("About");
  610. menuItem.setActionCommand("About");
  611. menuItem.addActionListener(this);
  612. helpMenu.add(menuItem);
  613. pluginsMenu = new JMenu("Plugins");
  614. pluginsMenu.setMnemonic('p');
  615. settingsMenu.add(pluginsMenu);
  616. menuItem = new JMenuItem();
  617. menuItem.setMnemonic('m');
  618. menuItem.setText("Manage plugins");
  619. menuItem.setActionCommand("ManagePlugins");
  620. menuItem.addActionListener(this);
  621. pluginsMenu.add(menuItem);
  622. menuBar.add(fileMenu);
  623. menuBar.add(settingsMenu);
  624. menuBar.add(windowsMenu);
  625. menuBar.add(helpMenu);
  626. setJMenuBar(menuBar);
  627. }
  628. /**
  629. * Initialises the window menu.
  630. *
  631. * @param windows Map of windows
  632. */
  633. public void populateWindowMenu(final Map<FrameContainer, JMenuItem> windows) {
  634. if (windowsMenu == null) {
  635. windowsMenu = new JMenu();
  636. }
  637. if (windowsMenu.isShowing()) {
  638. windowsMenu.setSelected(false);
  639. windowsMenu.setPopupMenuVisible(false);
  640. }
  641. windowsMenu.removeAll();
  642. JMenuItem menuItem;
  643. windowsMenu.setMnemonic('w');
  644. windowsMenu.setText("Window");
  645. windowsMenu.add(toggleStateMenuItem);
  646. menuItem = new JMenuItem();
  647. menuItem.setMnemonic('n');
  648. menuItem.setText("Minimise");
  649. menuItem.setActionCommand("Minimise");
  650. menuItem.addActionListener(this);
  651. windowsMenu.add(menuItem);
  652. menuItem = new JMenuItem();
  653. menuItem.setMnemonic('c');
  654. menuItem.setText("Close");
  655. menuItem.setActionCommand("Close");
  656. menuItem.addActionListener(this);
  657. windowsMenu.add(menuItem);
  658. menuItem = new JMenuItem();
  659. menuItem.setMnemonic('a');
  660. menuItem.setText("Close all");
  661. menuItem.setActionCommand("CloseAll");
  662. menuItem.addActionListener(this);
  663. windowsMenu.add(menuItem);
  664. windowsMenu.addSeparator();
  665. int i = 0;
  666. final Collection<JMenuItem> windowsValues = windows.values();
  667. for (JMenuItem mi : windowsValues) {
  668. if (i > 34) {
  669. windowsMenu.add(new JMenuItem("..."));
  670. break;
  671. }
  672. windowsMenu.add(mi);
  673. i++;
  674. }
  675. }
  676. /** Quits the client. */
  677. public void quit() {
  678. Config.setOption("ui", "frameManagerSize",
  679. String.valueOf(MainFrame.getMainFrame().getFrameManagerSize()));
  680. Main.quit();
  681. }
  682. /**
  683. * {@inheritDoc}.
  684. */
  685. public void actionPerformed(final ActionEvent e) {
  686. if (e.getActionCommand().equals("About")) {
  687. AboutDialog.showAboutDialog();
  688. } else if (e.getActionCommand().equals("Profile")) {
  689. ProfileEditorDialog.showActionsManagerDialog();
  690. } else if (e.getActionCommand().equals("Exit")) {
  691. quit();
  692. } else if (e.getActionCommand().equals("ManagePlugins")) {
  693. PluginDialog.showPluginDialog();
  694. } else if (e.getActionCommand().equals("Actions")) {
  695. ActionsManagerDialog.showActionsManagerDialog();
  696. } else if (e.getActionCommand().equals("Minimise")) {
  697. ((Frame) MainFrame.getMainFrame().getActiveFrame()).minimise();
  698. } else if (e.getActionCommand().equals("Close")) {
  699. ((Frame) MainFrame.getMainFrame().getActiveFrame()).close();
  700. } else if (e.getActionCommand().equals("CloseAll")) {
  701. ServerManager.getServerManager().closeAll();
  702. }
  703. }
  704. /** Initialises UI Settings. */
  705. public static void initUISettings() {
  706. // For this to work it *HAS* to be before anything else UI related.
  707. if (Config.hasOption("ui", "antialias")) {
  708. final String aaSetting = Config.getOption("ui", "antialias");
  709. System.setProperty("awt.useSystemAAFontSettings", aaSetting);
  710. System.setProperty("swing.aatext", aaSetting);
  711. }
  712. final String lnfName = getLookAndFeel(Config.getOption("ui", "lookandfeel"));
  713. try {
  714. UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
  715. final FontUIResource font = new FontUIResource("Dialog", Font.PLAIN , 12);
  716. UIManager.put("Label.font", font);
  717. UIManager.put("TextField.font", font);
  718. UIManager.put("PasswordField.font", font);
  719. UIManager.put("Button.font", font);
  720. UIManager.put("RadioButton.font", font);
  721. UIManager.put("CheckBox.font", font);
  722. UIManager.put("ComboBox.font", font);
  723. UIManager.put("Menu.font", font);
  724. UIManager.put("List.font", font);
  725. UIManager.put("MenuItem.font", font);
  726. UIManager.put("Panel.font", font);
  727. UIManager.put("TitledBorder.font", font);
  728. UIManager.put("TabbedPane.font", font);
  729. UIManager.put("Tree.font", font);
  730. UIManager.put("InternalFrame.titleFont", font);
  731. UIManager.put("EditorPane.font", font);
  732. UIManager.put("swing.boldMetal", false);
  733. UIManager.put("InternalFrame.useTaskBar", false);
  734. UIManager.put("SplitPaneDivider.border", BorderFactory.createEmptyBorder());
  735. UIManager.put("TabbedPane.contentBorderInsets", new Insets(1, 1, 1, 1));
  736. UIManager.put("Tree.scrollsOnExpand", true);
  737. UIManager.put("Tree.scrollsHorizontallyAndVertically", true);
  738. UIManager.put("Tree.dropCellBackground", Color.WHITE);
  739. UIManager.put("Tree.selectionBackground", Color.WHITE);
  740. UIManager.put("Tree.textBackground", Color.WHITE);
  741. UIManager.put("Tree.selectionBorderColor", Color.WHITE);
  742. UIManager.put("Tree.drawsFocusBorder", false);
  743. UIManager.put("Tree.drawHorizontalLines", true);
  744. UIManager.put("Tree.drawVerticalLines", true);
  745. UIManager.put("Tree.background", Color.WHITE);
  746. if (Config.hasOption("ui", "lookandfeel") && lnfName.length() != 0) {
  747. UIManager.setLookAndFeel(lnfName);
  748. }
  749. } catch (InstantiationException ex) {
  750. Logger.error(ErrorLevel.ERROR, "Unable to set look and feel: " + lnfName, ex);
  751. } catch (ClassNotFoundException ex) {
  752. Logger.error(ErrorLevel.ERROR, "Look and feel not available: " + lnfName, ex);
  753. } catch (UnsupportedLookAndFeelException ex) {
  754. Logger.error(ErrorLevel.ERROR, "Look and feel not available: " + lnfName, ex);
  755. } catch (IllegalAccessException ex) {
  756. Logger.error(ErrorLevel.ERROR, "Unable to set look and feel: " + lnfName, ex);
  757. }
  758. }
  759. /**
  760. * Returns the class name of the look and feel from its display name.
  761. *
  762. * @param displayName Look and feel display name
  763. *
  764. * @return Look and feel class name or a zero length string
  765. */
  766. private static String getLookAndFeel(final String displayName) {
  767. final StringBuilder classNameBuilder = new StringBuilder();
  768. if (displayName != null && !"".equals(displayName)) {
  769. for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
  770. if (laf.getName().equals(displayName)) {
  771. classNameBuilder.setLength(0);
  772. classNameBuilder.append(laf.getClassName());
  773. break;
  774. }
  775. }
  776. }
  777. return classNameBuilder.toString();
  778. }
  779. }