1 package de.lathanda.eos.gui;
3 import java.awt.BorderLayout;
5 import java.awt.Dimension;
7 import java.awt.GridBagConstraints;
8 import java.awt.GridBagLayout;
9 import java.awt.GridLayout;
10 import java.awt.KeyEventDispatcher;
11 import java.awt.KeyboardFocusManager;
12 import java.awt.Rectangle;
13 import java.awt.event.KeyEvent;
14 import java.awt.event.WindowEvent;
15 import java.awt.event.WindowListener;
16 import java.io.BufferedWriter;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.OutputStreamWriter;
21 import java.text.MessageFormat;
23 import javax.swing.JButton;
24 import javax.swing.JFileChooser;
25 import javax.swing.JFrame;
26 import javax.swing.JMenu;
27 import javax.swing.JMenuBar;
28 import javax.swing.JMenuItem;
29 import javax.swing.JOptionPane;
30 import javax.swing.JPanel;
31 import javax.swing.JScrollPane;
32 import javax.swing.JSlider;
33 import javax.swing.JSplitPane;
34 import javax.swing.JTextPane;
35 import javax.swing.JToolBar;
36 import javax.swing.Scrollable;
37 import javax.swing.WindowConstants;
38 import javax.swing.event.ChangeEvent;
39 import javax.swing.filechooser.FileNameExtensionFilter;
40 import javax.swing.filechooser.FileSystemView;
42 import de.lathanda.eos.base.ResourceLoader;
43 import de.lathanda.eos.base.util.GuiToolkit;
44 import de.lathanda.eos.common.gui.BackgroundCompiler;
45 import de.lathanda.eos.common.gui.CodeColoring;
46 import de.lathanda.eos.common.gui.ConfigFrame;
47 import de.lathanda.eos.common.gui.GuiConfiguration;
48 import de.lathanda.eos.common.gui.GuiConfiguration.GuiConfigurationListener;
49 import de.lathanda.eos.common.gui.HtmlExport;
50 import de.lathanda.eos.common.gui.PrintFrame;
51 import de.lathanda.eos.common.gui.SideInformation;
52 import de.lathanda.eos.common.gui.SourceCode;
53 import de.lathanda.eos.config.Language;
54 import de.lathanda.eos.common.gui.Messages;
55 import de.lathanda.eos.gui.classchart.ClassChart;
56 import de.lathanda.eos.gui.diagram.DiagramFrame;
57 import de.lathanda.eos.gui.flowchart.FlowChart;
58 import de.lathanda.eos.gui.objectchart.ObjectChart;
59 import de.lathanda.eos.gui.structogram.Structogram;
60 import static de.lathanda.eos.base.icons.Icons.*;
61 import static de.lathanda.eos.gui.icons.Icons.*;
69 private static final long serialVersionUID = -5517007240148560239L;
77 private final JFileChooser filechooser;
81 private final JFileChooser exportfilechooser;
89 private File activeFile =
null;
103 filechooser =
new JFileChooser();
104 filechooser.setFileFilter(
new FileNameExtensionFilter(
Messages.
getString(
"File.EOS"),
"eos"));
105 filechooser.setCurrentDirectory(
new File(FileSystemView.getFileSystemView().getDefaultDirectory().getPath()));
106 exportfilechooser =
new JFileChooser();
107 exportfilechooser.addChoosableFileFilter(
new FileNameExtensionFilter(
Messages.
getString(
"File.Html"),
"html"));
108 exportfilechooser.setCurrentDirectory(
new File(
"."));
114 txtProgram.setDocument(data);
116 txtProgram.requestFocus();
118 KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
new FunctionKeyDispatcher());
125 new Thread(compiler).start();
131 private void initComponents() {
133 mainMenu =
new JMenuBar();
134 mainToolbar =
new JToolBar();
135 jSeparator1 =
new JToolBar.Separator();
136 jSeparator2 =
new JToolBar.Separator();
137 jSeparator3 =
new JToolBar.Separator();
138 jSeparator4 =
new JToolBar.Separator();
139 mainSplit =
new JSplitPane();
140 scrollProgram =
new JScrollPane();
141 txtProgram =
new JTextPane();
143 scrollOutput =
new JScrollPane();
144 txtOutput =
new JTextPane();
145 runToolbar =
new JToolBar();
146 toolbarGroup =
new JPanel();
147 sliderSpeed =
new JSlider();
149 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
152 addWindowListener(
this);
154 toolbarGroup.setLayout(
new GridLayout(2, 1));
156 mainToolbar.setFloatable(
false);
157 mainToolbar.setRollover(
true);
158 mainToolbar.setBackground(
new Color(0xEEEEEE));
159 toolbarGroup.add(mainToolbar);
162 evt -> SaveActionPerformed(evt));
163 mainToolbar.add(btnSave);
166 evt -> OpenActionPerformed(evt));
167 mainToolbar.add(btnOpen);
169 mainToolbar.add(jSeparator1);
172 evt -> CopyActionPerformed(evt));
173 mainToolbar.add(btnCopy);
176 evt -> CutActionPerformed(evt));
177 mainToolbar.add(btnCut);
180 evt -> PasteActionPerformed(evt));
181 mainToolbar.add(btnPaste);
183 mainToolbar.add(jSeparator2);
186 evt -> UndoActionPerformed(evt));
187 mainToolbar.add(btnUndo);
190 evt -> RedoActionPerformed(evt));
191 mainToolbar.add(btnRedo);
193 mainToolbar.add(jSeparator3);
196 evt -> BreakpointActionPerformed(evt));
197 mainToolbar.add(btnBreakpoint);
199 mainToolbar.add(jSeparator4);
202 evt -> ClassDocActionPerformed(evt));
203 mainToolbar.add(btnClassDoc);
206 evt -> HelpActionPerformed(evt));
207 mainToolbar.add(btnHelp);
209 mainSplit.setOrientation(JSplitPane.VERTICAL_SPLIT);
210 mainSplit.setResizeWeight(1.0);
213 scrollProgram.setViewportView(
new NoTextWrapContainer(txtProgram));
214 scrollProgram.getViewport().setBackground(Color.WHITE);
215 scrollProgram.setRowHeaderView(sideInformation);
217 mainSplit.setTopComponent(scrollProgram);
219 txtOutput.setEditable(
false);
221 txtOutput.setFocusable(
false);
222 scrollOutput.setViewportView(txtOutput);
224 mainSplit.setRightComponent(scrollOutput);
226 runToolbar.setFloatable(
false);
227 runToolbar.setRollover(
true);
228 runToolbar.setBackground(
new Color(0xEEEEEE));
229 runToolbar.setLayout(
new GridBagLayout());
231 GridBagConstraints LAST =
new GridBagConstraints();
232 LAST.fill = GridBagConstraints.BOTH;
235 toolbarGroup.add(runToolbar);
238 evt -> StartActionPerformed(evt));
239 runToolbar.add(btnStart);
242 evt -> SingleStepActionPerformed(evt));
243 runToolbar.add(btnSingleStep);
246 evt -> PauseActionPerformed(evt));
247 runToolbar.add(btnPause);
250 evt -> StopActionPerformed(evt));
251 runToolbar.add(btnStop);
254 evt -> SkipActionPerformed(evt));
255 runToolbar.add(btnSkip);
258 evt -> sliderSpeedStateChanged(evt));
259 sliderSpeed.setValue(10);
260 runToolbar.add(sliderSpeed, LAST);
265 evt -> NewActionPerformed(evt), KeyEvent.VK_N);
266 menuFile.add(mitNew);
269 evt -> OpenActionPerformed(evt), KeyEvent.VK_O);
270 menuFile.add(mitOpen);
273 evt -> SaveActionPerformed(evt), KeyEvent.VK_S);
274 menuFile.add(mitSave);
278 menuFile.add(mitSaveAs);
281 Messages.
getString(
"Menu.SaveAs.Html.Tooltip"), evt -> SaveAsHtmlActionPerformed(evt));
282 menuFile.add(mitSaveAsHtml);
285 evt -> PrintActionPerformed(evt), KeyEvent.VK_P);
286 menuFile.add(mitPrint);
290 menuFile.add(mitConfig);
293 evt -> ExitActionPerformed(evt));
294 menuFile.add(mitExit);
296 mainMenu.add(menuFile);
301 evt -> CopyActionPerformed(evt), KeyEvent.VK_C);
302 editMenu.add(mitCopy);
305 evt -> CutActionPerformed(evt), KeyEvent.VK_X);
306 editMenu.add(mitCut);
309 evt -> PasteActionPerformed(evt), KeyEvent.VK_V);
310 editMenu.add(mitPaste);
313 evt -> UndoActionPerformed(evt), KeyEvent.VK_Z);
314 editMenu.add(mitUndo);
317 evt -> RedoActionPerformed(evt), KeyEvent.VK_Y);
318 editMenu.add(mitRedo);
321 Messages.
getString(
"Menu.Pretty.Tooltip"), evt -> PrettyActionPerformed(evt), KeyEvent.VK_F);
322 editMenu.add(mitPretty);
324 mainMenu.add(editMenu);
329 Messages.
getString(
"Menu.Structogram.Tooltip"), evt -> StructogramActionPerformed(evt));
330 diagramMenu.add(mitStructogram);
333 Messages.
getString(
"Menu.Flowchart.Tooltip"), evt -> FlowChartActionPerformed(evt));
334 diagramMenu.add(mitFlowChart);
337 Messages.
getString(
"Menu.Objectchart.Tooltip"), evt -> ObjectChartActionPerformed(evt));
338 diagramMenu.add(mitObjectChart);
341 Messages.
getString(
"Menu.Classchart.Tooltip"), evt -> ClassChartActionPerformed(evt));
342 diagramMenu.add(mitClassChart);
344 mainMenu.add(diagramMenu);
351 Messages.
getString(
"Menu.Classbook.Tooltip"), evt -> ClassDocActionPerformed(evt));
352 helpMenu.add(mitClassDoc);
355 Messages.
getString(
"Menu.Handbook.Tooltip"), evt -> HelpActionPerformed(evt), KeyEvent.VK_F1);
356 helpMenu.add(mitHelp);
358 mainMenu.add(helpMenu);
360 setJMenuBar(mainMenu);
362 getContentPane().setLayout(
new BorderLayout());
363 getContentPane().add(toolbarGroup, BorderLayout.NORTH);
364 getContentPane().add(mainSplit, BorderLayout.CENTER);
375 private void StartActionPerformed(java.awt.event.ActionEvent evt) {
384 private void SaveActionPerformed(java.awt.event.ActionEvent evt) {
393 private boolean save() {
395 if (activeFile !=
null) {
397 ResourceLoader.setWorkingDirectory(activeFile.getParent());
402 }
catch (IOException io) {
403 JOptionPane.showMessageDialog(
this, Messages.getString(
"Save.Error.Title"), io.getLocalizedMessage(),
404 JOptionPane.ERROR_MESSAGE);
414 private boolean saveAs() {
416 if (filechooser.showSaveDialog(
this) == JFileChooser.APPROVE_OPTION) {
417 File target = filechooser.getSelectedFile();
418 if (!target.getName().contains(
".")) {
419 target =
new File(target.toString() +
".eos");
421 if (!overwriteSafetyCheck(target)) {
426 ResourceLoader.setWorkingDirectory(activeFile.getParent());
431 }
catch (IOException io) {
432 JOptionPane.showMessageDialog(
this, Messages.getString(
"Save.Error.Title"), io.getLocalizedMessage(),
433 JOptionPane.ERROR_MESSAGE);
443 private void OpenActionPerformed(java.awt.event.ActionEvent evt) {
445 if (filechooser.showOpenDialog(
this) == JFileChooser.APPROVE_OPTION) {
446 if (dirtySafetyCheck()) {
448 activeFile = filechooser.getSelectedFile();
449 ResourceLoader.setWorkingDirectory(activeFile.getParent());
452 }
catch (IOException io) {
453 JOptionPane.showMessageDialog(
this, Messages.getString(
"Open.Error.Title"), io.getLocalizedMessage(),
454 JOptionPane.ERROR_MESSAGE);
468 filechooser.setSelectedFile(file);
472 }
catch (IOException io) {
473 JOptionPane.showMessageDialog(
this,
Messages.
getString(
"Open.Error.Title"), io.getLocalizedMessage(),
474 JOptionPane.ERROR_MESSAGE);
483 private void UndoActionPerformed(java.awt.event.ActionEvent evt) {
492 private void RedoActionPerformed(java.awt.event.ActionEvent evt) {
501 private void PrettyActionPerformed(java.awt.event.ActionEvent evt) {
510 private void CopyActionPerformed(java.awt.event.ActionEvent evt) {
519 private void CutActionPerformed(java.awt.event.ActionEvent evt) {
528 private void PasteActionPerformed(java.awt.event.ActionEvent evt) {
537 private void NewActionPerformed(java.awt.event.ActionEvent evt) {
538 if (dirtySafetyCheck()) {
550 private void HelpActionPerformed(java.awt.event.ActionEvent evt) {
559 private void ClassDocActionPerformed(java.awt.event.ActionEvent evt) {
568 private void SingleStepActionPerformed(java.awt.event.ActionEvent evt) {
577 private void PauseActionPerformed(java.awt.event.ActionEvent evt) {
586 private void StopActionPerformed(java.awt.event.ActionEvent evt) {
595 private void SkipActionPerformed(java.awt.event.ActionEvent evt) {
604 private void sliderSpeedStateChanged(ChangeEvent evt) {
605 data.
setSpeed(sliderSpeed.getValue());
606 sliderSpeed.setToolTipText(MessageFormat.format(Messages.getString(
"Speed.Tooltip"), data.
getSpeed()));
614 private void SaveAsActionPerformed(java.awt.event.ActionEvent evt) {
623 private void BreakpointActionPerformed(java.awt.event.ActionEvent evt) {
625 sideInformation.repaint();
633 private void PrintActionPerformed(java.awt.event.ActionEvent evt) {
634 PrintFrame pf =
new PrintFrame(
635 (activeFile !=
null) ? activeFile.getName() : Messages.getString(
"Print.Noname"));
645 private void ConfigActionPerformed(java.awt.event.ActionEvent evt) {
646 configFrame.setVisible(
true);
654 private void ExitActionPerformed(java.awt.event.ActionEvent evt) {
663 private void SaveAsHtmlActionPerformed(java.awt.event.ActionEvent evt) {
665 if (exportfilechooser.showSaveDialog(
this) == JFileChooser.APPROVE_OPTION) {
666 File file = exportfilechooser.getSelectedFile();
667 if (!overwriteSafetyCheck(file)) {
670 String text = HtmlExport.export2html(data.
getProgram(), file.getName());
671 try (BufferedWriter bw =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(file),
"Utf-8"))) {
673 }
catch (IOException ioe) {
674 JOptionPane.showMessageDialog(
this, Messages.getString(
"Export.Error.Title"), ioe.getLocalizedMessage(),
675 JOptionPane.ERROR_MESSAGE);
685 private void StructogramActionPerformed(java.awt.event.ActionEvent evt) {
686 new DiagramFrame(
new Structogram(), compiler).setVisible(
true);
694 private void FlowChartActionPerformed(java.awt.event.ActionEvent evt) {
695 new DiagramFrame(
new FlowChart(), compiler).setVisible(
true);
703 private void ObjectChartActionPerformed(java.awt.event.ActionEvent evt) {
704 new DiagramFrame(
new ObjectChart(), compiler).setVisible(
true);
712 private void ClassChartActionPerformed(java.awt.event.ActionEvent evt) {
713 new DiagramFrame(
new ClassChart(), compiler).setVisible(
true);
719 private void closeApp() {
720 if (dirtySafetyCheck()) {
725 private boolean overwriteSafetyCheck(File file) {
726 if (!file.exists()) {
729 int answer = JOptionPane.showConfirmDialog(
this, Messages.getString(
"Save.Overwrite.Text"),
730 Messages.getString(
"Save.Overwrite.Title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
731 return answer == JOptionPane.OK_OPTION;
734 private boolean dirtySafetyCheck() {
736 int answer = JOptionPane.showConfirmDialog(
this, Messages.getString(
"Closing.Save.Text"),
737 Messages.getString(
"Closing.Save.Title"), JOptionPane.YES_NO_CANCEL_OPTION,
738 JOptionPane.QUESTION_MESSAGE);
740 case JOptionPane.YES_OPTION:
746 case JOptionPane.NO_OPTION:
748 case JOptionPane.CANCEL_OPTION:
763 private JButton btnCopy;
764 private JButton btnCut;
765 private JButton btnHelp;
766 private JButton btnClassDoc;
767 private JButton btnOpen;
768 private JButton btnPaste;
769 private JButton btnPause;
770 private JButton btnRedo;
771 private JButton btnSave;
772 private JButton btnBreakpoint;
773 private JButton btnSingleStep;
774 private JButton btnSkip;
775 private JButton btnStart;
776 private JButton btnStop;
777 private JButton btnUndo;
778 private JMenu diagramMenu;
779 private JMenu editMenu;
780 private JMenu helpMenu;
781 private JToolBar.Separator jSeparator1;
782 private JToolBar.Separator jSeparator2;
783 private JToolBar.Separator jSeparator3;
784 private JToolBar.Separator jSeparator4;
785 private JMenuBar mainMenu;
786 private JSplitPane mainSplit;
787 private JToolBar mainToolbar;
788 private JPanel toolbarGroup;
789 private JMenu menuFile;
790 private JMenuItem mitConfig;
791 private JMenuItem mitCopy;
792 private JMenuItem mitCut;
793 private JMenuItem mitPretty;
794 private JMenuItem mitExit;
795 private JMenuItem mitFlowChart;
796 private JMenuItem mitObjectChart;
797 private JMenuItem mitClassChart;
798 private JMenuItem mitHelp;
799 private JMenuItem mitClassDoc;
800 private JMenuItem mitNew;
801 private JMenuItem mitOpen;
802 private JMenuItem mitPaste;
803 private JMenuItem mitPrint;
804 private JMenuItem mitRedo;
805 private JMenuItem mitSave;
806 private JMenuItem mitSaveAs;
807 private JMenuItem mitSaveAsHtml;
808 private JMenuItem mitStructogram;
810 private JMenuItem mitUndo;
811 private JToolBar runToolbar;
812 private JScrollPane scrollOutput;
813 private JScrollPane scrollProgram;
814 private JSlider sliderSpeed;
815 private JTextPane txtOutput;
816 private JTextPane txtProgram;
859 private static class NoTextWrapContainer
extends JPanel implements Scrollable {
860 private static final long serialVersionUID = 1687707567072204851L;
861 private Scrollable scrollable;
863 public NoTextWrapContainer(JTextPane textpane) {
864 super(
new BorderLayout());
865 scrollable = textpane;
870 public Dimension getPreferredScrollableViewportSize() {
871 return scrollable.getPreferredScrollableViewportSize();
875 public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation,
int direction) {
876 return scrollable.getScrollableBlockIncrement(visibleRect, orientation, direction);
880 public boolean getScrollableTracksViewportHeight() {
881 return scrollable.getScrollableTracksViewportHeight();
885 public boolean getScrollableTracksViewportWidth() {
886 return scrollable.getScrollableTracksViewportWidth();
890 public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation,
int direction) {
891 return scrollable.getScrollableUnitIncrement(visibleRect, orientation, direction);
896 private class FunctionKeyDispatcher
implements KeyEventDispatcher {
899 public boolean dispatchKeyEvent(KeyEvent ke) {
900 if (ke.getID() == KeyEvent.KEY_PRESSED) {
901 switch (ke.getKeyCode()) {
static void setWorkingDirectory(String workingDirectory)
void addCompilerListener(CompilerListener cl)
synchronized void addConfigurationListener(GuiConfigurationListener cf)
static final GuiConfiguration def
static String getString(String id)
DefaultStyledDocument getOutput()
void saveProgram(File file)
void setToggleBreakpoint(int position)
void init(AutoCompleteHook autoCompleteHook, CodeColorHook codeColorHook)
AbstractProgram getProgram()
void loadProgram(File file)
void addPluginMenues(JMenuBar mainMenu)
void windowIconified(WindowEvent we)
void windowOpened(WindowEvent we)
void windowClosing(WindowEvent arg0)
void fontsizeChanged(int fontsize)
void windowClosed(WindowEvent we)
void windowDeactivated(WindowEvent we)
void windowDeiconified(WindowEvent we)
void windowActivated(WindowEvent we)