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

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

fixes to the last change and made the selectinput render more nicely

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