/* * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved. * * http://izpack.org/ * http://izpack.codehaus.org/ * * Copyright 2003 Tino Schwarze * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.izforge.izpack.panels; import com.izforge.izpack.gui.ButtonFactory; import com.izforge.izpack.gui.LabelFactory; import com.izforge.izpack.installer.*; import com.izforge.izpack.adaptator.IXMLElement; import com.izforge.izpack.adaptator.impl.XMLElementImpl; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.Iterator; /** * The compile panel class. * <p/> * This class allows .java files to be compiled after installation. * <p/> * Parts of the code have been taken from InstallPanel.java and modified a lot. * * @author Tino Schwarze * @author Julien Ponge */ public class CompilePanel extends IzPanel implements ActionListener, CompileHandler { /** * */ private static final long serialVersionUID = 3258408430669674552L; /** * The combobox for compiler selection. */ protected JComboBox compilerComboBox; /** * The combobox for compiler argument selection. */ protected JComboBox argumentsComboBox; /** * The start button. */ protected JButton startButton; /** * The browse button. */ protected JButton browseButton; /** * The tip label. */ protected JLabel tipLabel; /** * The operation label . */ protected JLabel opLabel; /** * The pack progress bar. */ protected JProgressBar packProgressBar; /** * The operation label . */ protected JLabel overallLabel; /** * The overall progress bar. */ protected JProgressBar overallProgressBar; /** * True if the compilation has been done. */ private boolean validated = false; /** * The compilation worker. Does all the work. */ private CompileWorker worker; /** * Number of jobs to compile. Used for progress indication. */ private int noOfJobs; /** * The constructor. * * @param parent The parent window. * @param idata The installation data. * @throws IOException */ public CompilePanel(InstallerFrame parent, InstallData idata) throws IOException { super(parent, idata); this.worker = new CompileWorker(idata, this); GridBagConstraints gridBagConstraints; JLabel heading = new JLabel(); // put everything but the heading into it's own panel // (to center it vertically) JPanel subpanel = new JPanel(); JLabel compilerLabel = new JLabel(); compilerComboBox = new JComboBox(); this.browseButton = ButtonFactory.createButton(parent.langpack .getString("CompilePanel.browse"), idata.buttonsHColor); JLabel argumentsLabel = new JLabel(); this.argumentsComboBox = new JComboBox(); this.startButton = ButtonFactory.createButton(parent.langpack .getString("CompilePanel.start"), idata.buttonsHColor); this.tipLabel = LabelFactory.create(parent.langpack.getString("CompilePanel.tip"), parent.icons.getImageIcon("tip"), SwingConstants.TRAILING); this.opLabel = new JLabel(); packProgressBar = new JProgressBar(); this.overallLabel = new JLabel(); this.overallProgressBar = new JProgressBar(); setLayout(new GridBagLayout()); Font font = heading.getFont(); font = font.deriveFont(Font.BOLD, font.getSize() * 2.0f); heading.setFont(font); heading.setHorizontalAlignment(SwingConstants.CENTER); heading.setText(parent.langpack.getString("CompilePanel.heading")); heading.setVerticalAlignment(SwingConstants.TOP); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = 0; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = GridBagConstraints.NORTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 0.1; add(heading, gridBagConstraints); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = GridBagConstraints.CENTER; gridBagConstraints.gridy = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 0.9; add(subpanel, gridBagConstraints); subpanel.setLayout(new GridBagLayout()); int row = 0; compilerLabel.setHorizontalAlignment(SwingConstants.LEFT); compilerLabel.setLabelFor(compilerComboBox); compilerLabel.setText(parent.langpack.getString("CompilePanel.choose_compiler")); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; // gridBagConstraints.weighty = 0.1; subpanel.add(compilerLabel, gridBagConstraints); compilerComboBox.setEditable(true); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; // gridBagConstraints.weighty = 0.1; Iterator<String> it = this.worker.getAvailableCompilers().iterator(); while (it.hasNext()) { compilerComboBox.addItem(it.next()); } subpanel.add(compilerComboBox, gridBagConstraints); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridx = 1; gridBagConstraints.anchor = GridBagConstraints.EAST; browseButton.addActionListener(this); subpanel.add(browseButton, gridBagConstraints); argumentsLabel.setHorizontalAlignment(SwingConstants.LEFT); argumentsLabel.setLabelFor(argumentsComboBox); argumentsLabel.setText(parent.langpack.getString("CompilePanel.additional_arguments")); // argumentsLabel.setToolTipText(""); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 0.5; // gridBagConstraints.weighty = 0.1; subpanel.add(argumentsLabel, gridBagConstraints); argumentsComboBox.setEditable(true); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 0.5; // gridBagConstraints.weighty = 0.1; it = this.worker.getAvailableArguments().iterator(); while (it.hasNext()) { argumentsComboBox.addItem(it.next()); } subpanel.add(argumentsComboBox, gridBagConstraints); // leave some space above the label gridBagConstraints.insets = new Insets(10, 0, 0, 0); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; subpanel.add(tipLabel, gridBagConstraints); opLabel.setText(" "); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; subpanel.add(opLabel, gridBagConstraints); packProgressBar.setValue(0); packProgressBar.setString(parent.langpack.getString("CompilePanel.progress.initial")); packProgressBar.setStringPainted(true); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = GridBagConstraints.SOUTH; subpanel.add(packProgressBar, gridBagConstraints); overallLabel.setText(parent.langpack.getString("CompilePanel.progress.overall")); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; subpanel.add(overallLabel, gridBagConstraints); overallProgressBar.setValue(0); overallProgressBar.setString(""); overallProgressBar.setStringPainted(true); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = row++; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = GridBagConstraints.SOUTH; subpanel.add(overallProgressBar, gridBagConstraints); startButton.setText(parent.langpack.getString("CompilePanel.start")); startButton.addActionListener(this); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridwidth = 2; gridBagConstraints.gridy = row++; gridBagConstraints.fill = GridBagConstraints.NONE; // leave some space above the button gridBagConstraints.insets = new Insets(5, 0, 0, 0); subpanel.add(startButton, gridBagConstraints); } /** * Indicates wether the panel has been validated or not. * * @return The validation state. */ public boolean isValidated() { return validated; } /** * Action function, called when the start button is pressed. */ public void actionPerformed(ActionEvent e) { if (e.getSource() == this.startButton) { this.worker.setCompiler((String) this.compilerComboBox.getSelectedItem()); this.worker.setCompilerArguments((String) this.argumentsComboBox.getSelectedItem()); this.blockGUI(); this.worker.startThread(); } else if (e.getSource() == this.browseButton) { this.parent.blockGUI(); JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File((String) this.compilerComboBox.getSelectedItem()) .getParentFile()); int result = chooser.showDialog(this.parent, this.parent.langpack .getString("CompilePanel.browse.approve")); if (result == JFileChooser.APPROVE_OPTION) { File file_chosen = chooser.getSelectedFile(); if (file_chosen.isFile()) { this.compilerComboBox.setSelectedItem(file_chosen.getAbsolutePath()); } } this.parent.releaseGUI(); } } /** * Block the GUI - disalow input. */ protected void blockGUI() { // disable all controls this.startButton.setEnabled(false); this.browseButton.setEnabled(false); this.compilerComboBox.setEnabled(false); this.argumentsComboBox.setEnabled(false); this.parent.blockGUI(); } /** * Release the GUI - allow input. * * @param allowconfig allow the user to enter new configuration */ protected void releaseGUI(boolean allowconfig) { // disable all controls if (allowconfig) { this.startButton.setEnabled(true); this.browseButton.setEnabled(true); this.compilerComboBox.setEnabled(true); this.argumentsComboBox.setEnabled(true); } this.parent.releaseGUI(); } /** * An error was encountered. * * @param error The error information. * @see com.izforge.izpack.installer.CompileHandler */ public void handleCompileError(CompileResult error) { String message = error.getMessage(); opLabel.setText(message); CompilerErrorDialog dialog = new CompilerErrorDialog(parent, message, idata.buttonsHColor); dialog.show(error); if (dialog.getResult() == CompilerErrorDialog.RESULT_IGNORE) { error.setAction(CompileResult.ACTION_CONTINUE); } else if (dialog.getResult() == CompilerErrorDialog.RESULT_RECONFIGURE) { error.setAction(CompileResult.ACTION_RECONFIGURE); } else // default case: abort { error.setAction(CompileResult.ACTION_ABORT); } } /* (non-Javadoc) * @see com.izforge.izpack.util.AbstractUIProgressHandler#startAction(java.lang.String, int) */ public void startAction(String name, int noOfJobs1) { this.noOfJobs = noOfJobs1; overallProgressBar.setMaximum(noOfJobs1); parent.lockPrevButton(); } /** * The compiler stops. */ public void stopAction() { CompileResult result = this.worker.getResult(); this.releaseGUI(result.isReconfigure()); if (result.isContinue()) { parent.lockPrevButton(); packProgressBar.setString(parent.langpack.getString("CompilePanel.progress.finished")); packProgressBar.setEnabled(false); packProgressBar.setValue(packProgressBar.getMaximum()); overallProgressBar.setValue(this.noOfJobs); String no_of_jobs = Integer.toString(this.noOfJobs); overallProgressBar.setString(no_of_jobs + " / " + no_of_jobs); overallProgressBar.setEnabled(false); opLabel.setText(" "); opLabel.setEnabled(false); validated = true; idata.installSuccess = true; if (idata.panels.indexOf(this) != (idata.panels.size() - 1)) { parent.unlockNextButton(); } } else { idata.installSuccess = false; } } /** * Normal progress indicator. * * @param val The progression value. * @param msg The progression message. */ public void progress(int val, String msg) { // Debug.trace ("progress: " + val + " " + msg); packProgressBar.setValue(val + 1); opLabel.setText(msg); } /** * Job changing. * * @param jobName The job name. * @param max The new maximum progress. * @param jobNo The job number. */ public void nextStep(String jobName, int max, int jobNo) { packProgressBar.setValue(0); packProgressBar.setMaximum(max); packProgressBar.setString(jobName); opLabel.setText(""); overallProgressBar.setValue(jobNo); overallProgressBar.setString(Integer.toString(jobNo) + " / " + Integer.toString(this.noOfJobs)); } /** * {@inheritDoc} */ public void setSubStepNo(int max) { packProgressBar.setMaximum(max); } /** * Called when the panel becomes active. */ public void panelActivate() { // get compilers again (because they might contain variables from former // panels) Iterator<String> it = this.worker.getAvailableCompilers().iterator(); compilerComboBox.removeAllItems(); while (it.hasNext()) { compilerComboBox.addItem(it.next()); } // We clip the panel Dimension dim = parent.getPanelsContainerSize(); dim.width -= (dim.width / 4); dim.height = 150; setMinimumSize(dim); setMaximumSize(dim); setPreferredSize(dim); parent.lockNextButton(); } /** * Create XML data for automated installation. */ public void makeXMLData(IXMLElement panelRoot) { // just save the compiler chosen and the arguments IXMLElement compiler = new XMLElementImpl("compiler",panelRoot); compiler.setContent(this.worker.getCompiler()); panelRoot.addChild(compiler); IXMLElement args = new XMLElementImpl("arguments",panelRoot); args.setContent(this.worker.getCompilerArguments()); panelRoot.addChild(args); } /** * Show a special dialog for compiler errors. * <p/> * This dialog is neccessary because we have lots of information if compilation failed. We'd * also like the user to chose whether to ignore the error or not. */ protected class CompilerErrorDialog extends JDialog implements ActionListener { private static final long serialVersionUID = 3762537797721995317L; /** * user closed the dialog without pressing "Ignore" or "Abort" */ public static final int RESULT_NONE = 0; /** * user pressed "Ignore" button */ public static final int RESULT_IGNORE = 23; /** * user pressed "Abort" button */ public static final int RESULT_ABORT = 42; /** * user pressed "Reconfigure" button */ public static final int RESULT_RECONFIGURE = 47; /** * visual goodie: button hightlight color */ private java.awt.Color buttonHColor = null; /** * Creates new form compilerErrorDialog * * @param parent parent to be used * @param title String to be used as title * @param buttonHColor highlight color to be used */ public CompilerErrorDialog(java.awt.Frame parent, String title, java.awt.Color buttonHColor) { super(parent, title, true); this.buttonHColor = buttonHColor; initComponents(); } /** * This method is called from within the constructor to initialize the form. * <p/> * Generated with help from NetBeans IDE. */ private void initComponents() { JPanel errorMessagePane = new JPanel(); errorMessageText = new JTextArea(); JTextArea seeBelowText = new JTextArea(); JTabbedPane errorDisplayPane = new JTabbedPane(); JScrollPane commandScrollPane = new JScrollPane(); commandText = new JTextArea(); JScrollPane stdOutScrollPane = new JScrollPane(); stdOutText = new JTextArea(); JScrollPane stdErrScrollPane = new JScrollPane(); stdErrText = new JTextArea(); JPanel buttonsPanel = new JPanel(); reconfigButton = ButtonFactory.createButton(parent.langpack .getString("CompilePanel.error.reconfigure"), this.buttonHColor); ignoreButton = ButtonFactory.createButton(parent.langpack .getString("CompilePanel.error.ignore"), this.buttonHColor); abortButton = ButtonFactory.createButton(parent.langpack .getString("CompilePanel.error.abort"), this.buttonHColor); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { closeDialog(); } }); errorMessagePane.setLayout(new BoxLayout(errorMessagePane, BoxLayout.Y_AXIS)); errorMessageText.setBackground(super.getBackground()); errorMessageText.setEditable(false); errorMessageText.setLineWrap(true); // errorMessageText.setText("The compiler does not seem to work. See // below for the command we tried to execute and the results."); // errorMessageText.setToolTipText("null"); errorMessageText.setWrapStyleWord(true); errorMessagePane.add(errorMessageText); seeBelowText.setBackground(super.getBackground()); seeBelowText.setEditable(false); seeBelowText.setLineWrap(true); seeBelowText.setWrapStyleWord(true); seeBelowText.setText(parent.langpack.getString("CompilePanel.error.seebelow")); errorMessagePane.add(seeBelowText); getContentPane().add(errorMessagePane, java.awt.BorderLayout.NORTH); // use 12pt monospace font for compiler output etc. Font output_font = new Font("Monospaced", Font.PLAIN, 12); // errorDisplayPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); // errorDisplayPane.setName("null"); commandText.setFont(output_font); commandText.setEditable(false); commandText.setRows(10); commandText.setColumns(82); commandText.setWrapStyleWord(true); commandText.setLineWrap(true); // commandText.setText("akjfkajfeafjakefjakfkaejfja"); commandScrollPane.setViewportView(commandText); errorDisplayPane.addTab("Command", commandScrollPane); stdOutText.setFont(output_font); stdOutText.setEditable(false); stdOutText.setWrapStyleWord(true); stdOutText.setLineWrap(true); stdOutScrollPane.setViewportView(stdOutText); errorDisplayPane.addTab("Standard Output", null, stdOutScrollPane); stdErrText.setFont(output_font); stdErrText.setEditable(false); stdErrText.setWrapStyleWord(true); stdErrText.setLineWrap(true); stdErrScrollPane.setViewportView(stdErrText); errorDisplayPane.addTab("Standard Error", null, stdErrScrollPane); getContentPane().add(errorDisplayPane, java.awt.BorderLayout.CENTER); buttonsPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); reconfigButton.addActionListener(this); buttonsPanel.add(reconfigButton); ignoreButton.addActionListener(this); buttonsPanel.add(ignoreButton); abortButton.addActionListener(this); buttonsPanel.add(abortButton); getContentPane().add(buttonsPanel, java.awt.BorderLayout.SOUTH); pack(); } /** * Close the panel. */ protected void closeDialog() { setVisible(false); dispose(); } /** * Shows the given errors * * @param error error messages to be shown */ public void show(CompileResult error) { this.errorMessageText.setText(error.getMessage()); this.commandText.setText(error.getCmdline()); this.stdOutText.setText(error.getStdout()); this.stdErrText.setText(error.getStderr()); super.setVisible(true); } /** * Returns the result of this dialog. * * @return the result of this dialog */ public int getResult() { return this.result; } public void actionPerformed(ActionEvent e) { boolean closenow = false; if (e.getSource() == this.ignoreButton) { this.result = RESULT_IGNORE; closenow = true; } else if (e.getSource() == this.abortButton) { this.result = RESULT_ABORT; closenow = true; } else if (e.getSource() == this.reconfigButton) { this.result = RESULT_RECONFIGURE; closenow = true; } if (closenow) { this.setVisible(false); this.dispose(); } } // Variables declaration - do not modify//GEN-BEGIN:variables private JTextArea commandText; // private JScrollPane stdOutScrollPane; private JTextArea stdErrText; // private JPanel buttonsPanel; // private JScrollPane commandScrollPane; private JTextArea errorMessageText; // private JScrollPane stdErrScrollPane; private JButton ignoreButton; private JTextArea stdOutText; private JButton abortButton; private JButton reconfigButton; // private JTabbedPane errorDisplayPane; // End of variables declaration//GEN-END:variables private int result = RESULT_NONE; } }