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

Last change on this file since 15210 was 15210, checked in by oranfry, 16 years ago

Lots of changes to the installer. Now only look in LanguagePack resource bundle for strings.

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