您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

StandardDialog.java 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (c) 2006-2014 DMDirc Developers
  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.addons.ui_swing.dialogs;
  23. import com.dmdirc.ui.CoreUIUtils;
  24. import java.awt.Component;
  25. import java.awt.Dimension;
  26. import java.awt.Frame;
  27. import java.awt.Window;
  28. import java.awt.event.WindowAdapter;
  29. import java.awt.event.WindowEvent;
  30. import java.util.concurrent.Semaphore;
  31. import javax.swing.JButton;
  32. import javax.swing.JDialog;
  33. import javax.swing.SwingUtilities;
  34. /**
  35. * Provides common methods for dialogs.
  36. */
  37. public class StandardDialog extends JDialog {
  38. /** Serial version UID. */
  39. private static final long serialVersionUID = 1;
  40. /** Parent window. */
  41. private Window owner;
  42. /** The OK button for this frame. */
  43. private JButton okButton;
  44. /** The cancel button for this frame. */
  45. private JButton cancelButton;
  46. /**
  47. * Creates a new instance of StandardDialog.
  48. *
  49. * @param owner The frame that owns this dialog
  50. * @param modal Whether to display modally or not
  51. */
  52. public StandardDialog(final Frame owner, final boolean modal) {
  53. this(owner, modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);
  54. }
  55. /**
  56. * Creates a new instance of StandardDialog.
  57. *
  58. * @param owner The frame that owns this dialog
  59. * @param modal Whether to display modally or not
  60. */
  61. public StandardDialog(final Window owner, final ModalityType modal) {
  62. super(owner, modal);
  63. this.owner = owner;
  64. if (owner != null) {
  65. setIconImages(owner.getIconImages());
  66. }
  67. orderButtons(new JButton(), new JButton());
  68. setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  69. }
  70. /** {@inheritDoc} */
  71. @Override
  72. public void setTitle(final String title) {
  73. super.setTitle("DMDirc: " + title);
  74. }
  75. /**
  76. * Displays the dialog if it is not visible, otherwise requests focus.
  77. */
  78. public void displayOrRequestFocus() {
  79. displayOrRequestFocus(owner);
  80. }
  81. /**
  82. * Displays the dialog if it is not visible, otherwise requests focus. The parent window will
  83. * only be changed if the dialog has not been displayed.
  84. *
  85. * @param parent Parent window
  86. */
  87. public void displayOrRequestFocus(final Window parent) {
  88. if (isVisible()) {
  89. requestFocus();
  90. } else {
  91. display(parent);
  92. }
  93. }
  94. /**
  95. * Displays the dialog centering on the specified window.
  96. *
  97. * @param owner Window to center on
  98. */
  99. public void display(final Window owner) {
  100. this.owner = owner;
  101. display();
  102. }
  103. /**
  104. * Displays the dialog centering on the parent window.
  105. */
  106. public void display() {
  107. if (isVisible()) {
  108. return;
  109. }
  110. addWindowListener(new WindowAdapter() {
  111. /** {@inheritDoc} */
  112. @Override
  113. public void windowClosing(final WindowEvent e) {
  114. executeAction(getCancelButton());
  115. }
  116. });
  117. centreOnOwner();
  118. pack();
  119. centreOnOwner();
  120. setVisible(false);
  121. setVisible(true);
  122. }
  123. /**
  124. * Displays the dialog centering on the parent window, blocking until complete.
  125. */
  126. public void displayBlocking() {
  127. displayBlocking(owner);
  128. }
  129. /**
  130. * Displays the dialog centering on the specified window, blocking until complete.
  131. *
  132. * @param owner Window to center on
  133. */
  134. public void displayBlocking(final Component owner) {
  135. if (SwingUtilities.isEventDispatchThread()) {
  136. throw new IllegalStateException("Unable to display blocking dialog"
  137. + " in the EDT.");
  138. }
  139. final Semaphore semaphore = new Semaphore(0);
  140. SwingUtilities.invokeLater(new Runnable() {
  141. /** {@inheritDoc} */
  142. @Override
  143. public void run() {
  144. display();
  145. addWindowListener(new WindowAdapter() {
  146. @Override
  147. public void windowClosed(final WindowEvent e) {
  148. semaphore.release();
  149. }
  150. });
  151. }
  152. });
  153. semaphore.acquireUninterruptibly();
  154. }
  155. /**
  156. * Centres this dialog on its owner, or the screen if no owner is present.
  157. */
  158. public void centreOnOwner() {
  159. if (owner == null) {
  160. CoreUIUtils.centreWindow(this);
  161. } else {
  162. setLocationRelativeTo(owner);
  163. }
  164. }
  165. /**
  166. * Returns the window owner for this dialog.
  167. *
  168. * @return Parent window or null
  169. */
  170. public Component getParentWindow() {
  171. return owner;
  172. }
  173. /**
  174. * Sets the specified button up as the OK button.
  175. *
  176. * @param button The target button
  177. */
  178. protected void setOkButton(final JButton button) {
  179. okButton = button;
  180. button.setText("OK");
  181. button.setDefaultCapable(false);
  182. }
  183. /**
  184. * Sets the specified button up as the Cancel button.
  185. *
  186. * @param button The target button
  187. */
  188. protected void setCancelButton(final JButton button) {
  189. cancelButton = button;
  190. button.setText("Cancel");
  191. button.setDefaultCapable(false);
  192. }
  193. /**
  194. * Gets the left hand button for a dialog.
  195. *
  196. * @return left JButton
  197. */
  198. protected JButton getLeftButton() {
  199. if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
  200. return getOkButton();
  201. } else {
  202. return getCancelButton();
  203. }
  204. }
  205. /**
  206. * Gets the right hand button for a dialog.
  207. *
  208. * @return right JButton
  209. */
  210. protected JButton getRightButton() {
  211. if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
  212. return getCancelButton();
  213. } else {
  214. return getOkButton();
  215. }
  216. }
  217. /**
  218. * Orders the OK and Cancel buttons in an appropriate order for the current operating system.
  219. *
  220. * @param leftButton The left-most button
  221. * @param rightButton The right-most button
  222. */
  223. protected void orderButtons(final JButton leftButton,
  224. final JButton rightButton) {
  225. if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
  226. // Windows - put the OK button on the left
  227. setOkButton(leftButton);
  228. setCancelButton(rightButton);
  229. } else {
  230. // Everything else - adhere to usability guidelines and put it on
  231. // the right.
  232. setOkButton(rightButton);
  233. setCancelButton(leftButton);
  234. }
  235. leftButton.setPreferredSize(new Dimension(100, 25));
  236. rightButton.setPreferredSize(new Dimension(100, 25));
  237. leftButton.setMinimumSize(new Dimension(100, 25));
  238. rightButton.setMinimumSize(new Dimension(100, 25));
  239. }
  240. /**
  241. * Retrieves the OK button for this form.
  242. *
  243. * @return The form's OK button
  244. */
  245. public JButton getOkButton() {
  246. return okButton;
  247. }
  248. /**
  249. * Retrieves the Cancel button for this form.
  250. *
  251. * @return The form's cancel button
  252. */
  253. public JButton getCancelButton() {
  254. return cancelButton;
  255. }
  256. /**
  257. * Simulates the user clicking on the specified target button.
  258. *
  259. * @param target The button to use
  260. */
  261. public void executeAction(final JButton target) {
  262. if (target != null && target.isEnabled()) {
  263. target.doClick();
  264. }
  265. }
  266. /**
  267. * This method is called when enter is pressed anywhere in the dialog except on a button. By
  268. * default this method does nothing.
  269. *
  270. * @return Returns true if the key press has been handled and is not be be forwarded on by
  271. * default this is false
  272. */
  273. public boolean enterPressed() {
  274. return false;
  275. }
  276. /**
  277. * This method is called when ctrl + enter is pressed anywhere in the dialog. By default this
  278. * method presses the OK button.
  279. *
  280. * @return Returns true if the key press has been handled and is not be be forwarded on by
  281. * default this is true
  282. */
  283. public boolean ctrlEnterPressed() {
  284. executeAction(getOkButton());
  285. return true;
  286. }
  287. /**
  288. * This method is called when enter is pressed anywhere in the dialog except on a button. By
  289. * default this method presses the cancel button.
  290. *
  291. * @return Returns true if the key press has been handled and is not be be forwarded on by
  292. * default this is true
  293. */
  294. public boolean escapePressed() {
  295. executeAction(getCancelButton());
  296. return true;
  297. }
  298. }