Gridarta Editor
PluginManager.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2023 The Gridarta Developers.
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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.gui.dialog.plugin;
21 
22 import java.awt.BorderLayout;
23 import java.awt.CardLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Container;
27 import java.awt.GridLayout;
28 import java.util.HashMap;
29 import java.util.Map;
30 import javax.swing.AbstractListModel;
31 import javax.swing.JButton;
32 import javax.swing.JFrame;
33 import javax.swing.JList;
34 import javax.swing.JOptionPane;
35 import javax.swing.JPanel;
36 import javax.swing.ListModel;
37 import javax.swing.ListSelectionModel;
38 import javax.swing.border.LineBorder;
43 import net.sf.gridarta.plugin.Plugin;
48 import net.sf.japi.swing.action.ActionBuilder;
49 import net.sf.japi.swing.action.ActionBuilderFactory;
50 import net.sf.japi.swing.action.ActionMethod;
51 import org.jetbrains.annotations.NotNull;
52 import org.jetbrains.annotations.Nullable;
53 
54 public class PluginManager<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
55 
59  @NotNull
60  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
61 
62  @NotNull
63  private final JFrame frame = new JFrame(ActionBuilderUtils.getString(ACTION_BUILDER, "pluginManagerTitle"));
64 
65  @NotNull
66  private final JList<Plugin<G, A, R>> scripts;
67 
68  @NotNull
69  private final CardLayout scriptLayout = new CardLayout();
70 
71  @NotNull
72  private final Container scriptPanel = new JPanel(scriptLayout);
73 
74  @NotNull
76 
77  @NotNull
79 
80  @NotNull
82 
86  @NotNull
88 
89  //TODO fix a memory leak. If a script is remove, it stays in hash map along with it's visual component
90 
91  @NotNull
92  private final Map<Plugin<G, A, R>, PluginEditor<G, A, R>> components = new HashMap<>();
93 
102  this.pluginController = pluginController;
103  this.pluginModel = pluginModel;
104  this.pluginParameterViewFactory = pluginParameterViewFactory;
105  this.resourceIcons = resourceIcons;
106  frame.getContentPane().setLayout(new BorderLayout());
107  final ListModel<Plugin<G, A, R>> listModel = new AbstractListModel<Plugin<G, A, R>>() {
108 
112  private static final long serialVersionUID = 1L;
113 
118  private final PluginModelListener<G, A, R> scriptModelListener = new PluginModelListener<G, A, R>() {
119 
120  @Override
121  public void pluginCreated(@NotNull final Plugin<G, A, R> plugin) {
122  fireContentsChanged(scripts, 0, PluginManager.this.pluginModel.getPluginCount() + 1);
123  }
124 
125  @Override
126  public void pluginDeleted(@NotNull final Plugin<G, A, R> plugin) {
127  fireContentsChanged(scripts, 0, PluginManager.this.pluginModel.getPluginCount() + 1);
128  }
129 
130  @Override
131  public void pluginRegistered(@NotNull final Plugin<G, A, R> plugin) {
132  fireContentsChanged(scripts, 0, PluginManager.this.pluginModel.getPluginCount() + 1);
133  }
134 
135  @Override
136  public void pluginUnregistered(@NotNull final Plugin<G, A, R> plugin) {
137  fireContentsChanged(scripts, 0, PluginManager.this.pluginModel.getPluginCount() + 1);
138  }
139 
140  };
141 
142  {
143  PluginManager.this.pluginModel.addPluginModelListener(scriptModelListener);
144  }
145 
146  @Nullable
147  @Override
148  public Plugin<G, A, R> getElementAt(final int index) {
149  return PluginManager.this.pluginModel.getPlugin(index);
150  }
151 
152  @Override
153  public int getSize() {
155  }
156  };
157 
158  scripts = new JList<>(listModel);
159  scripts.addListSelectionListener(e -> {
160  if (!e.getValueIsAdjusting()) {
161  showScript(scripts.getSelectedValue());
162  }
163  });
164  scripts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
165  scripts.setBorder(new LineBorder(Color.black, 1));
166  scripts.setSelectedIndex(0);
167 
168  final Container bottomLeft = new JPanel(new GridLayout(2, 1));
169  bottomLeft.add(new JButton(ACTION_BUILDER.createAction(false, "pluginManagerNewScript", this)));
170  bottomLeft.add(new JButton(ACTION_BUILDER.createAction(false, "pluginManagerRemoveScript", this)));
171 
172  final Container left = new JPanel(new BorderLayout());
173  left.add(scripts, BorderLayout.CENTER);
174  left.add(bottomLeft, BorderLayout.SOUTH);
175 
176  frame.getContentPane().add(left, BorderLayout.WEST);
177  frame.getContentPane().add(scriptPanel, BorderLayout.CENTER);
178  frame.pack();
179  frame.setLocationRelativeTo(parent);
180  }
181 
182  private void showScript(@Nullable final Plugin<G, A, R> plugin) {
183  /* using a card layout is a necessary trick as
184  * simply removing previous component and putting
185  * the new one in the JPanel lead to problem unless
186  * we recreate the component each time
187  * (the validate process goes strangely and only portions
188  * of component are redrawn until window resize :s)
189  */
190  if (plugin == null) {
191  return;
192  }
193 
194  PluginEditor<G, A, R> pluginEditor = components.get(plugin);
195  if (pluginEditor == null) {
197  components.put(plugin, pluginEditor);
198  scriptPanel.add(pluginEditor.getComponent(), Integer.toString(pluginEditor.hashCode()));
199  }
200  scriptLayout.show(scriptPanel, Integer.toString(pluginEditor.hashCode()));
201  }
202 
203  private void removeScript(@NotNull final Plugin<G, A, R> plugin) {
204  final PluginEditor<?, ?, ?> scriptEditor = components.get(plugin);
205  if (scriptEditor != null) {
206  components.remove(plugin);
207  scriptPanel.remove(scriptEditor.getComponent());
208  }
209  }
210 
214  public void show() {
215  frame.setVisible(true);
216  }
217 
221  @ActionMethod
222  public void pluginManagerNewScript() {
223  final String name = JOptionPane.showInputDialog(scripts, ActionBuilderUtils.getString(ACTION_BUILDER, "pluginManagerNewScriptTitle"));
224  if (name == null) {
225  return;
226  }
227 
228  final Plugin<G, A, R> plugin = pluginModel.newPlugin(name, "//input your beanshell Code");
229  if (plugin == null) {
230  final String title = ActionBuilderUtils.getString(ACTION_BUILDER, "pluginManagerNewScriptExists.title");
231  final String message = ActionBuilderUtils.format(ACTION_BUILDER, "pluginManagerNewScriptExists.message", name);
232  JOptionPane.showMessageDialog(scripts, message, title, JOptionPane.WARNING_MESSAGE);
233  return;
234  }
235 
236  showScript(plugin);
237  }
238 
242  @ActionMethod
244  final Plugin<G, A, R> plugin = scripts.getSelectedValue();
245  if (plugin == null) {
246  return;
247  }
248 
249  final String title = ActionBuilderUtils.getString(ACTION_BUILDER, "pluginManagerRemoveScriptConfirm.title");
250  final String message = ActionBuilderUtils.format(ACTION_BUILDER, "pluginManagerRemoveScriptConfirm.message", plugin.getName());
251  if (JOptionPane.showConfirmDialog(scripts, message, title, JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
252  return;
253  }
254 
255  pluginModel.removePlugin(plugin);
256  scripts.setSelectedIndex(0);
257  removeScript(plugin);
258  }
259 
260 }
name
name
Definition: ArchetypeTypeSetParserTest-ignoreDefaultAttribute1-result.txt:2
net.sf.gridarta.gui.dialog.plugin.PluginManager.pluginController
final PluginController< G, A, R > pluginController
Definition: PluginManager.java:75
net.sf.gridarta.plugin
Definition: BshRunnable.java:20
net.sf.gridarta.plugin.PluginModel.newPlugin
Plugin< G, A, R > newPlugin(@NotNull final String name, @NotNull final String code)
Definition: PluginModel.java:219
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.plugin.PluginModel.addPluginModelListener
void addPluginModelListener(@NotNull final PluginModelListener< G, A, R > listener)
Adds a listener to be informed of changes.
Definition: PluginModel.java:155
net.sf.gridarta.plugin.PluginModel.removePlugin
void removePlugin(@NotNull final Plugin< G, A, R > plugin)
Definition: PluginModel.java:125
net.sf.gridarta.plugin.PluginModelListener
Listener interface for scripting related events.
Definition: PluginModelListener.java:32
net.sf.gridarta.plugin.Plugin.getName
String getName()
Returns the name of this plugin.
Definition: Plugin.java:148
net.sf.gridarta.gui.dialog.plugin.PluginEditor.getComponent
Component getComponent()
Returns the Component for this plugin editor.
Definition: PluginEditor.java:352
net.sf
net.sf.gridarta.gui.dialog.plugin.PluginManager.pluginModel
final PluginModel< G, A, R > pluginModel
Definition: PluginManager.java:78
net.sf.gridarta.gui.dialog.plugin.PluginManager.scripts
final JList< Plugin< G, A, R > > scripts
Definition: PluginManager.java:66
net.sf.gridarta.model.archetype
Definition: AbstractArchetype.java:20
net.sf.gridarta.model.gameobject.GameObject
Reflects a game object (object on a map).
Definition: GameObject.java:36
net.sf.gridarta.gui.dialog.plugin.PluginManager.pluginManagerNewScript
void pluginManagerNewScript()
Action method to create a new plugin script.
Definition: PluginManager.java:222
net.sf.gridarta.gui.dialog.plugin.parameter
net.sf.gridarta.gui.dialog.plugin.PluginManager.scriptLayout
final CardLayout scriptLayout
Definition: PluginManager.java:69
net.sf.gridarta.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.model.gameobject
GameObjects are the objects based on Archetypes found on maps.
Definition: AbstractGameObject.java:20
net
net.sf.gridarta.gui.dialog.plugin.PluginManager.resourceIcons
final ResourceIcons resourceIcons
The ResourceIcons for creating icons.
Definition: PluginManager.java:87
net.sf.gridarta.model.maparchobject.MapArchObject
Interface for MapArchObjects.
Definition: MapArchObject.java:40
net.sf.gridarta.plugin.PluginModel.getPlugin
Plugin< G, A, R > getPlugin(@NotNull final String name)
Definition: PluginModel.java:79
net.sf.gridarta.gui.dialog.plugin.PluginManager.showScript
void showScript(@Nullable final Plugin< G, A, R > plugin)
Definition: PluginManager.java:182
net.sf.gridarta.utils.ActionBuilderUtils.format
static String format(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final Object... args)
Returns the value of a key.
Definition: ActionBuilderUtils.java:101
net.sf.gridarta.utils.ActionBuilderUtils.getString
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
Definition: ActionBuilderUtils.java:71
net.sf.gridarta.gui.dialog
net.sf.gridarta.gui.dialog.plugin.PluginManager.pluginManagerRemoveScript
void pluginManagerRemoveScript()
Action method to remove the selected plugin script.
Definition: PluginManager.java:243
net.sf.gridarta.gui.dialog.plugin
Definition: CloseableTabbedPane.java:47
net.sf.gridarta.gui.dialog.plugin.PluginManager.components
final Map< Plugin< G, A, R >, PluginEditor< G, A, R > > components
Definition: PluginManager.java:92
net.sf.gridarta.gui.dialog.plugin.parameter.PluginParameterViewFactory
Factory for creating PluginParameterView instances.
Definition: PluginParameterViewFactory.java:49
net.sf.gridarta.gui.dialog.plugin.PluginManager.show
void show()
Shows the plugin manager window.
Definition: PluginManager.java:214
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Reflects an Archetype.
Definition: Archetype.java:41
net.sf.gridarta.gui.dialog.plugin.PluginEditor
Definition: PluginEditor.java:64
net.sf.gridarta.plugin.Plugin
Model for plugins.
Definition: Plugin.java:53
net.sf.gridarta.gui.dialog.plugin.PluginManager.removeScript
void removeScript(@NotNull final Plugin< G, A, R > plugin)
Definition: PluginManager.java:203
net.sf.gridarta.utils.ActionBuilderUtils
Utility class for ActionBuilder related functions.
Definition: ActionBuilderUtils.java:31
net.sf.gridarta.gui.dialog.plugin.PluginManager.pluginParameterViewFactory
final PluginParameterViewFactory< G, A, R > pluginParameterViewFactory
Definition: PluginManager.java:81
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.gui.dialog.plugin.PluginManager
Definition: PluginManager.java:54
net.sf.gridarta.utils.ResourceIcons
Creates ImageIcon instances from resources.
Definition: ResourceIcons.java:46
net.sf.gridarta.gui.dialog.plugin.PluginManager.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Action Builder to create Actions.
Definition: PluginManager.java:60
net.sf.gridarta.gui.dialog.plugin.PluginController< G, A, R >
net.sf.gridarta.gui.dialog.plugin.PluginManager.frame
final JFrame frame
Definition: PluginManager.java:63
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.gui.dialog.plugin.PluginManager.PluginManager
PluginManager(@NotNull final Component parent, @NotNull final PluginController< G, A, R > pluginController, @NotNull final PluginModel< G, A, R > pluginModel, @NotNull final PluginParameterViewFactory< G, A, R > pluginParameterViewFactory, @NotNull final ResourceIcons resourceIcons)
Creates a PluginManager.
Definition: PluginManager.java:101
net.sf.gridarta.plugin.PluginModel.getPluginCount
int getPluginCount()
Definition: PluginModel.java:83
net.sf.gridarta.gui.dialog.plugin.PluginManager.scriptPanel
final Container scriptPanel
Definition: PluginManager.java:72
net.sf.gridarta.plugin.PluginModel
Definition: PluginModel.java:49