Gridarta Editor
ScriptEditView.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.textedit.scripteditor;
21 
22 import java.awt.Frame;
23 import java.awt.Rectangle;
24 import java.awt.geom.RectangularShape;
25 import java.io.BufferedReader;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.prefs.Preferences;
34 import javax.swing.JDialog;
35 import javax.swing.JOptionPane;
36 import javax.swing.JTabbedPane;
37 import javax.swing.SwingConstants;
38 import javax.swing.event.ChangeEvent;
39 import javax.swing.event.ChangeListener;
40 import javax.swing.text.BadLocationException;
45 import net.sf.gridarta.utils.Exiter;
47 import net.sf.japi.swing.action.ActionBuilder;
48 import net.sf.japi.swing.action.ActionBuilderFactory;
49 import org.apache.log4j.Category;
50 import org.apache.log4j.Logger;
51 import org.jetbrains.annotations.NotNull;
52 import org.jetbrains.annotations.Nullable;
53 
59 public class ScriptEditView extends JDialog {
60 
64  @NotNull
65  private static final Category LOG = Logger.getLogger(ScriptEditView.class);
66 
70  @NotNull
71  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
72 
76  @NotNull
78 
82  private static final long serialVersionUID = 1L;
83 
88  @NotNull
89  private static final String WINDOW_X = "ScriptEditWindow.x";
90 
95  @NotNull
96  private static final String WINDOW_Y = "ScriptEditWindow.y";
97 
101  @NotNull
102  private static final String WINDOW_WIDTH = "ScriptEditWindow.width";
103 
107  @NotNull
108  private static final String WINDOW_HEIGHT = "ScriptEditWindow.height";
109 
113  @NotNull
114  private final Actions actions;
115 
119  @NotNull
121 
122  @NotNull
123  private final JTabbedPane tabPane; // tab pane
124 
125  @NotNull
126  private final List<JEditTextArea> textAreas; // list of 'JEditTextArea' objects, same order as tabs
127 
135  public ScriptEditView(@NotNull final ScriptEditControl control, @NotNull final Frame owner, @NotNull final Preferences preferences, @NotNull final Exiter exiter) {
136  super(owner, "Script Pad");
137  setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
138 
139  textAreas = new ArrayList<>();
140  actions = new Actions(control);
142  setJMenuBar(ACTION_BUILDER.createMenuBar(true, "scriptEditMenu"));
143 
144  tabPane = new JTabbedPane(SwingConstants.TOP); // init tab pane
145  tabPane.addChangeListener(new EditTabListener(this));
146 
147  getContentPane().add(tabPane);
148  addWindowListener(new EditWindowListener(control)); // add listener for close box
149 
150  // calculate some default values in case there is no settings file
151  final RectangularShape screen = getGraphicsConfiguration().getBounds();
152  final int width = preferences.getInt(WINDOW_WIDTH, (int) (0.8 * screen.getWidth()));
153  final int height = preferences.getInt(WINDOW_HEIGHT, (int) (0.8 * screen.getHeight()));
154  final int x = preferences.getInt(WINDOW_X, (int) (screen.getX() + (screen.getWidth() - width) / 2.0));
155  final int y = preferences.getInt(WINDOW_Y, (int) (screen.getY() + (screen.getHeight() - height) / 2.0));
156  setBounds(x, y, width, height);
157 
158  final ExiterListener exiterListener = new ExiterListener() {
159 
160  @Override
161  public void preExitNotify() {
162  // ignore
163  }
164 
165  @Override
166  public void appExitNotify() {
167  final Rectangle bounds = getBounds();
168  preferences.putInt(WINDOW_X, bounds.x);
169  preferences.putInt(WINDOW_Y, bounds.y);
170  preferences.putInt(WINDOW_WIDTH, bounds.width);
171  preferences.putInt(WINDOW_HEIGHT, bounds.height);
172  }
173 
174  @Override
175  public void waitExitNotify() {
176  // ignore
177  }
178 
179  };
180  exiter.addExiterListener(exiterListener);
181  }
182 
183  @Deprecated
185  this.textAreaDefaults = textAreaDefaults;
186  }
187 
193  public void addTab(@NotNull final String title, @Nullable final File file) {
194  final SyntaxDocument syntaxDocument = new SyntaxDocument();
196  final JEditTextArea ta = new JEditTextArea(textAreaDefaults, syntaxDocument, textAreaDefaults.getPaintInvalid()); // open new TextArea
197  //ta.setFont(new Font("Courier New", Font.PLAIN, 12));
198  textAreas.add(ta);
199  scriptEditUndoActions.addDocument(syntaxDocument);
200  tabPane.addTab(title, ta);
201  if (getTabCount() <= 1 || !isShowing()) {
202  setVisible(true);
203  }
204 
206 
207  tabPane.setSelectedIndex(getTabCount() - 1);
208 
209  // very important: There must be a drawing update after showing the frame, to make
210  // sure the graphics context is fully initialized before calling 'setEditingFocus()'
211  //if (isFirstTimeShowing) {
212  update(getGraphics());
213  //}
214 
215  if (file != null && file.exists()) {
216  // print file into this document
217  try {
218  try (FileInputStream fis = new FileInputStream(file)) {
219  try (InputStreamReader isr = new InputStreamReader(fis)) {
220  try (BufferedReader in = new BufferedReader(isr)) {
221  boolean firstLine = true;
222  final StringBuilder buff = new StringBuilder();
223  while (true) {
224  final String line = in.readLine();
225  if (line == null) {
226  break;
227  }
228  if (firstLine) {
229  firstLine = false;
230  } else {
231  buff.append('\n');
232  }
233  buff.append(line);
234  }
235  syntaxDocument.insertString(0, buff.toString(), null);
236  }
237  }
238  }
239  // insert buffer into the document
240  } catch (final FileNotFoundException e) {
241  if (LOG.isInfoEnabled()) {
242  LOG.info("addTab(): File '" + file.getName() + "' not found.");
243  }
244  } catch (final IOException e) {
245  if (LOG.isInfoEnabled()) {
246  LOG.info("addTab(): I/O-Error while reading '" + file.getName() + "'.");
247  }
248  } catch (final BadLocationException e) {
249  if (LOG.isInfoEnabled()) {
250  LOG.info("addTab(): Bad Location in Document!");
251  }
252  }
253  scriptEditUndoActions.resetUndo(syntaxDocument);
254  }
255 
256  ta.setEditingFocus(); // set focus to TextArea in order to respond to key press events
257  //ta.scrollToCaret(); // make sure the window shows caret (top left corner)
258 
259  ta.resetModified();
260 
261  toFront(); // bring window to front
262  }
263 
267  public void closeActiveTab() {
268  if (textAreas.isEmpty()) {
269  setVisible(false);
270  } else {
271  final int oldIndex = tabPane.getSelectedIndex();
272  final int newIndex = oldIndex >= tabPane.getTabCount() - 1 ? oldIndex - 1 : oldIndex;
273  tabPane.setSelectedIndex(newIndex);
274  scriptEditUndoActions.removeDocument(textAreas.get(oldIndex).getDocument());
275  textAreas.remove(oldIndex);
276  tabPane.remove(oldIndex);
277  actions.refresh();
278  scriptEditUndoActions.setCurrentDocument(newIndex == -1 ? null : textAreas.get(newIndex).getDocument());
279  }
280  }
281 
285  @Nullable
287  return getTabCount() <= 0 ? null : textAreas.get(tabPane.getSelectedIndex());
288  }
289 
293  public int getSelectedIndex() {
294  return tabPane.getSelectedIndex();
295  }
296 
300  public int getTabCount() {
301  return tabPane.getTabCount();
302  }
303 
309  public void setTitleAt(final int index, @NotNull final String title) {
310  tabPane.setTitleAt(index, title);
311  }
312 
317  @Nullable
318  public String getActiveTitle() {
319  return getTabCount() > 0 ? tabPane.getTitleAt(tabPane.getSelectedIndex()) : null;
320  }
321 
330  public boolean askConfirm(@NotNull final String title, @NotNull final String message) {
331  return JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.YES_OPTION;
332  }
333 
341  public void showMessage(@NotNull final String title, @NotNull final String message, final int messageType) {
342  JOptionPane.showMessageDialog(this, message, title, messageType);
343  }
344 
345  public void showMessage(@NotNull final String title, @NotNull final String message) {
346  JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
347  }
348 
352  private class EditTabListener implements ChangeListener {
353 
354  @NotNull
355  private final ScriptEditView view; // view
356 
357  private int index; // index of selected tab
358 
359  private EditTabListener(@NotNull final ScriptEditView view) {
360  this.view = view;
362  }
363 
364  @Override
365  public void stateChanged(@NotNull final ChangeEvent e) {
366  if (index != view.getSelectedIndex()) {
368  // active selected tab has changed
369  actions.refresh(); // refresh state of menus
370  scriptEditUndoActions.setCurrentDocument(index == -1 ? null : textAreas.get(index).getDocument());
371  }
372  }
373 
374  }
375 
376 }
net.sf.gridarta.textedit.scripteditor.ScriptEditView.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Action Builder.
Definition: ScriptEditView.java:71
net.sf.gridarta.textedit.textarea.TextAreaDefaults
Encapsulates default settings for a text area.
Definition: TextAreaDefaults.java:26
net.sf.gridarta.textedit.scripteditor.ScriptEditView.tabPane
final JTabbedPane tabPane
Definition: ScriptEditView.java:123
net.sf.gridarta.textedit.textarea.JEditTextArea
jEdit's text area component.
Definition: JEditTextArea.java:91
net.sf.gridarta.textedit.scripteditor.ScriptEditView.showMessage
void showMessage(@NotNull final String title, @NotNull final String message, final int messageType)
Shows the given message in the UI.
Definition: ScriptEditView.java:341
net.sf.gridarta.textedit.scripteditor.ScriptEditView
The script editor frame.
Definition: ScriptEditView.java:59
net.sf.gridarta.textedit.textarea
This package contains the other part of the script editor.
net.sf.gridarta.textedit.textarea.JEditTextArea.setEditingFocus
void setEditingFocus()
Sets the focus to this TextArea, so this component is instantly registered for key press events.
Definition: JEditTextArea.java:402
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.textedit.scripteditor.EditWindowListener
Listener for close box on the window.
Definition: EditWindowListener.java:30
net.sf.gridarta.textedit.scripteditor.Actions.refresh
void refresh()
Refreshes the enable/disable state of all menus.
Definition: Actions.java:261
net.sf.gridarta.textedit.scripteditor.ScriptEditView.getActiveTitle
String getActiveTitle()
Returns the title of the active tab.
Definition: ScriptEditView.java:318
net.sf.gridarta.textedit.scripteditor.ScriptEditView.setTitleAt
void setTitleAt(final int index, @NotNull final String title)
Sets the title of the tab at specified index.
Definition: ScriptEditView.java:309
net.sf
net.sf.gridarta.textedit.scripteditor.ScriptEditUndoActions.removeDocument
void removeDocument(@NotNull final Document document)
Removes a document.
Definition: ScriptEditUndoActions.java:98
net.sf.gridarta.textedit.scripteditor.ScriptEditView.EditTabListener.index
int index
Definition: ScriptEditView.java:357
net.sf.gridarta.textedit.scripteditor.ScriptEditView.getActiveTextArea
JEditTextArea getActiveTextArea()
Definition: ScriptEditView.java:286
net.sf.gridarta.textedit.scripteditor.ScriptEditUndoActions.resetUndo
void resetUndo(@NotNull final Document document)
Forget all undo-able operations for a document.
Definition: ScriptEditUndoActions.java:111
net.sf.gridarta.textedit.scripteditor.ScriptEditView.textAreaDefaults
TextAreaDefaults textAreaDefaults
The TextAreaDefaults for tabs.
Definition: ScriptEditView.java:77
net.sf.gridarta.textedit
net.sf.gridarta.textedit.textarea.JEditTextArea.resetModified
void resetModified()
Reset the "modified" state.
Definition: JEditTextArea.java:962
net.sf.gridarta.textedit.scripteditor.ScriptEditView.scriptEditUndoActions
final ScriptEditUndoActions scriptEditUndoActions
The undo related actions for the script editor.
Definition: ScriptEditView.java:120
net.sf.gridarta.textedit.scripteditor.ScriptEditView.setTextAreaDefaults
void setTextAreaDefaults(@NotNull final TextAreaDefaults textAreaDefaults)
Definition: ScriptEditView.java:184
net.sf.gridarta.textedit.textarea.SyntaxDocument
A document implementation that can be tokenized by the syntax highlighting system.
Definition: SyntaxDocument.java:29
net.sf.gridarta.textedit.textarea.tokenmarker
Definition: CrossfireDialogTokenMarker.java:20
net
net.sf.gridarta.textedit.scripteditor.ScriptEditView.LOG
static final Category LOG
The Logger for printing log messages.
Definition: ScriptEditView.java:65
net.sf.gridarta.textedit.scripteditor.ScriptEditUndoActions.setCurrentDocument
void setCurrentDocument(@Nullable final Document currentDocument)
Sets the current document.
Definition: ScriptEditUndoActions.java:173
net.sf.gridarta.textedit.scripteditor.Actions
Actions used by the script editor.
Definition: Actions.java:41
net.sf.gridarta.textedit.scripteditor.ScriptEditView.EditTabListener.view
final ScriptEditView view
Definition: ScriptEditView.java:355
net.sf.gridarta.textedit.textarea.TextAreaDefaults.getPaintInvalid
boolean getPaintInvalid()
Definition: TextAreaDefaults.java:175
net.sf.gridarta.textedit.textarea.tokenmarker.TokenMarkerFactory.createTokenMarker
static TokenMarker createTokenMarker(@Nullable final File file)
Creates a suitable TokenMarker for a given file.
Definition: TokenMarkerFactory.java:80
net.sf.gridarta.textedit.scripteditor.ScriptEditView.addTab
void addTab(@NotNull final String title, @Nullable final File file)
Adds a new TextArea Panel to the TabbedPane.
Definition: ScriptEditView.java:193
net.sf.gridarta.textedit.scripteditor.ScriptEditView.ScriptEditView
ScriptEditView(@NotNull final ScriptEditControl control, @NotNull final Frame owner, @NotNull final Preferences preferences, @NotNull final Exiter exiter)
Builds a frame but keep it hidden (it is shown when first file is opened).
Definition: ScriptEditView.java:135
net.sf.gridarta.textedit.scripteditor.ScriptEditView.getTabCount
int getTabCount()
Definition: ScriptEditView.java:300
net.sf.gridarta.textedit.scripteditor.ScriptEditView.actions
final Actions actions
The actions for the script editor.
Definition: ScriptEditView.java:114
net.sf.gridarta.textedit.scripteditor.ScriptEditView.showMessage
void showMessage(@NotNull final String title, @NotNull final String message)
Definition: ScriptEditView.java:345
net.sf.gridarta.textedit.scripteditor.ScriptEditView.textAreas
final List< JEditTextArea > textAreas
Definition: ScriptEditView.java:126
net.sf.gridarta.textedit.scripteditor.ScriptEditUndoActions.addDocument
void addDocument(@NotNull final Document document)
Adds a document.
Definition: ScriptEditUndoActions.java:88
net.sf.gridarta.textedit.scripteditor.ScriptEditControl
ScriptEditControl - Manages events and data flow for the script editor entity.
Definition: ScriptEditControl.java:59
net.sf.gridarta.textedit.scripteditor.ScriptEditView.EditTabListener.EditTabListener
EditTabListener(@NotNull final ScriptEditView view)
Definition: ScriptEditView.java:359
net.sf.gridarta.textedit.scripteditor.ScriptEditView.askConfirm
boolean askConfirm(@NotNull final String title, @NotNull final String message)
Shows the given confirmation message as popup frame.
Definition: ScriptEditView.java:330
net.sf.gridarta.textedit.scripteditor.ScriptEditView.EditTabListener
Inner class: Listener for ChangeEvents in the tabPane.
Definition: ScriptEditView.java:352
net.sf.gridarta.textedit.scripteditor.ScriptEditView.EditTabListener.stateChanged
void stateChanged(@NotNull final ChangeEvent e)
Definition: ScriptEditView.java:365
net.sf.gridarta.textedit.scripteditor.ScriptEditView.serialVersionUID
static final long serialVersionUID
Serial Version UID.
Definition: ScriptEditView.java:82
net.sf.gridarta.textedit.textarea.SyntaxDocument.setTokenMarker
void setTokenMarker(@Nullable final TokenMarker tokenMarker)
Sets the token marker that is to be used to split lines of this document up into tokens.
Definition: SyntaxDocument.java:52
net.sf.gridarta.textedit.scripteditor.ScriptEditView.WINDOW_Y
static final String WINDOW_Y
The key used to store the editor window y-coordinate in preferences file.
Definition: ScriptEditView.java:96
net.sf.gridarta.textedit.textarea.tokenmarker.TokenMarkerFactory
A factory for creatingTokenMarker instances for Files.
Definition: TokenMarkerFactory.java:32
net.sf.gridarta.textedit.scripteditor.ScriptEditView.WINDOW_X
static final String WINDOW_X
The key used to store the editor window x-coordinate in preferences file.
Definition: ScriptEditView.java:89
net.sf.gridarta.textedit.scripteditor.ScriptEditView.closeActiveTab
void closeActiveTab()
Closes the active script-tab.
Definition: ScriptEditView.java:267
net.sf.gridarta.utils.ExiterListener
Interface for listeners interested in Exiter related events.
Definition: ExiterListener.java:28
net.sf.gridarta.textedit.scripteditor.ScriptEditView.WINDOW_HEIGHT
static final String WINDOW_HEIGHT
The key used to store the editor window height in preferences file.
Definition: ScriptEditView.java:108
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.textedit.scripteditor.ScriptEditView.WINDOW_WIDTH
static final String WINDOW_WIDTH
The key used to store the editor window width in preferences file.
Definition: ScriptEditView.java:102
net.sf.gridarta.textedit.scripteditor.ScriptEditView.getSelectedIndex
int getSelectedIndex()
Definition: ScriptEditView.java:293
net.sf.gridarta.textedit.scripteditor.ScriptEditUndoActions
Implements undo and redo actions.
Definition: ScriptEditUndoActions.java:42
net.sf.gridarta.utils.Exiter
Exits the application.
Definition: Exiter.java:28