package de.gaalop.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; import java.util.Observable; import java.util.Observer; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import de.gaalop.CodeGeneratorPlugin; import de.gaalop.CodeParserPlugin; import de.gaalop.CompilerFacade; import de.gaalop.Notifications; import de.gaalop.OptimizationStrategyPlugin; /** * This class models a model-view-control ready version of {@link JProgressBar}. This class can be registered as * observer of a {@link CodeParserPlugin} in order to visualize the compilation process. The * {@link #update(Observable, Object)} method is implemented to call {@link #setMaximum(int)}, so notifications about a * new maximum of steps are recorded accordingly. * * @author Christian Schwinn * */ public class StatusBar extends JPanel implements Observer { private static final long serialVersionUID = -1854594532112610893L; private final String spacer = " "; private final JProgressBar progressBar; private final JLabel statusLabel; private Throwable ex; private List<Notifications.Warning> warnings; public StatusBar() { setLayout(new BorderLayout(10, 0)); progressBar = new JProgressBar(); statusLabel = new JLabel(); statusLabel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (ex != null) { ErrorDialog.show(ex); } if (warnings != null) { displayWarnings(); } } }); setStatus("Ready"); add(statusLabel, BorderLayout.WEST); add(progressBar, BorderLayout.CENTER); add(new JLabel(spacer), BorderLayout.EAST); } private void setStatus(String status) { statusLabel.setText(spacer + status); } @Override public void update(Observable o, Object arg) { // check if observable is a code parser plugin if (o instanceof CodeParserPlugin) { updateFromCodeParser(arg); } // check if observable is an optimization strategy plugin if (o instanceof OptimizationStrategyPlugin) { updateFromOptimizer(arg); } // check if observable is a compiler facade if (o instanceof CompilerFacade) { updateFromCompilerFacade(arg); } // check if observable is a code generator if (o instanceof CodeGeneratorPlugin) { updateFromCodeGenerator(arg); } } private void updateFromCodeParser(Object arg) { // currently no update } private void updateFromOptimizer(Object arg) { if (arg instanceof Notifications.Start) { progressBar.setValue(0); } else if (arg instanceof Notifications.Number) { progressBar.setMaximum(((Notifications.Number) arg).getValue()); } else if (arg instanceof Notifications.Error) { Throwable ex = ((Notifications.Error) arg).getError(); displayError(ex); ErrorDialog.show(ex); } else if (arg instanceof Notifications.Progress) { progressBar.setValue(progressBar.getValue() + 1); } } private void updateFromCompilerFacade(Object arg) { if (arg instanceof Notifications.Info) { setStatus(((Notifications.Info) arg).getMessage()); } else if (arg instanceof Notifications.Finished) { setStatus("Finished"); progressBar.setValue(progressBar.getMaximum()); if (Notifications.hasWarnings()) { warnings = Notifications.getWarnings(); setStatus("Finished (click here to see warnings)"); } } } private void updateFromCodeGenerator(Object arg) { if (arg instanceof Notifications.Error) { Throwable ex = ((Notifications.Error) arg).getError(); displayError(ex); ErrorDialog.show(ex); } } private void displayWarnings() { if (warnings != null && warnings.size() > 0) { int n = warnings.size(); int i = 1; StringBuilder messages = new StringBuilder(); for (Notifications.Warning warning : warnings) { messages.append("Warning " + i++ + " of " + n + ":\n"); messages.append(warning.getMessage()); messages.append('\n'); } JOptionPane.showMessageDialog(null, messages.toString(), "Warnings", JOptionPane.WARNING_MESSAGE); } } public void reset() { ex = null; warnings = null; Notifications.clearWarnings(); statusLabel.setForeground(Color.BLACK); setStatus("Ready"); progressBar.setValue(0); } public void displayError(Throwable ex) { this.ex = ex; statusLabel.setForeground(Color.RED); setStatus("Error (click here to see error dialog)"); } }