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.

GeneralTabPanel.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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.dialogs.actionseditor;
  23. import java.awt.Dimension;
  24. import java.awt.event.ActionEvent;
  25. import java.awt.event.ActionListener;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. import javax.swing.DefaultComboBoxModel;
  29. import javax.swing.DefaultListModel;
  30. import javax.swing.JComboBox;
  31. import javax.swing.JLabel;
  32. import javax.swing.JList;
  33. import javax.swing.JOptionPane;
  34. import javax.swing.JPanel;
  35. import javax.swing.JScrollPane;
  36. import javax.swing.JTextField;
  37. import javax.swing.SpringLayout;
  38. import javax.swing.SwingUtilities;
  39. import com.dmdirc.actions.ActionManager;
  40. import com.dmdirc.actions.ActionType;
  41. import static com.dmdirc.ui.UIUtilities.SMALL_BORDER;
  42. import static com.dmdirc.ui.UIUtilities.layoutGrid;
  43. /**
  44. * General tab panel, name and trigger editing for the actions editor dialog.
  45. */
  46. public final class GeneralTabPanel extends JPanel implements ActionListener {
  47. /**
  48. * A version number for this class. It should be changed whenever the class
  49. * structure is changed (or anything else that would prevent serialized
  50. * objects being unserialized with the new class).
  51. */
  52. private static final long serialVersionUID = 1;
  53. /** Parent ActionsEditorDialog. */
  54. private ActionsEditorDialog owner;
  55. /** Name textfield. */
  56. private JTextField name;
  57. /** Primary trigger combobox. */
  58. private JComboBox trigger;
  59. /** Secondary trigger list. */
  60. private JList otherTriggers;
  61. /** Currently selected trigger. */
  62. private ActionType type;
  63. /**
  64. * Creates a new instance of GeneralTabPanel.
  65. *
  66. * @param owner Parent dialog
  67. */
  68. public GeneralTabPanel(final ActionsEditorDialog owner) {
  69. super();
  70. this.owner = owner;
  71. initComponents();
  72. addListeners();
  73. layoutComponents();
  74. }
  75. /** Initialises the components. */
  76. private void initComponents() {
  77. name = new JTextField();
  78. trigger = new JComboBox(new DefaultComboBoxModel());
  79. otherTriggers = new JList(new DefaultListModel());
  80. trigger.setRenderer(new ActionCellRenderer());
  81. otherTriggers.setCellRenderer(new ActionCellRenderer());
  82. ((DefaultComboBoxModel) trigger.getModel()).addElement("");
  83. for (ActionType thisType : ActionManager.getTypes().toArray(new ActionType[0])) {
  84. ((DefaultComboBoxModel) trigger.getModel()).addElement(thisType);
  85. }
  86. name.setPreferredSize(new Dimension(100, name.getFont().getSize()));
  87. trigger.setPreferredSize(new Dimension(100, trigger.getFont().getSize()));
  88. otherTriggers.setVisibleRowCount(2);
  89. otherTriggers.setEnabled(false);
  90. if (owner.getAction() == null) {
  91. return;
  92. }
  93. name.setText(owner.getAction().getName());
  94. trigger.setSelectedItem(owner.getAction().getTriggers()[0]);
  95. type = (ActionType) trigger.getSelectedItem();
  96. otherTriggers.setEnabled(true);
  97. populateOtherTriggers();
  98. selectOtherTriggers();
  99. }
  100. /** Populates the other triggers list with compatible types. */
  101. private void populateOtherTriggers() {
  102. otherTriggers.removeAll();
  103. if (trigger.getSelectedIndex() == 0) {
  104. otherTriggers.setEnabled(false);
  105. } else {
  106. for (ActionType thisType
  107. : ActionManager.getCompatibleTypes((ActionType) trigger.getSelectedItem())) {
  108. ((DefaultListModel) otherTriggers.getModel()).addElement(thisType);
  109. }
  110. }
  111. otherTriggers.repaint();
  112. }
  113. /** Selects other triggers that are part of this action. */
  114. private void selectOtherTriggers() {
  115. for (ActionType thisType : owner.getAction().getTriggers()) {
  116. final int index = ((DefaultListModel) otherTriggers.getModel()).indexOf(thisType);
  117. if (index != -1) {
  118. otherTriggers.getSelectionModel().addSelectionInterval(index, index);
  119. }
  120. }
  121. }
  122. /** Adds listeners to the components. */
  123. private void addListeners() {
  124. trigger.addActionListener(this);
  125. }
  126. /** Lays out components. */
  127. private void layoutComponents() {
  128. add(new JLabel("Name: "));
  129. add(name);
  130. add(new JLabel("Primary trigger: "));
  131. add(trigger);
  132. add(new JLabel("Additional triggers: "));
  133. add(new JScrollPane(otherTriggers));
  134. this.setLayout(new SpringLayout());
  135. layoutGrid(this, 3,
  136. 2, SMALL_BORDER, SMALL_BORDER, SMALL_BORDER, SMALL_BORDER);
  137. }
  138. /**
  139. * Returns the name for this panel.
  140. *
  141. * @return Action name
  142. */
  143. public String getName() {
  144. return name.getText();
  145. }
  146. /**
  147. * Returns the primary trigger for this panel.
  148. *
  149. * @return Primary trigger
  150. */
  151. public ActionType getTrigger() {
  152. if (trigger.getSelectedIndex() == 0) {
  153. return null;
  154. }
  155. return (ActionType) trigger.getSelectedItem();
  156. }
  157. /**
  158. * Returns the triggers for this panel.
  159. *
  160. * @return Trigger list
  161. */
  162. public List<ActionType> getTriggers() {
  163. final List<ActionType> triggers = new ArrayList<ActionType>();
  164. if (trigger.getSelectedIndex() == 0) {
  165. return null;
  166. }
  167. triggers.add((ActionType) trigger.getSelectedItem());
  168. for (Object thisType : otherTriggers.getSelectedValues()) {
  169. triggers.add((ActionType) thisType);
  170. }
  171. return triggers;
  172. }
  173. /** {@inheritDoc}. */
  174. public void actionPerformed(final ActionEvent event) {
  175. if (event.getSource() == trigger) {
  176. SwingUtilities.invokeLater(new Runnable() {
  177. public void run() {
  178. handleTriggerChange();
  179. }
  180. });
  181. }
  182. }
  183. /** Prompts the user for confirmation of type change. */
  184. private void handleTriggerChange() {
  185. boolean compatible = false;
  186. if (trigger.getSelectedIndex() != 0) {
  187. owner.getOkButton().setEnabled(true);
  188. if (owner.getTrigger().getType().getArgNames().length > 0) {
  189. owner.setNewConditionButtonState(true);
  190. }
  191. } else {
  192. owner.getOkButton().setEnabled(false);
  193. owner.setNewConditionButtonState(false);
  194. }
  195. if (type == null || trigger.getSelectedIndex() == 0) {
  196. compatible = false;
  197. } else if (ActionManager.getCompatibleTypes(type).contains(trigger.getSelectedItem())
  198. || trigger.getSelectedItem() == type) {
  199. compatible = true;
  200. }
  201. if (compatible) {
  202. populateOtherTriggers();
  203. selectOtherTriggers();
  204. type = (ActionType) trigger.getSelectedItem();
  205. } else if (owner.getConditionCount() > 0) {
  206. final int response = JOptionPane.showConfirmDialog(this,
  207. "Changing to this trigger will remove your existing "
  208. + "conditions. Are you sure?", "Incompatible triggers",
  209. JOptionPane.OK_CANCEL_OPTION);
  210. if (response == JOptionPane.OK_OPTION) {
  211. type = (ActionType) trigger.getSelectedItem();
  212. owner.clearConditions();
  213. } else {
  214. trigger.setSelectedItem(type);
  215. }
  216. }
  217. }
  218. }