package ui; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileOutputStream; import java.lang.reflect.Method; import java.util.LinkedList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.JToolBar; import ui.annotations.MainActionInfo; import ui.bigstep.BigStepGUI; import ui.newgui.DefaultEditorAction; import ui.newgui.EditorAction; import ui.newgui.EditorComponent; import ui.newgui.FileWindow; import ui.newgui.MainWindow; import ui.smallstep.SmallStepGUI; import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable; import expressions.Expression; /** * An Editor in the UI. It contains the sourcefile and the excecutions. * * @author cfehling * */ public class EditorWindow extends JPanel implements FileWindow { private static final long serialVersionUID = -5830307198539052787L; private SourceFile file; private File systemfile = null; private JToolBar menu; private JToolBar actions; private EditorComponent shownComponent; private List<DefaultEditorAction> fileactions; private List<DefaultEditorAction> runactions; private List<DefaultEditorAction> toolbaractions; private List<DefaultEditorAction> editactions; private Hashtable myactions; private boolean modified; /** * Constructor. * * @param ifile * The file to display. */ public EditorWindow(SourceFile ifile, MainWindow imywindow) { file = ifile; file.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("modified")) { EditorWindow.this.setModified((Boolean) evt.getNewValue()); ((DefaultEditorAction) myactions.get("Save")) .setEnabled((Boolean) evt.getNewValue()); } else if (evt.getPropertyName().equals("filename")) { firePropertyChange("name", evt.getOldValue(), evt .getNewValue()); } } }); JPanel menupanel = new JPanel(); // TODO DONT use BorderLayout!! menupanel.setLayout(new BorderLayout()); menu = new JToolBar(); actions = new JToolBar(); setShownComponent(file); fileactions = new LinkedList<DefaultEditorAction>(); runactions = new LinkedList<DefaultEditorAction>(); toolbaractions = new LinkedList<DefaultEditorAction>(); editactions = new LinkedList<DefaultEditorAction>(); myactions = new Hashtable(); // modified = false; this.setLayout(new BorderLayout()); menu.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); addEditorComponent(file); add(menupanel, BorderLayout.NORTH); menupanel.add(menu, BorderLayout.WEST); menupanel.add(actions, BorderLayout.CENTER); generateActions(); setActionStatus("Undo", shownComponent.getAction("Undo").isEnabled()); setActionStatus("Redo", shownComponent.getAction("Redo").isEnabled()); } public String getTitle() { return file.getFilename(); } private void generateActions() { Class me = this.getClass(); Method[] methods = me.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { final Method tmp = methods[i]; MainActionInfo actioninfo = tmp.getAnnotation(MainActionInfo.class); if (actioninfo != null) { DefaultEditorAction newaction = new DefaultEditorAction(); newaction.setTitle(actioninfo.name()); newaction.setEnabled(true); myactions.put(tmp.getName().substring(6), newaction); if (!actioninfo.icon().equals("none")) { java.net.URL imgURL = EditorWindow.class .getResource(actioninfo.icon()); if (imgURL != null) { newaction.setIcon(new ImageIcon(imgURL)); } else { System.out.println("Imagefile not found!"); } } newaction.setGroup(1); newaction.setAccelModifiers(actioninfo.accelModifiers()); newaction.setAccelKey(actioninfo.accelKey()); newaction.setActionlistener(new ActionListener() { public void actionPerformed(ActionEvent event) { try { tmp.invoke(EditorWindow.this); } catch (Exception e) { e.printStackTrace(); // TODO Add Handling!! } } }); if (actioninfo.visibleToolbar() == MainActionInfo.TOOLBAR_VISIBLE) { toolbaractions.add(newaction); } if (actioninfo.visibleMenu() == MainActionInfo.MENU_FILE) { fileactions.add(newaction); } if (actioninfo.visibleMenu() == MainActionInfo.MENU_RUN) { runactions.add(newaction); } if (actioninfo.visibleMenu() == MainActionInfo.MENU_EDIT) { editactions.add(newaction); } } } } @MainActionInfo(name = "Save", icon = "icons/save.png", visibleMenu = MainActionInfo.MENU_FILE, visibleToolbar = MainActionInfo.TOOLBAR_VISIBLE, accelModifiers = KeyEvent.CTRL_MASK, accelKey = KeyEvent.VK_S) public boolean handleSave() { if (systemfile == null) { return handleSaveAs(); } else { return writeFile(); } } @MainActionInfo(name = "SaveAs", icon = "icons/saveas.png", visibleMenu = MainActionInfo.MENU_FILE, visibleToolbar = MainActionInfo.TOOLBAR_VISIBLE, accelModifiers = KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, accelKey = KeyEvent.VK_S) public boolean handleSaveAs() { JFileChooser chooser = new JFileChooser(); chooser.showSaveDialog(this); File outfile = chooser.getSelectedFile(); if (outfile != null) { try { outfile.createNewFile(); systemfile = outfile; String oldname = file.getFilename(); String newname = outfile.getName(); file.setFilename(newname); firePropertyChange("name", oldname, newname); writeFile(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } else { return false; } } @MainActionInfo(name = "Undo", icon = "icons/undo.gif", visibleMenu = MainActionInfo.MENU_EDIT, visibleToolbar = MainActionInfo.TOOLBAR_VISIBLE, accelModifiers = KeyEvent.CTRL_MASK, accelKey = KeyEvent.VK_Z) public void handleUndo() { shownComponent.handleUndo(); } @MainActionInfo(name = "Redo", icon = "icons/redo.gif", visibleMenu = MainActionInfo.MENU_EDIT, visibleToolbar = MainActionInfo.TOOLBAR_VISIBLE, accelModifiers = KeyEvent.CTRL_MASK, accelKey = KeyEvent.VK_Y) public void handleRedo() { shownComponent.handleRedo(); } @MainActionInfo(name = "SmallStep", icon = "none", visibleMenu = MainActionInfo.MENU_RUN, visibleToolbar = MainActionInfo.TOOLBAR_HIDDEN, accelModifiers = KeyEvent.VK_UNDEFINED, accelKey = KeyEvent.VK_F11) public void handleSmallStep() { try { SmallStepGUI gui = new SmallStepGUI("SmallStep", file.getDocument() .getText(0, file.getDocument().getLength())); addEditorComponent(gui); setActionStatus("Undo", gui.getAction("Undo").isEnabled()); setActionStatus("Redo", gui.getAction("Redo").isEnabled()); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } @MainActionInfo(name = "BigStep", icon = "none", visibleMenu = MainActionInfo.MENU_RUN, visibleToolbar = MainActionInfo.TOOLBAR_HIDDEN, accelModifiers = KeyEvent.VK_UNDEFINED, accelKey = KeyEvent.VK_UNDEFINED) public void handleBigStep() { try { BigStepGUI gui = new BigStepGUI("BigStep", file.getDocument() .getText(0, file.getDocument().getLength())); addEditorComponent(gui); setActionStatus("Undo", gui.getAction("Undo").isEnabled()); setActionStatus("Redo", gui.getAction("Redo").isEnabled()); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } @MainActionInfo(name = "TypeChecker", icon = "none", visibleMenu = MainActionInfo.MENU_RUN, visibleToolbar = MainActionInfo.TOOLBAR_HIDDEN, accelModifiers = KeyEvent.VK_UNDEFINED, accelKey = KeyEvent.VK_F12) public void handleTypeChecker() { try { Expression e = file.getDocument().getExpression(); TypeCheckerGUI gui = new TypeCheckerGUI("TypeChecker"); gui.startTypeChecking(e); addEditorComponent(gui); setActionStatus("Undo", gui.getAction("Undo").isEnabled()); setActionStatus("Redo", gui.getAction("Redo").isEnabled()); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } private void addEditorComponent(EditorComponent comp) { JToggleButton compbutton = new JToggleButton(comp.getTitle()); Component[] buttons = menu.getComponents(); boolean existed = false; for (int i = 0; i < buttons.length; i++) { if (((JToggleButton) buttons[i]).getLabel().equals(comp.getTitle())) { compbutton = (JToggleButton) buttons[i]; compbutton .removeActionListener(compbutton.getActionListeners()[0]); existed = true; break; } } compbutton.addActionListener(new EditorComponentListener(this, comp, compbutton)); deselectButtons(); compbutton.setSelected(true); if (!existed) menu.add(compbutton); remove((Component) getShownComponent()); add((Component) comp, BorderLayout.CENTER); setShownComponent(comp); updateActions(comp); paintAll(getGraphics()); } public void deselectButtons() { Component[] buttons = menu.getComponents(); for (int i = 0; i < buttons.length; i++) { ((JToggleButton) buttons[i]).setSelected(false); } } private boolean writeFile() { try { FileOutputStream out = new FileOutputStream(systemfile); out.write(file.getDocument().getText(0, file.getDocument().getLength()).getBytes()); out.flush(); out.close(); file.setModified(false); return true; } catch (Exception e) { // TODO Add Handling!! System.out.println("Error while saving!"); return false; } } public void updateActions(EditorComponent comp) { actions.removeAll(); addActions(comp.getActions(), actions); } private void addActions(List<EditorAction> list, JComponent component) { List<EditorAction> actionlist = list; for (int i = 0; i < actionlist.size(); i++) { final EditorAction action = actionlist.get(i); if (action.isVisible()) { final JButton tmp; if (action.getIcon() == null) { tmp = new JButton(action.getTitle()); } else { tmp = new JButton(action.getIcon()); tmp.setToolTipText(action.getTitle()); } tmp.setEnabled(action.isEnabled()); // tmp.setAccelerator(KeyStroke.getKeyStroke(action.getAccelKey(),action.getAccelModifiers())); action.addPropertyChangeListener("enabled", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { tmp.setEnabled(action.isEnabled()); } }); component.add(tmp); tmp.addActionListener(action.getActionListener()); } } } public EditorComponent getShownComponent() { return shownComponent; } public void setShownComponent(EditorComponent ishownComponent) { shownComponent = ishownComponent; EditorAction undo = shownComponent.getAction("Undo"); EditorAction redo = shownComponent.getAction("Redo"); undo.addPropertyChangeListener("enabled", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { setActionStatus("Undo", (Boolean) evt.getNewValue()); } }); // TODO this is dirty... nullpointer on initialisation try { setActionStatus("Undo", undo.isEnabled()); } catch (Exception e) { } redo.addPropertyChangeListener("enabled", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { setActionStatus("Redo", (Boolean) evt.getNewValue()); } }); // TODO this is dirty... nullpointer on initialisation try { setActionStatus("Redo", redo.isEnabled()); } catch (Exception e) { } } public void setActionStatus(String action, boolean enabled) { ((DefaultEditorAction) myactions.get(action)).setEnabled(enabled); } public List<EditorAction> getFileActions() { List<EditorAction> tmp = new LinkedList<EditorAction>(); tmp.addAll(fileactions); return tmp; } public List<EditorAction> getToolbarActions() { List<EditorAction> tmp = new LinkedList<EditorAction>(); tmp.addAll(toolbaractions); return tmp; } public List<EditorAction> getEditActions() { List<EditorAction> tmp = new LinkedList<EditorAction>(); tmp.addAll(editactions); return tmp; } public List<EditorAction> getRunActions() { List<EditorAction> tmp = new LinkedList<EditorAction>(); tmp.addAll(runactions); return tmp; } public JToolBar getMenu() { return menu; } public SourceFile getFile() { return file; } public void setFile(SourceFile file) { this.file = file; } public File getSystemfile() { return systemfile; } public void setSystemfile(File systemfile) { this.systemfile = systemfile; } public boolean isModified() { return modified; } public void setModified(boolean modified) { this.modified = modified; } }