source: release-kits/shared/ant-installer/src/org/tp23/antinstaller/runtime/SwingRunner.java@ 17858

Last change on this file since 17858 was 17858, checked in by oranfry, 15 years ago

os conditional font selection

File size: 12.8 KB
Line 
1/*
2 * Copyright 2005 Paul Hinds
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.tp23.antinstaller.runtime;
17
18import java.awt.GraphicsConfiguration;
19import java.awt.Toolkit;
20import java.awt.Dimension;
21import java.io.ByteArrayOutputStream;
22import java.io.InputStream;
23import java.util.ArrayList;
24import java.util.List;
25import java.util.ResourceBundle;
26
27import javax.swing.ImageIcon;
28import javax.swing.JFrame;
29
30import org.tp23.antinstaller.InstallException;
31import org.tp23.antinstaller.Installer;
32import org.tp23.antinstaller.InstallerContext;
33import org.tp23.antinstaller.ValidationException;
34import org.tp23.antinstaller.antmod.FeedbackListener;
35import org.tp23.antinstaller.page.Page;
36import org.tp23.antinstaller.renderer.AntOutputRenderer;
37import org.tp23.antinstaller.renderer.RendererFactory;
38import org.tp23.antinstaller.renderer.swing.PageCompletionListener;
39import org.tp23.antinstaller.renderer.swing.SizeConstants;
40import org.tp23.antinstaller.renderer.swing.SwingInstallerContext;
41import org.tp23.antinstaller.renderer.swing.SwingMessageRenderer;
42import org.tp23.antinstaller.renderer.swing.SwingPageRenderer;
43
44import java.util.Enumeration;
45import java.awt.Font;
46import javax.swing.plaf.FontUIResource;
47import javax.swing.UIManager;
48
49
50
51/**
52 * <p>Runs the installer in a JFrame window </p>
53 * <p>This class uses the Installer object tree as its data source and renderers
54 * from the org.tp23.antinstaller.renderer.swing package </p>
55 * Runners must also create a MessageRenderer and make it available in the
56 * InstallerContext
57 * <p>Copyright: Copyright (c) 2004</p>
58 * <p>Company: tp23</p>
59 *
60 * @author Paul Hinds
61 * @version $Id: SwingRunner.java,v 1.11 2007/01/19 00:24:36 teknopaul Exp $
62 */
63public class SwingRunner extends AntRunner implements Runner, PageCompletionListener {
64
65 protected SwingInstallerContext swingCtx = null;
66 private JFrame frame = new JFrame();
67 private List pageRenderers;
68 private volatile boolean doAnt = false;
69 protected Thread initialThread;
70 protected IfPropertyHelper ifHelper;
71 // context local property refs
72 protected InstallerContext ctx;
73 protected Logger logger;
74 protected Installer installer;
75
76 public SwingRunner(InstallerContext ctx) {
77 super(ctx);
78 swingCtx = new SwingInstallerContext(ctx, frame);
79
80 SwingMessageRenderer smr = new SwingMessageRenderer();
81 smr.setOwner(frame);
82 ctx.setMessageRenderer(smr);
83
84 ctx.setBuildListener(new FeedbackListener(swingCtx));
85
86 ifHelper = new IfPropertyHelper(ctx);
87 logger = ctx.getLogger();
88 installer = ctx.getInstaller();
89 this.ctx = ctx;
90 }
91
92 /**
93 * Renders the installer in a Swing GUI, this method blocks until
94 * the UI has finished
95 *
96 * @return boolean false implies user aborted
97 * @throws InstallException
98 */
99 public boolean runInstaller() throws InstallException {
100 try {
101 frame.setTitle(installer.getName());
102 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
103 frame.setSize(SizeConstants.PAGE_WIDTH, SizeConstants.PAGE_HEIGHT);
104 frame.getRootPane().setDoubleBuffered(true);
105 frame.setResizable( true );
106
107 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
108 frame.setLocation(screenSize.width/2 - frame.getWidth()/2, screenSize.height/2 - frame.getHeight()/2);
109
110 //setLocation(frame);
111 setIcon(frame, installer);
112
113 //set font
114 String new_default_font_str = null;
115 if ( System.getProperty("os.name").equals("Linux") ) {
116 new_default_font_str = "Bitstream Cyberbit";
117 } else if ( System.getProperty("os.name").startsWith("Windows") ) {
118 new_default_font_str = "Arial Unicode MS";
119 }
120
121 if ( new_default_font_str != null ) {
122
123 FontUIResource default_font = new FontUIResource(new_default_font_str, Font.PLAIN, 12);
124 Enumeration keys = UIManager.getDefaults().keys();
125 while (keys.hasMoreElements()) {
126 Object key = keys.nextElement();
127 Object value = UIManager.get(key);
128 if (value instanceof FontUIResource) {
129 UIManager.put(key, default_font);
130 }
131 }
132
133 }
134
135 preparePages(installer.getPages(), ctx);
136 showFirstPage();
137 // need to block here until pages are complete
138 initialThread = Thread.currentThread();
139 try {
140 Thread.sleep(Long.MAX_VALUE);
141 }
142 catch (InterruptedException ex1) {
143
144 }
145 return doAnt;
146 }
147 catch (Exception ex) {
148 logger.log("Fatal exception: " + ex.getMessage());
149 if (ctx.getInstaller().isVerbose()) {
150 logger.log(ex);
151 }
152 ctx.getMessageRenderer().printMessage("Fatal exception: " + ex.getMessage());
153 throw new InstallException("", ex);
154 }
155 }
156
157 public void pageBack(Page page) {
158 if (page.isAbort()) {
159 abort();
160 return;
161 }
162 Page[] pages = installer.getPages();
163 for (int i = 0; i < pages.length; i++) {
164 if (pages[i] == page) {
165 // found current page
166 if (i > 0) {
167
168 //skip pages if the ifTarget or ifProperty attributes exist and fail
169 int nextIdx = i - 1;
170 try {
171 while (true) {
172 if (!ifHelper.ifTarget(pages[nextIdx], pages) ||
173 !ifHelper.ifProperty(pages[nextIdx])) {
174 //Continue looping
175 --nextIdx;
176 } else {
177 break;
178 }
179 }
180 }
181 catch (InstallException instExc) {
182 logger.log("InstallException rendering page:" + page.getName());
183 logger.log(installer, instExc);
184 }
185
186 //for(;ifTargetSkip(pages[nextIdx], pages);nextIdx--);
187
188 SwingPageRenderer renderer = (SwingPageRenderer) pageRenderers.get(nextIdx);
189 ctx.setCurrentPage(pages[nextIdx]);
190 try {
191 renderNext(renderer);
192 }
193 catch (InstallException ex) {
194 logger.log("InstallExcepiton rendering page:" + page.getName());
195 logger.log(installer, ex);
196 }
197 catch (ClassNotFoundException ex) {
198 logger.log("ClassNotFoundException rendering page:" + page.getName());
199 logger.log(installer, ex);
200 }
201 return;
202 }
203 }
204 }
205 }
206
207 /**
208 * Called when a page is complete and the next button is pressed.
209 * This method is called by the event thread that looses exceptions so Throwable
210 * is caught
211 *
212 * @param page Page
213 */
214 public void pageComplete(Page page) {
215 try {
216 if (page.isAbort()) {
217 abort();
218 return;
219 }
220 runPost(page);
221 Page[] pages = installer.getPages();
222 SwingPageRenderer currentRenderer;
223 for (int i = 0; i < pages.length; i++) {
224 if (pages[i] == page) { // found current page
225 currentRenderer = (SwingPageRenderer) pageRenderers.get(i);
226 // check validation
227 boolean validationPassed = false;
228 try {
229 currentRenderer.updateInputFields();
230 validationPassed = currentRenderer.validateFields();
231 } catch (ValidationException ve) {
232 logger.log("ValidationException rendering page:" + page.getName());
233 logger.log(installer, ve);
234 return;
235 }
236 if (!validationPassed) {
237 return;
238 }
239
240
241 if (i < pages.length - 1) {
242
243 //more pages left
244
245 // skip the page if the ifTarget or ifProperty dictate it
246 int nextIdx = i + 1;
247 while (true) {
248 if (!ifHelper.ifTarget(pages[nextIdx], pages) ||
249 !ifHelper.ifProperty(pages[nextIdx])) {
250 //Continue looping
251 nextIdx++;
252 } else {
253 break;
254 }
255 }
256
257
258 SwingPageRenderer renderer = (SwingPageRenderer) pageRenderers.get(nextIdx);
259 ctx.setCurrentPage(pages[nextIdx]);
260 try {
261 renderNext(renderer);
262 }
263 catch (InstallException ex) {
264 logger.log("InstallException rendering page:" + page.getName());
265 logger.log(installer, ex);
266 }
267 catch (ClassNotFoundException ex) {
268 logger.log("ClassNotFoundException rendering page:" + page.getName());
269 logger.log(installer, ex);
270 }
271 return;
272 }
273 if (i == pages.length - 1) {
274 // all done
275 currentRenderer.getBackButton().setEnabled(false);
276 currentRenderer.getNextButton().setEnabled(false);
277 currentRenderer.getFinishButton().setEnabled(false);
278 doAnt = true;
279 initialThread.interrupt();
280 return;
281 }
282 }
283 }
284 }
285 catch (Throwable e) {
286 ctx.log("Throwable during page completion:" + e.getMessage());
287 if (ctx.getInstaller().isVerbose()) {
288 ctx.log(e);
289 }
290 }
291 }
292
293 protected void showFirstPage() throws Exception {
294 ctx.setCurrentPage(installer.getPages()[0]);
295 renderNext((SwingPageRenderer) pageRenderers.get(0));
296 }
297
298
299 private void preparePages(Page[] pages, InstallerContext ctx) throws Exception {
300 pageRenderers = new ArrayList();
301 for (int i = 0; i < pages.length; i++) {
302 SwingPageRenderer renderer = RendererFactory.getSwingPageRenderer(pages[i]);
303 if (i == 0) renderer.getBackButton().setEnabled(false);
304 renderer.setContext(swingCtx);
305 renderer.setPageCompletionListener(this);
306 renderer.setPage(pages[i]);
307 renderer.instanceInit();
308 pageRenderers.add(renderer);
309 if (renderer instanceof AntOutputRenderer) {
310 ctx.setAntOutputRenderer((AntOutputRenderer) renderer);
311 }
312 }
313 }
314
315 protected void renderNext(SwingPageRenderer renderer) throws ClassNotFoundException, InstallException {
316 renderer.reInit();
317 renderer.reInstanceInit();
318
319 renderer.updateDefaultValues();
320 frame.getContentPane().removeAll();
321 frame.getContentPane().add(renderer);
322 frame.getContentPane().repaint();
323 frame.show();
324 if (renderer.getNextButton().isEnabled()) {
325 renderer.getNextButton().requestFocus();
326 } else if (renderer.getFinishButton().isEnabled()) {
327 renderer.getFinishButton().requestFocus();
328 }
329 }
330
331 private void setLocation(JFrame frame) {
332 GraphicsConfiguration config = frame.getGraphicsConfiguration();
333 int x = (int) config.getBounds().getCenterX() - (SizeConstants.PAGE_WIDTH / 2);
334 int y = (int) config.getBounds().getCenterY() - (SizeConstants.PAGE_HEIGHT / 2);
335 frame.setLocation(x, y);
336 frame.setResizable(false);
337 }
338
339 private void setIcon(JFrame frame, Installer installer) {
340 String iconResource = installer.getWindowIcon();
341 try {
342 if (iconResource == null) {
343 return;
344 }
345 InputStream in = this.getClass().getResourceAsStream(iconResource);
346 ByteArrayOutputStream baos = new ByteArrayOutputStream();
347 byte[] buffer = new byte[256];
348 int read = 0; // The number of bytes read from the stream
349 for (read = in.read(buffer); read != -1; read = in.read(buffer)) {
350 baos.write(buffer, 0, read);
351 }
352 ImageIcon icon = new ImageIcon(baos.toByteArray());
353 //Image icon = Toolkit.getDefaultToolkit().createImage(baos.toByteArray());
354 frame.setIconImage(icon.getImage());
355 }
356 catch (Exception ex) {
357 // we can live with out an icon
358 logger.log("Can not load icon resource: " + iconResource);
359 logger.log(installer, ex);
360 }
361 }
362
363 public void antFinished() {
364 SwingPageRenderer renderer = (SwingPageRenderer) pageRenderers.get(pageRenderers.size() - 1);
365 renderer.getBackButton().setEnabled(false);
366 renderer.getNextButton().setEnabled(false);
367 renderer.getCancelButton().setEnabled(false);
368 renderer.getFinishButton().setText(org.tp23.antinstaller.Installer.langPack.getString("exit"));
369 renderer.getFinishButton().setEnabled(true);
370 renderer.getFinishButton().requestFocus();
371 renderer.getTitleLabel().setText(org.tp23.antinstaller.Installer.langPack.getString("complete"));
372 renderer.stopPage();
373 ctx.getAntOutputRenderer().getErr().flush();
374 ctx.getAntOutputRenderer().getOut().flush();
375 ctx.getMessageRenderer().printMessage(org.tp23.antinstaller.Installer.langPack.getString("finished"));
376 }
377
378 public void fatalError() {
379 List renderers = getPageRenderers();
380 if ((renderers != null) && (renderers.size() > 0)) {
381 SwingPageRenderer renderer = (SwingPageRenderer) renderers.get(renderers.size() - 1);
382 renderer.getBackButton().setEnabled(false);
383 renderer.getNextButton().setEnabled(false);
384 renderer.getCancelButton().setEnabled(false);
385 renderer.getFinishButton().setText(org.tp23.antinstaller.Installer.langPack.getString("exit"));
386 renderer.getFinishButton().setEnabled(true);
387 renderer.getFinishButton().requestFocus();
388 renderer.stopPage();
389 renderer.getTitleLabel().setText(org.tp23.antinstaller.Installer.langPack.getString("failed"));
390 }
391 // else - we're done here, or should we call abort()?
392 }
393
394 /**
395 * Returns a string representation of the object.
396 *
397 * @return a string representation of the object.
398 */
399 public String toString() {
400 return "SwingRunner";
401 }
402
403 private void abort() {
404 this.doAnt = false;
405 initialThread.interrupt();
406 }
407
408 /**
409 * @return Returns the frame.
410 */
411 public JFrame getFrame() {
412 return frame;
413 }
414
415 /**
416 * This method is only valid after the PageRenderers have been generated
417 *
418 * @return Returns the pageRenderers.
419 */
420 public List getPageRenderers() {
421 return pageRenderers;
422 }
423}
Note: See TracBrowser for help on using the repository browser.