Rev 15 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 15 | Rev 73 | ||
|---|---|---|---|
| 1 | /** |
1 | /** |
| 2 | * File created by Jimmy |
2 | * File created by Jimmy |
| 3 | * at 2003-dec-23 21:43:41 |
3 | * at 2003-dec-23 21:43:41 |
| 4 | */ |
4 | */ |
| 5 | package Macbeth; |
5 | package Macbeth; |
| 6 | 6 | ||
| 7 | import Macbeth.System.*; |
7 | import Macbeth.System.*; |
| 8 | import Macbeth.Utilities.*; |
8 | import Macbeth.Utilities.*; |
| 9 | import com.jgoodies.plaf.windows.ExtWindowsLookAndFeel; |
9 | import com.jgoodies.plaf.windows.ExtWindowsLookAndFeel; |
| 10 | import com.jgoodies.plaf.plastic.PlasticXPLookAndFeel; |
10 | import com.jgoodies.plaf.plastic.PlasticXPLookAndFeel; |
| 11 | import com.jgoodies.plaf.plastic.Plastic3DLookAndFeel; |
11 | import com.jgoodies.plaf.plastic.Plastic3DLookAndFeel; |
| 12 | import javax.swing.*; |
12 | import javax.swing.*; |
| 13 | import javax.swing.event.*; |
13 | import javax.swing.event.*; |
| 14 | import java.awt.*; |
14 | import java.awt.*; |
| 15 | import java.awt.event.*; |
15 | import java.awt.event.*; |
| 16 | import java.util.HashMap; |
16 | import java.util.HashMap; |
| 17 | import java.util.Iterator; |
17 | import java.util.Iterator; |
| 18 | import java.io.IOException; |
18 | import java.io.IOException; |
| 19 | import java.net.URL; |
19 | import java.net.URL; |
| 20 | 20 | ||
| 21 | /** |
21 | /** |
| 22 | * A full featured kernel with graphical user interface. |
22 | * A full featured kernel with graphical user interface. |
| 23 | * @author Jimmy |
23 | * @author Jimmy |
| 24 | */ |
24 | */ |
| 25 | public class GUIKernel extends MbKernel { |
25 | public class GUIKernel extends MbKernel { |
| 26 | 26 | ||
| 27 | //a list of references to all loaded module GUI windows |
27 | //a list of references to all loaded module GUI windows |
| 28 | private HashMap loadedModuleGUIs; |
28 | private HashMap loadedModuleGUIs; |
| 29 | //the module whose info page we're currently viewing |
29 | //the module whose info page we're currently viewing |
| 30 | private MbModule selectedModule; |
30 | private MbModule selectedModule; |
| 31 | 31 | ||
| 32 | /** |
32 | /** |
| 33 | * Creates a new instance of GUIKernel. |
33 | * Creates a new instance of GUIKernel. |
| 34 | * @param configFile The XML-configuration file to use. |
34 | * @param configFile The XML-configuration file to use. |
| 35 | */ |
35 | */ |
| 36 | public GUIKernel(String configFile) { |
36 | public GUIKernel(String configFile) { |
| 37 | super(configFile); |
37 | super(configFile); |
| 38 | selectedModule = null; |
38 | selectedModule = null; |
| 39 | //create GUI |
39 | //create GUI |
| 40 | try { |
40 | try { |
| 41 | _debug.println("Loading Swing look and feel"); |
41 | _debug.println("Loading Swing look and feel"); |
| 42 | //UIManager.setLookAndFeel(new ExtWindowsLookAndFeel()); |
42 | //UIManager.setLookAndFeel(new ExtWindowsLookAndFeel()); |
| 43 | UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); |
43 | UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); |
| 44 | } catch (Exception e) {} |
44 | } catch (Exception e) {} |
| 45 | _debug.println("Creating Swing GUI"); |
45 | _debug.println("Creating Swing GUI"); |
| 46 | GUI g = new GUI(); |
46 | GUI g = new GUI(); |
| 47 | g.setVisible(true); |
47 | g.setVisible(true); |
| 48 | try { |
48 | try { |
| 49 | startup(); |
49 | startup(); |
| 50 | } catch (MbStartupException e) { |
50 | } catch (MbStartupException e) { |
| 51 | _errors.println("Failed to start up kernel! (message: '" + e.getMessage() + "')"); |
51 | _errors.println("Failed to start up kernel! (message: '" + e.getMessage() + "')"); |
| 52 | shutdown(); |
52 | shutdown(); |
| 53 | } |
53 | } |
| 54 | g.updateHTMLBar(); |
54 | g.updateHTMLBar(); |
| 55 | } |
55 | } |
| 56 | 56 | ||
| 57 | /** |
57 | /** |
| 58 | * Gets a short description of the kernel. |
58 | * Gets a short description of the kernel. |
| 59 | * @return A short description of the kernel. |
59 | * @return A short description of the kernel. |
| 60 | */ |
60 | */ |
| 61 | public String description() { |
61 | public String description() { |
| 62 | return "Advanced kernel with graphical user interface"; |
62 | return "Advanced kernel with graphical user interface"; |
| 63 | } |
63 | } |
| 64 | 64 | ||
| 65 | /** |
65 | /** |
| 66 | * Starts up this kernel. |
66 | * Starts up this kernel. |
| 67 | */ |
67 | */ |
| 68 | public void startup() throws MbStartupException { |
68 | public void startup() throws MbStartupException { |
| 69 | //startup MbKernel |
69 | //startup MbKernel |
| 70 | super.startup(); |
70 | super.startup(); |
| 71 | loadedModuleGUIs = new HashMap(32); |
71 | loadedModuleGUIs = new HashMap(32); |
| 72 | } |
72 | } |
| 73 | 73 | ||
| 74 | /** |
74 | /** |
| 75 | * Shuts down this kernel. |
75 | * Shuts down this kernel. |
| 76 | */ |
76 | */ |
| 77 | public void shutdown() { |
77 | public void shutdown() { |
| 78 | //shut down MbKernel |
78 | //shut down MbKernel |
| 79 | super.shutdown(); |
79 | super.shutdown(); |
| 80 | } |
80 | } |
| 81 | 81 | ||
| 82 | /** |
82 | /** |
| 83 | * Finds out whether or not a module has a graphical user interface. |
83 | * Finds out whether or not a module has a graphical user interface. |
| 84 | * @param moduleName The classname of the module. |
84 | * @param moduleName The classname of the module. |
| 85 | * @return True if this module has a GUI, false otherwise (or if module wasn't found). |
85 | * @return True if this module has a GUI, false otherwise (or if module wasn't found). |
| 86 | */ |
86 | */ |
| 87 | public boolean moduleHasGUI(String moduleName) { |
87 | public boolean moduleHasGUI(String moduleName) { |
| 88 | //get the module |
88 | //get the module |
| 89 | MbModule m = (MbModule)loadedModules.get(moduleName); |
89 | MbModule m = (MbModule)loadedModules.get(moduleName); |
| 90 | if (m!=null) { |
90 | if (m!=null) { |
| 91 | //get its interfaces |
91 | //get its interfaces |
| 92 | Class[] interfaces = m.getClass().getInterfaces(); |
92 | Class[] interfaces = m.getClass().getInterfaces(); |
| 93 | //check whether the module implements the MbModuleGUI interface |
93 | //check whether the module implements the MbModuleGUI interface |
| 94 | for (int i=0; i<interfaces.length; i++) { |
94 | for (int i=0; i<interfaces.length; i++) { |
| 95 | if (interfaces[i].getName().equals("Macbeth.System.MbModuleGUI")) { |
95 | if (interfaces[i].getName().equals("Macbeth.System.MbModuleGUI")) { |
| 96 | return true; |
96 | return true; |
| 97 | } |
97 | } |
| 98 | } |
98 | } |
| 99 | } |
99 | } |
| 100 | return false; |
100 | return false; |
| 101 | } |
101 | } |
| 102 | 102 | ||
| 103 | /** |
103 | /** |
| 104 | * Gets the HTML-page from a specified module. |
104 | * Gets the HTML-page from a specified module. |
| 105 | * @param moduleName The classname of the module whose HTML-page you want to get. |
105 | * @param moduleName The classname of the module whose HTML-page you want to get. |
| 106 | * @return Full HTML-code for this modules HTML-page. If the specified module |
106 | * @return Full HTML-code for this modules HTML-page. If the specified module |
| 107 | * doesn't have a HTML-interface, its description is returned instead. |
107 | * doesn't have a HTML-interface, its description is returned instead. |
| 108 | */ |
108 | */ |
| 109 | public String getHTMLPage(String moduleName) { |
109 | public String getHTMLPage(String moduleName) { |
| 110 | //get the module |
110 | //get the module |
| 111 | MbModule mod = (MbModule)loadedModules.get(moduleName); |
111 | MbModule mod = (MbModule)loadedModules.get(moduleName); |
| 112 | //get its html-interface |
112 | //get its html-interface |
| 113 | MbHTMLInterface html = mod.getHTMLInterface(); |
113 | MbHTMLInterface html = mod.getHTMLInterface(); |
| 114 | //if this module has a HTML-interface |
114 | //if this module has a HTML-interface |
| 115 | if (html!=null) { |
115 | if (html!=null) { |
| 116 | //then return the HTML-page |
116 | //then return the HTML-page |
| 117 | return html.getHTMLPage(); |
117 | return html.getHTMLPage(); |
| 118 | //else, if this module doesn't have a html-interface |
118 | //else, if this module doesn't have a html-interface |
| 119 | } else { |
119 | } else { |
| 120 | //return description instead |
120 | //return description instead |
| 121 | return mod.description(); |
121 | return mod.description(); |
| 122 | } |
122 | } |
| 123 | } |
123 | } |
| 124 | 124 | ||
| 125 | /** |
125 | /** |
| 126 | * The whole graphical user interface for this kernel. |
126 | * The whole graphical user interface for this kernel. |
| 127 | */ |
127 | */ |
| 128 | private class GUI extends JFrame implements ActionListener,WindowListener { |
128 | private class GUI extends JFrame implements ActionListener,WindowListener { |
| 129 | //private JSplitPane contentArea; |
129 | //private JSplitPane contentArea; |
| 130 | private JEditorPane htmlBar; |
130 | private JEditorPane htmlBar; |
| 131 | private JScrollPane htmlBarScrolled; |
131 | private JScrollPane htmlBarScrolled; |
| 132 | private JTabbedPane tabbedArea; |
132 | private JTabbedPane tabbedArea; |
| 133 | private JEditorPane tabInfo; |
133 | private JEditorPane tabInfo; |
| 134 | private JScrollPane tabInfoScrolled; |
134 | private JScrollPane tabInfoScrolled; |
| 135 | private MDIDesktopPane tabGUI; |
135 | private MDIDesktopPane tabGUI; |
| 136 | private JScrollPane tabGUIScrolled; |
136 | private JScrollPane tabGUIScrolled; |
| 137 | //private JTextArea console; |
137 | //private JTextArea console; |
| 138 | private JEditorPane console; |
138 | private JEditorPane console; |
| 139 | //private MbHTMLDocument consoleDocument; |
139 | //private MbHTMLDocument consoleDocument; |
| 140 | private JScrollPane consoleScrolled; |
140 | private JScrollPane consoleScrolled; |
| 141 | private JMenuBar menuBar; |
141 | private JMenuBar menuBar; |
| 142 | 142 | ||
| 143 | public GUI() { |
143 | public GUI() { |
| 144 | setTitle("Macbeth GUI kernel"); |
144 | setTitle("Macbeth GUI kernel"); |
| 145 | 145 | ||
| 146 | //create html bar |
146 | //create html bar |
| 147 | htmlBar = new JEditorPane(); |
147 | htmlBar = new JEditorPane(); |
| 148 | htmlBar.setEditable(false); |
148 | htmlBar.setEditable(false); |
| 149 | htmlBar.setBorder(BorderFactory.createEmptyBorder()); |
149 | htmlBar.setBorder(BorderFactory.createEmptyBorder()); |
| 150 | htmlBar.setContentType("text/html"); |
150 | htmlBar.setContentType("text/html"); |
| 151 | htmlBar.addHyperlinkListener(new HyperlinkActionsHTMLBar()); |
151 | htmlBar.addHyperlinkListener(new HyperlinkActionsHTMLBar()); |
| 152 | htmlBarScrolled = new JScrollPane(htmlBar); |
152 | htmlBarScrolled = new JScrollPane(htmlBar); |
| 153 | htmlBarScrolled.setMinimumSize(new Dimension(100,100)); |
153 | htmlBarScrolled.setMinimumSize(new Dimension(100,100)); |
| 154 | htmlBarScrolled.setBorder(BorderFactory.createEmptyBorder()); |
154 | htmlBarScrolled.setBorder(BorderFactory.createEmptyBorder()); |
| 155 | 155 | ||
| 156 | //create info tab |
156 | //create info tab |
| 157 | tabInfo = new JEditorPane(); |
157 | tabInfo = new JEditorPane(); |
| 158 | tabInfo.setBorder(BorderFactory.createEmptyBorder()); |
158 | tabInfo.setBorder(BorderFactory.createEmptyBorder()); |
| 159 | tabInfo.setContentType("text/html"); |
159 | tabInfo.setContentType("text/html"); |
| 160 | tabInfo.addHyperlinkListener(new HyperlinkActionsInfoPage()); |
160 | tabInfo.addHyperlinkListener(new HyperlinkActionsInfoPage()); |
| 161 | tabInfo.setText("<html><h1>Macbeth!</h1></html>"); |
161 | tabInfo.setText("<html><h1>Macbeth!</h1></html>"); |
| 162 | tabInfo.setEditable(false); |
162 | tabInfo.setEditable(false); |
| 163 | tabInfoScrolled = new JScrollPane(tabInfo); |
163 | tabInfoScrolled = new JScrollPane(tabInfo); |
| 164 | tabInfoScrolled.setBorder(BorderFactory.createEmptyBorder()); |
164 | tabInfoScrolled.setBorder(BorderFactory.createEmptyBorder()); |
| 165 | 165 | ||
| 166 | //create gui tab |
166 | //create gui tab |
| 167 | tabGUI = new MDIDesktopPane(); |
167 | tabGUI = new MDIDesktopPane(); |
| 168 | tabGUI.setBorder(BorderFactory.createEmptyBorder()); |
168 | tabGUI.setBorder(BorderFactory.createEmptyBorder()); |
| 169 | tabGUIScrolled = new JScrollPane(tabGUI); |
169 | tabGUIScrolled = new JScrollPane(tabGUI); |
| 170 | tabGUIScrolled.setBorder(BorderFactory.createEmptyBorder()); |
170 | tabGUIScrolled.setBorder(BorderFactory.createEmptyBorder()); |
| 171 | 171 | ||
| 172 | //create tabbed view |
172 | //create tabbed view |
| 173 | tabbedArea = new JTabbedPane(); |
173 | tabbedArea = new JTabbedPane(); |
| 174 | tabbedArea.addTab("Info Page", null, tabInfoScrolled, "Module information"); |
174 | tabbedArea.addTab("Info Page", null, tabInfoScrolled, "Module information"); |
| 175 | tabbedArea.addTab("GUI Desktop", null, tabGUIScrolled, "Module GUI desktop"); |
175 | tabbedArea.addTab("GUI Desktop", null, tabGUIScrolled, "Module GUI desktop"); |
| 176 | tabbedArea.setPreferredSize(new Dimension(600,500)); |
176 | tabbedArea.setPreferredSize(new Dimension(600,500)); |
| 177 | tabbedArea.setMinimumSize(new Dimension(100,100)); |
177 | tabbedArea.setMinimumSize(new Dimension(100,100)); |
| 178 | tabbedArea.setBorder(BorderFactory.createEmptyBorder()); |
178 | tabbedArea.setBorder(BorderFactory.createEmptyBorder()); |
| 179 | 179 | ||
| 180 | //create console area |
180 | //create console area |
| 181 | console = new JEditorPane(); |
181 | console = new JEditorPane(); |
| 182 | console.setEditable(false); |
182 | console.setEditable(false); |
| 183 | console.setContentType("text/html"); |
183 | console.setContentType("text/html"); |
| 184 | //console = new JTextArea(); |
184 | //console = new JTextArea(); |
| 185 | //console.setMargin(new Insets(5,5,5,5)); |
185 | //console.setMargin(new Insets(5,5,5,5)); |
| 186 | console.setBorder(BorderFactory.createEmptyBorder()); |
186 | console.setBorder(BorderFactory.createEmptyBorder()); |
| 187 | consoleScrolled = new JScrollPane(console); |
187 | consoleScrolled = new JScrollPane(console); |
| 188 | consoleScrolled.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); |
188 | consoleScrolled.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); |
| 189 | consoleScrolled.setPreferredSize(new Dimension(600,80)); |
189 | consoleScrolled.setPreferredSize(new Dimension(600,80)); |
| 190 | consoleScrolled.setMinimumSize(new Dimension(200,50)); |
190 | consoleScrolled.setMinimumSize(new Dimension(200,50)); |
| 191 | consoleScrolled.setBorder(BorderFactory.createEmptyBorder()); |
191 | consoleScrolled.setBorder(BorderFactory.createEmptyBorder()); |
| 192 | consoleScrolled.addComponentListener( |
192 | consoleScrolled.addComponentListener( |
| 193 | new ComponentListener(){ |
193 | new ComponentListener(){ |
| 194 | //when console is resized, make sure it scrolls down to bottom |
194 | //when console is resized, make sure it scrolls down to bottom |
| 195 | public void componentResized(ComponentEvent e) { |
195 | public void componentResized(ComponentEvent e) { |
| 196 | //hmm....ugly hack, but it doesn't seem to work without the 0-position |
196 | //hmm....ugly hack, but it doesn't seem to work without the 0-position |
| 197 | console.setCaretPosition(0); |
197 | console.setCaretPosition(0); |
| 198 | console.setCaretPosition(console.getDocument().getLength()); |
198 | console.setCaretPosition(console.getDocument().getLength()); |
| 199 | } |
199 | } |
| 200 | public void componentMoved(ComponentEvent e) {} |
200 | public void componentMoved(ComponentEvent e) {} |
| 201 | public void componentShown(ComponentEvent e) {} |
201 | public void componentShown(ComponentEvent e) {} |
| 202 | public void componentHidden(ComponentEvent e) {} |
202 | public void componentHidden(ComponentEvent e) {} |
| 203 | }); |
203 | }); |
| 204 | 204 | ||
| 205 | _errors = new TextFormatterStream(new EditorPaneStream(console)); |
205 | _errors = new TextFormatterStream(new EditorPaneStream(console)); |
| 206 | ((TextFormatterStream)_errors).setPreString("<font size=\"-1\" color=\"red\">"); |
206 | ((TextFormatterStream)_errors).setPreString("<font size=\"-1\" color=\"red\">"); |
| 207 | ((TextFormatterStream)_errors).setPostString("</font>"); |
207 | ((TextFormatterStream)_errors).setPostString("</font>"); |
| 208 | _info = new TextFormatterStream(new EditorPaneStream(console)); |
208 | _info = new TextFormatterStream(new EditorPaneStream(console)); |
| 209 | ((TextFormatterStream)_info).setPreString("<font size=\"-1\" color=\"black\">"); |
209 | ((TextFormatterStream)_info).setPreString("<font size=\"-1\" color=\"black\">"); |
| 210 | ((TextFormatterStream)_info).setPostString("</font>"); |
210 | ((TextFormatterStream)_info).setPostString("</font>"); |
| 211 | _debug = new TextFormatterStream(new EditorPaneStream(console)); |
211 | _debug = new TextFormatterStream(new EditorPaneStream(console)); |
| 212 | ((TextFormatterStream)_debug).setPreString("<font size=\"-1\" color=\"#777777\">"); |
212 | ((TextFormatterStream)_debug).setPreString("<font size=\"-1\" color=\"#777777\">"); |
| 213 | ((TextFormatterStream)_debug).setPostString("</font>"); |
213 | ((TextFormatterStream)_debug).setPostString("</font>"); |
| 214 | 214 | ||
| 215 | //create menu bar |
215 | //create menu bar |
| 216 | menuBar = new JMenuBar(); |
216 | menuBar = new JMenuBar(); |
| 217 | setJMenuBar(menuBar); |
217 | setJMenuBar(menuBar); |
| 218 | JMenu menu; |
218 | JMenu menu; |
| 219 | JMenuItem menuItem; |
219 | JMenuItem menuItem; |
| 220 | menu = new JMenu("System"); |
220 | menu = new JMenu("System"); |
| 221 | menu.getAccessibleContext().setAccessibleDescription("System commands"); |
221 | menu.getAccessibleContext().setAccessibleDescription("System commands"); |
| 222 | menuBar.add(menu); |
222 | menuBar.add(menu); |
| 223 | menuItem = new JMenuItem("Restart modules"); |
223 | menuItem = new JMenuItem("Restart modules"); |
| 224 | menuItem.getAccessibleContext().setAccessibleDescription("Restart all modules"); |
224 | menuItem.getAccessibleContext().setAccessibleDescription("Restart all modules"); |
| 225 | menu.add(menuItem); |
225 | menu.add(menuItem); |
| 226 | menuItem = new JMenuItem("Restart kernel"); |
226 | menuItem = new JMenuItem("Restart kernel"); |
| 227 | menu.add(menuItem); |
227 | menu.add(menuItem); |
| 228 | menu.addSeparator(); |
228 | menu.addSeparator(); |
| 229 | menuItem = new JMenuItem("Quit"); |
229 | menuItem = new JMenuItem("Quit"); |
| 230 | menu.add(menuItem); |
230 | menu.add(menuItem); |
| 231 | 231 | ||
| 232 | //create a split pane that holds the HTML bar to the left and the tabview to the right |
232 | //create a split pane that holds the HTML bar to the left and the tabview to the right |
| 233 | JSplitPane splitHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new TitledControl(htmlBarScrolled,"Macbeth menu"),tabbedArea); |
233 | JSplitPane splitHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new TitledControl(htmlBarScrolled,"Macbeth menu"),tabbedArea); |
| 234 | splitHorizontal.setDividerLocation(130); |
234 | splitHorizontal.setDividerLocation(130); |
| 235 | splitHorizontal.setDividerSize(6); |
235 | splitHorizontal.setDividerSize(6); |
| 236 | //tabbedArea will get all extra space when resizing |
236 | //tabbedArea will get all extra space when resizing |
| 237 | splitHorizontal.setResizeWeight(0.0); |
237 | splitHorizontal.setResizeWeight(0.0); |
| 238 | //JWindowPane splitHorizontal = new JWindowPane(JWindowPane.HORIZONTAL,"Macbeth components",htmlBarScrolled,"Content",tabbedArea,null); |
238 | //JWindowPane splitHorizontal = new JWindowPane(JWindowPane.HORIZONTAL,"Macbeth components",htmlBarScrolled,"Content",tabbedArea,null); |
| 239 | 239 | ||
| 240 | //create a split pane that holds the the content at top and the console at bottom |
240 | //create a split pane that holds the the content at top and the console at bottom |
| 241 | JSplitPane splitVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT,splitHorizontal,new TitledControl(consoleScrolled,"Console")); |
241 | JSplitPane splitVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT,splitHorizontal,new TitledControl(consoleScrolled,"Console")); |
| 242 | splitVertical.setResizeWeight(0.8); |
242 | splitVertical.setResizeWeight(0.8); |
| 243 | //JWindowPane splitVertical = new JWindowPane(JWindowPane.VERTICAL,"top",splitHorizontal,"Console",consoleScrolled,null); |
243 | //JWindowPane splitVertical = new JWindowPane(JWindowPane.VERTICAL,"top",splitHorizontal,"Console",consoleScrolled,null); |
| 244 | 244 | ||
| 245 | //add everything to main frame |
245 | //add everything to main frame |
| 246 | Container content = this.getContentPane(); |
246 | Container content = this.getContentPane(); |
| 247 | content.setLayout(new BorderLayout()); |
247 | content.setLayout(new BorderLayout()); |
| 248 | content.add(splitVertical,BorderLayout.CENTER); |
248 | content.add(splitVertical,BorderLayout.CENTER); |
| 249 | pack(); |
249 | pack(); |
| 250 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); |
250 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); |
| 251 | addWindowListener(this); |
251 | addWindowListener(this); |
| 252 | } |
252 | } |
| 253 | 253 | ||
| 254 | /* EVENT HANDLERS... */ |
254 | /* EVENT HANDLERS... */ |
| 255 | public void actionPerformed(ActionEvent e) {} |
255 | public void actionPerformed(ActionEvent e) {} |
| 256 | public void windowClosing(WindowEvent e) { |
256 | public void windowClosing(WindowEvent e) { |
| 257 | //when kernel GUI is closed, it's time to shut down |
257 | //when kernel GUI is closed, it's time to shut down |
| 258 | shutdown(); |
258 | shutdown(); |
| 259 | setVisible(false); |
259 | setVisible(false); |
| 260 | _errors = System.err; |
260 | _errors = System.err; |
| 261 | _info = System.out; |
261 | _info = System.out; |
| 262 | _debug = System.out; |
262 | _debug = System.out; |
| 263 | _debug.println("GUI has been closed"); |
263 | _debug.println("GUI has been closed"); |
| 264 | _debug.println("Waiting for threads to stop"); |
264 | _debug.println("Waiting for threads to stop"); |
| 265 | dispose(); |
265 | dispose(); |
| 266 | } |
266 | } |
| 267 | public void windowOpened(WindowEvent e) {} |
267 | public void windowOpened(WindowEvent e) {} |
| 268 | public void windowClosed(WindowEvent e) {} |
268 | public void windowClosed(WindowEvent e) {} |
| 269 | public void windowIconified(WindowEvent e) {} |
269 | public void windowIconified(WindowEvent e) {} |
| 270 | public void windowDeiconified(WindowEvent e) {} |
270 | public void windowDeiconified(WindowEvent e) {} |
| 271 | public void windowActivated(WindowEvent e) {} |
271 | public void windowActivated(WindowEvent e) {} |
| 272 | public void windowDeactivated(WindowEvent e) {} |
272 | public void windowDeactivated(WindowEvent e) {} |
| 273 | 273 | ||
| 274 | /** |
274 | /** |
| 275 | * Responds to hyperlink clicks in the left HTML bar. |
275 | * Responds to hyperlink clicks in the left HTML bar. |
| 276 | */ |
276 | */ |
| 277 | class HyperlinkActionsHTMLBar implements HyperlinkListener { |
277 | class HyperlinkActionsHTMLBar implements HyperlinkListener { |
| 278 | public void hyperlinkUpdate(HyperlinkEvent e) { |
278 | public void hyperlinkUpdate(HyperlinkEvent e) { |
| 279 | if (e.getEventType()==HyperlinkEvent.EventType.ACTIVATED) { |
279 | if (e.getEventType()==HyperlinkEvent.EventType.ACTIVATED) { |
| 280 | URL url = e.getURL(); |
280 | URL url = e.getURL(); |
| 281 | String description = e.getDescription(); |
281 | String description = e.getDescription(); |
| 282 | //if a valid URL exists for the link |
282 | //if a valid URL exists for the link |
| 283 | if (url!=null) { |
283 | if (url!=null) { |
| 284 | //load the page in the main browser |
284 | //load the page in the main browser |
| 285 | try { |
285 | try { |
| 286 | tabInfo.setPage(url); |
286 | tabInfo.setPage(url); |
| 287 | selectedModule = null; |
287 | selectedModule = null; |
| 288 | } catch (IOException e1) { |
288 | } catch (IOException e1) { |
| 289 | e1.printStackTrace(); |
289 | e1.printStackTrace(); |
| 290 | } |
290 | } |
| 291 | } |
291 | } |
| 292 | //else, use the description to find out what to do |
292 | //else, use the description to find out what to do |
| 293 | else { |
293 | else { |
| 294 | //interprete the description as an internal macbeth command |
294 | //interprete the description as an internal macbeth command |
| 295 | String[] cmd = description.split(":"); |
295 | String[] cmd = description.split(":"); |
| 296 | if (cmd.length<=0) { |
296 | if (cmd.length<=0) { |
| 297 | return; |
297 | return; |
| 298 | } |
298 | } |
| 299 | //shows information on the specified macbeth component |
299 | //shows information on the specified macbeth component |
| 300 | if (cmd[0].equalsIgnoreCase("ShowInfo")) { |
300 | if (cmd[0].equalsIgnoreCase("ShowInfo")) { |
| 301 | tabInfo.setText(getHTMLPage(cmd[1])); |
301 | tabInfo.setText(getHTMLPage(cmd[1])); |
| 302 | selectedModule = (MbModule)loadedModules.get(cmd[1]); |
302 | selectedModule = (MbModule)loadedModules.get(cmd[1]); |
| 303 | } |
303 | } |
| 304 | //adds a module GUI to the GUI desktop |
304 | //adds a module GUI to the GUI desktop |
| 305 | else if (cmd[0].equalsIgnoreCase("ShowGUI")) { |
305 | else if (cmd[0].equalsIgnoreCase("ShowGUI")) { |
| 306 | loadModuleGUI(cmd[1]); |
306 | loadModuleGUI(cmd[1]); |
| 307 | } |
307 | } |
| 308 | //unloads a module |
308 | //unloads a module |
| 309 | else if (cmd[0].equalsIgnoreCase("Unload")) { |
309 | else if (cmd[0].equalsIgnoreCase("Unload")) { |
| 310 | unloadModule(cmd[1]); |
310 | unloadModule(cmd[1]); |
| 311 | updateHTMLBar(); |
311 | updateHTMLBar(); |
| 312 | } |
312 | } |
| 313 | //loads an unloaded module |
313 | //loads an unloaded module |
| 314 | else if (cmd[0].equalsIgnoreCase("Load")) { |
314 | else if (cmd[0].equalsIgnoreCase("Load")) { |
| 315 | try { |
315 | try { |
| 316 | loadModule(cmd[1]); |
316 | loadModule(cmd[1]); |
| 317 | } catch (Exception el) { |
317 | } catch (Exception el) { |
| 318 | _errors.println("Error loading module: " + el); |
318 | _errors.println("Error loading module: " + el); |
| 319 | } |
319 | } |
| 320 | updateHTMLBar(); |
320 | updateHTMLBar(); |
| 321 | } |
321 | } |
| 322 | } |
322 | } |
| 323 | 323 | ||
| 324 | } |
324 | } |
| 325 | } |
325 | } |
| 326 | } |
326 | } |
| 327 | 327 | ||
| 328 | /** |
328 | /** |
| 329 | * Responds to hyperlink clicks on module info page. |
329 | * Responds to hyperlink clicks on module info page. |
| 330 | */ |
330 | */ |
| 331 | class HyperlinkActionsInfoPage implements HyperlinkListener { |
331 | class HyperlinkActionsInfoPage implements HyperlinkListener { |
| 332 | public void hyperlinkUpdate(HyperlinkEvent e) { |
332 | public void hyperlinkUpdate(HyperlinkEvent e) { |
| 333 | if (e.getEventType()==HyperlinkEvent.EventType.ACTIVATED) { |
333 | if (e.getEventType()==HyperlinkEvent.EventType.ACTIVATED) { |
| 334 | URL url = e.getURL(); |
334 | URL url = e.getURL(); |
| 335 | String description = e.getDescription(); |
335 | String description = e.getDescription(); |
| 336 | //if a valid URL exists for the link |
336 | //if a valid URL exists for the link |
| 337 | if (url!=null) { |
337 | if (url!=null) { |
| 338 | //load the page in the main browser |
338 | //load the page in the main browser |
| 339 | try { |
339 | try { |
| 340 | tabInfo.setPage(url); |
340 | tabInfo.setPage(url); |
| 341 | } catch (IOException e1) { |
341 | } catch (IOException e1) { |
| 342 | e1.printStackTrace(); |
342 | e1.printStackTrace(); |
| 343 | } |
343 | } |
| 344 | } |
344 | } |
| 345 | //else, notify the current module about the click |
345 | //else, notify the current module about the click |
| 346 | else { |
346 | else { |
| 347 | if (selectedModule!=null) { |
347 | if (selectedModule!=null) { |
| 348 | MbHTMLInterface html = selectedModule.getHTMLInterface(); |
348 | MbHTMLInterface html = selectedModule.getHTMLInterface(); |
| 349 | if (html!=null) { |
349 | if (html!=null) { |
| 350 | html.linkPressed(description); |
350 | html.linkPressed(description); |
| 351 | } |
351 | } |
| 352 | } |
352 | } |
| 353 | } |
353 | } |
| 354 | 354 | ||
| 355 | } |
355 | } |
| 356 | } |
356 | } |
| 357 | } |
357 | } |
| 358 | 358 | ||
| 359 | public void updateHTMLBar() { |
359 | public void updateHTMLBar() { |
| 360 | String html = "<html>" + MySystem.lineBreak; |
360 | String html = "<html>" + MySystem.lineBreak; |
| 361 | html += "<body><b>Loaded modules</b><p>" + MySystem.lineBreak; |
361 | html += "<body><b>Loaded modules</b><p>" + MySystem.lineBreak; |
| 362 | //iterate through loaded modules-list |
362 | //iterate through loaded modules-list |
| 363 | Iterator it = loadedModules.keySet().iterator(); |
363 | Iterator it = loadedModules.keySet().iterator(); |
| 364 | while (it.hasNext()) { |
364 | while (it.hasNext()) { |
| 365 | String modname = (String)it.next(); |
365 | String modname = (String)it.next(); |
| 366 | html += "<b>" + modname + "</b><br>" + MySystem.lineBreak; |
366 | html += "<b>" + modname + "</b><br>" + MySystem.lineBreak; |
| 367 | html += " - [<a href=\"ShowInfo:" + modname + "\">Show Info</a>]<br>" + MySystem.lineBreak; |
367 | html += " - [<a href=\"ShowInfo:" + modname + "\">Show Info</a>]<br>" + MySystem.lineBreak; |
| 368 | if (moduleHasGUI(modname)) { |
368 | if (moduleHasGUI(modname)) { |
| 369 | html += " - [<a href=\"ShowGUI:" + modname + "\">Load GUI</a>]<br>" + MySystem.lineBreak; |
369 | html += " - [<a href=\"ShowGUI:" + modname + "\">Load GUI</a>]<br>" + MySystem.lineBreak; |
| 370 | } |
370 | } |
| 371 | html += " - [<a href=\"Unload:" + modname + "\">Unload</a>]<br>" + MySystem.lineBreak; |
371 | html += " - [<a href=\"Unload:" + modname + "\">Unload</a>]<br>" + MySystem.lineBreak; |
| 372 | } |
372 | } |
| 373 | html += "</p>" + MySystem.lineBreak; |
373 | html += "</p>" + MySystem.lineBreak; |
| 374 | html += "<b>Unloaded modules</b><p>"; |
374 | html += "<b>Unloaded modules</b><p>"; |
| 375 | //iterate through module list to find unloaded modules |
375 | //iterate through module list to find unloaded modules |
| 376 | it = moduleList.keySet().iterator(); |
376 | it = moduleList.keySet().iterator(); |
| 377 | while (it.hasNext()) { |
377 | while (it.hasNext()) { |
| 378 | String modname = (String)it.next(); |
378 | String modname = (String)it.next(); |
| 379 | //only show unloaded modules |
379 | //only show unloaded modules |
| 380 | if (!loadedModules.containsKey(modname)) { |
380 | if (!loadedModules.containsKey(modname)) { |
| 381 | html += "<b>" + modname + "</b><br>" + MySystem.lineBreak; |
381 | html += "<b>" + modname + "</b><br>" + MySystem.lineBreak; |
| 382 | html += " - [<a href=\"Load:" + modname + "\">Load</a>]<br>" + MySystem.lineBreak; |
382 | html += " - [<a href=\"Load:" + modname + "\">Load</a>]<br>" + MySystem.lineBreak; |
| 383 | } |
383 | } |
| 384 | } |
384 | } |
| 385 | html += "</p>" + MySystem.lineBreak; |
385 | html += "</p>" + MySystem.lineBreak; |
| 386 | html += "</body></html>"; |
386 | html += "</body></html>"; |
| 387 | htmlBar.setText(html); |
387 | htmlBar.setText(html); |
| 388 | } |
388 | } |
| 389 | 389 | ||
| 390 | 390 | ||
| 391 | /** |
391 | /** |
| 392 | * Loads the GUI for the specified module. |
392 | * Loads the GUI for the specified module. |
| 393 | * @param moduleName The module whose GUI should be loaded. |
393 | * @param moduleName The module whose GUI should be loaded. |
| 394 | */ |
394 | */ |
| 395 | public void loadModuleGUI(String moduleName) { |
395 | public void loadModuleGUI(String moduleName) { |
| 396 | //if a GUI is already loaded for this module |
396 | //if a GUI is already loaded for this module |
| 397 | if (loadedModuleGUIs.containsKey(moduleName)) { |
397 | if (loadedModuleGUIs.containsKey(moduleName)) { |
| 398 | //then bring this GUI to the front |
398 | //then bring this GUI to the front |
| 399 | ModuleGUIWindow w = (ModuleGUIWindow)loadedModuleGUIs.get(moduleName); |
399 | ModuleGUIWindow w = (ModuleGUIWindow)loadedModuleGUIs.get(moduleName); |
| 400 | w.moveToFront(); |
400 | w.moveToFront(); |
| 401 | return; |
401 | return; |
| 402 | } |
402 | } |
| 403 | //else, if this module does have a GUI |
403 | //else, if this module does have a GUI |
| 404 | else if (moduleHasGUI(moduleName)) { |
404 | else if (moduleHasGUI(moduleName)) { |
| 405 | //create a new window for the GUI |
405 | //create a new window for the GUI |
| 406 | MbModuleGUI i = (MbModuleGUI)loadedModules.get(moduleName); |
406 | MbModuleGUI i = (MbModuleGUI)loadedModules.get(moduleName); |
| 407 | ModuleGUIWindow w = new ModuleGUIWindow(moduleName); |
407 | ModuleGUIWindow w = new ModuleGUIWindow(moduleName); |
| 408 | //and render GUI into this window |
408 | //and render GUI into this window |
| 409 | i.renderGUI(w.getContentPane()); |
409 | i.renderGUI(w.getContentPane()); |
| 410 | w.setTitle(moduleName); |
410 | w.setTitle(moduleName); |
| 411 | //pack the contents to minimum possible size and show frame |
411 | //pack the contents to minimum possible size and show frame |
| 412 | w.pack(); |
412 | w.pack(); |
| 413 | w.setVisible(true); |
413 | w.setVisible(true); |
| 414 | tabGUI.add(w); |
414 | tabGUI.add(w); |
| 415 | } else { |
415 | } else { |
| 416 | //the module doesn't have any GUI |
416 | //the module doesn't have any GUI |
| 417 | } |
417 | } |
| 418 | } |
418 | } |
| 419 | 419 | ||
| 420 | /** |
420 | /** |
| 421 | * A window for a module GUI. This window will be shown |
421 | * A window for a module GUI. This window will be shown |
| 422 | * on the GUI desktop located inside the tabview. |
422 | * on the GUI desktop located inside the tabview. |
| 423 | */ |
423 | */ |
| 424 | private class ModuleGUIWindow extends JInternalFrame implements InternalFrameListener { |
424 | private class ModuleGUIWindow extends JInternalFrame implements InternalFrameListener { |
| 425 | private String moduleName; |
425 | private String moduleName; |
| 426 | 426 | ||
| 427 | /** |
427 | /** |
| 428 | * Creates a new GUI window. |
428 | * Creates a new GUI window. |
| 429 | * @param moduleName The name of the module. |
429 | * @param moduleName The name of the module. |
| 430 | */ |
430 | */ |
| 431 | public ModuleGUIWindow(String moduleName) { |
431 | public ModuleGUIWindow(String moduleName) { |
| 432 | super(); |
432 | super(); |
| 433 | this.moduleName = moduleName; |
433 | this.moduleName = moduleName; |
| 434 | setDefaultCloseOperation(DISPOSE_ON_CLOSE); |
434 | setDefaultCloseOperation(DISPOSE_ON_CLOSE); |
| 435 | setResizable(true); |
435 | setResizable(true); |
| 436 | setClosable(true); |
436 | setClosable(true); |
| 437 | setMaximizable(false); |
437 | setMaximizable(false); |
| 438 | addInternalFrameListener(this); |
438 | addInternalFrameListener(this); |
| 439 | } |
439 | } |
| 440 | 440 | ||
| 441 | public void internalFrameOpened(InternalFrameEvent e) { |
441 | public void internalFrameOpened(InternalFrameEvent e) { |
| 442 | //put a reference to this window into the hashmap |
442 | //put a reference to this window into the hashmap |
| 443 | loadedModuleGUIs.put(moduleName,this); |
443 | loadedModuleGUIs.put(moduleName,this); |
| 444 | } |
444 | } |
| 445 | 445 | ||
| 446 | public void internalFrameClosed(InternalFrameEvent e) { |
446 | public void internalFrameClosed(InternalFrameEvent e) { |
| 447 | //remove our reference from the hashmap |
447 | //remove our reference from the hashmap |
| 448 | loadedModuleGUIs.remove(moduleName); |
448 | loadedModuleGUIs.remove(moduleName); |
| 449 | } |
449 | } |
| 450 | 450 | ||
| 451 | public void internalFrameClosing(InternalFrameEvent e) {} |
451 | public void internalFrameClosing(InternalFrameEvent e) {} |
| 452 | public void internalFrameIconified(InternalFrameEvent e) {} |
452 | public void internalFrameIconified(InternalFrameEvent e) {} |
| 453 | public void internalFrameDeiconified(InternalFrameEvent e) {} |
453 | public void internalFrameDeiconified(InternalFrameEvent e) {} |
| 454 | public void internalFrameActivated(InternalFrameEvent e) {} |
454 | public void internalFrameActivated(InternalFrameEvent e) {} |
| 455 | public void internalFrameDeactivated(InternalFrameEvent e) {} |
455 | public void internalFrameDeactivated(InternalFrameEvent e) {} |
| 456 | } |
456 | } |
| 457 | } |
457 | } |
| 458 | 458 | ||
| 459 | 459 | ||
| 460 | /** |
460 | /** |
| 461 | * Program entry point. |
461 | * Program entry point. |
| 462 | * @param args The command line arguments. |
462 | * @param args The command line arguments. |
| 463 | */ |
463 | */ |
| 464 | public static void main(String[] args) { |
464 | public static void main(String[] args) { |
| 465 | String configFile = "Config\\Kernel.xml"; |
465 | String configFile = "Config\\Kernel.xml"; |
| 466 | //config file can also be specified with command line args |
466 | //config file can also be specified with command line args |
| 467 | if (args.length>0) { |
467 | if (args.length>0) { |
| 468 | configFile = args[0]; |
468 | configFile = args[0]; |
| 469 | } |
469 | } |
| 470 | //create new kernel |
470 | //create new kernel |
| 471 | new GUIKernel(configFile); |
471 | new GUIKernel(configFile); |
| 472 | } |
472 | } |
| 473 | 473 | ||
| 474 | } |
474 | } |
| 475 | 475 | ||