/*
*------------------------------------------------------------------------------
* Copyright (C) 2006-2015 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.env.ui;
import info.clearthought.layout.TableLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import omero.model.OriginalFile;
import org.openmicroscopy.shoola.util.CommonsLangUtils;
import org.jdesktop.swingx.JXBusyLabel;
import org.openmicroscopy.shoola.env.Environment;
import org.openmicroscopy.shoola.env.LookupNames;
import org.openmicroscopy.shoola.env.config.Registry;
import org.openmicroscopy.shoola.env.data.ProcessException;
import org.openmicroscopy.shoola.env.data.model.ApplicationData;
import org.openmicroscopy.shoola.env.data.model.DownloadActivityParam;
import org.openmicroscopy.shoola.env.data.model.DownloadAndLaunchActivityParam;
import omero.gateway.SecurityContext;
import org.openmicroscopy.shoola.env.event.EventBus;
import org.openmicroscopy.shoola.util.filter.file.CSVFilter;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
import org.openmicroscopy.shoola.util.ui.filechooser.FileChooser;
import omero.gateway.model.FileAnnotationData;
/**
* Top class that each action should extend.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* @since 3.0-Beta4
*/
public abstract class ActivityComponent
extends JPanel
implements ActionListener
{
/** Bound property indicating to remove the entry from the display. */
static final String REMOVE_ACTIVITY_PROPERTY = "removeActivity";
/** Bound property indicating to unregister the activity. */
static final String UNREGISTER_ACTIVITY_PROPERTY = "unregisterActivity";
/** The default dimension of the status. */
private static final Dimension SIZE = new Dimension(22, 22);
/** ID to remove the entry from the display. */
private static final int REMOVE = 0;
/** ID to cancel the activity. */
private static final int CANCEL = 1;
/** ID to display the standard error. */
private static final int EXCEPTION = 2;
/** ID to display all the output. */
private static final int ALL_RESULT = 3;
/** ID to display the error. */
private static final int ERROR = 4;
/** ID to display the info. */
private static final int INFO = 5;
/** The key to look for to display the output message. */
private static final String MESSAGE = "Message";
/** The key to look for to display the error message if any. */
static final String STD_ERR = "stderr";
/** The key to look for to display the output message if any. */
static final String STD_OUT = "stdout";
/** Indicate the status of the activity. */
private JXBusyLabel status;
/** Button to remove the activity from the display. */
private JButton removeButton;
/** Button to cancel the activity. */
private JButton cancelButton;
/** The label hosting the icon. */
protected JLabel iconLabel;
/** The component displaying the status. */
private JComponent statusPane;
/** The index of the {@link #cancelButton} or {@link #removeButton}. */
private int buttonIndex;
/** The tool bar displaying controls. *. */
private JToolBar toolBar;
/** Button to shows the exception. */
private JButton exceptionButton;
/** Menu displaying the option to view the standard error. */
private ActivityResultPopupMenu errorMenu;
/** Menu displaying the option to view the standard output. */
private ActivityResultPopupMenu infoMenu;
/** The exception thrown while running the script. */
private Throwable exception;
/** The label displaying the type of activity. */
protected JLabel type;
/** The label displaying message if any. */
protected JLabel messageLabel;
/** Convenience reference for subclasses. */
protected final Registry registry;
/** Convenience reference for subclasses. */
protected final SecurityContext ctx;
/** Convenience reference for subclasses. */
protected final UserNotifier viewer;
/** The result of the activity. */
protected Object result;
/** Loader associated to the activity. */
protected UserNotifierLoader loader;
/** The object hosting the error.*/
protected Object errorObject;
/** The object hosting the info.*/
protected Object infoObject;
/** The component displaying the results.*/
private JComponent resultPane;
/** Button to show the general result. */
protected List<ActivityResultRow> resultButtons;
private PropertyChangeListener listener;
/** The index where the output goes.*/
private String paneIndex;
/**
* Opens the passed object. Downloads it first.
*
* @param object The object to open.
* @param parameters Either Analysis parameters or Application data.
* @param source The source triggering the operation.
*/
private void open(Object object, Object parameters, JComponent source)
{
if (!(object instanceof FileAnnotationData ||
object instanceof OriginalFile)) return;
Environment env = (Environment) registry.lookup(LookupNames.ENV);
int index = -1;
long id = -1;
String name = "";
OriginalFile of = null;
if (object instanceof FileAnnotationData) {
FileAnnotationData data = (FileAnnotationData) object;
if (data.isLoaded()) {
of = (OriginalFile) data.getContent();
name = data.getFileName();
} else {
id = data.getId();
index = DownloadActivityParam.FILE_ANNOTATION;
name = "Annotation_"+id;
}
} else {
of = (OriginalFile) object;
id = of.getId().getValue();
if (!of.isLoaded()) {
index = DownloadActivityParam.ORIGINAL_FILE;
name = "File_"+id;
} else {
if (of.getName() != null)
name = of.getName().getValue();
else name = "File_"+id;
}
}
String path = env.getOmeroFilesHome();
File f;
if (index != -1) {
path += File.separator+name;
f = new File(path);
//Delete the file if it already exists
if (f.exists()) {
f.delete();
f = new File(path);
}
f.deleteOnExit();
} else {
String v = path + File.separator+name;
File ff = new File(v);
if (ff.exists())
ff.delete();
f = new File(path);
}
DownloadAndLaunchActivityParam activity;
if (index != -1)
activity = new DownloadAndLaunchActivityParam(id, index, f, null);
else
activity = new DownloadAndLaunchActivityParam(of, f, null);
if (parameters instanceof ApplicationData) {
activity.setApplicationData((ApplicationData) parameters);
}
activity.setSource(source);
viewer.notifyActivity(ctx, activity);
}
/**
* Initializes the components.
*
* @param text The type of activity.
* @param icon The icon to display when done.
*/
private void initComponents(String text, Icon icon)
{
exceptionButton = createButton("Failure", EXCEPTION, this);
exceptionButton.setVisible(false);
removeButton = createButton("Remove", REMOVE, this);
cancelButton = createButton("Cancel", CANCEL, this);
//if (index == ADVANCED)
resultButtons = new ArrayList<ActivityResultRow>();
status = new JXBusyLabel(SIZE);
type = UIUtilities.setTextFont(text);
iconLabel = new JLabel();
messageLabel = UIUtilities.setTextFont("",
iconLabel.getFont().getStyle(), 10);
iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
if (icon != null) iconLabel.setIcon(icon);
statusPane = status;
resultPane = new JPanel();
listener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
//do something
}
};
}
/** Builds and lays out the UI. */
private void buildGUI()
{
JPanel barPane = new JPanel();
barPane.setOpaque(false);
barPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
double[][] size = {{TableLayout.FILL},
{TableLayout.PREFERRED, TableLayout.PREFERRED}};
barPane.setLayout(new TableLayout(size));
barPane.add(type, "0, 0, LEFT, CENTER");
barPane.add(messageLabel, "0, 1, CENTER, CENTER");
//icon, message, content, toolbar
double[][] tl = {{TableLayout.PREFERRED, TableLayout.FILL,
TableLayout.PREFERRED, TableLayout.PREFERRED},
{TableLayout.PREFERRED}};
setLayout(new TableLayout(tl));
add(statusPane, "0, 0");
JPanel p = UIUtilities.buildComponentPanel(barPane);
p.setOpaque(false);
p.setBackground(barPane.getBackground());
add(p, "1, 0");
paneIndex = "2, 0";
add(resultPane, paneIndex);
add(createToolBar(), "3, 0");
}
/**
* Returns the tool bar.
*
* @return See above.
*/
private JComponent createToolBar()
{
toolBar = new JToolBar();
toolBar.setOpaque(false);
toolBar.setFloatable(false);
toolBar.setBorder(null);
buttonIndex = 0;
toolBar.add(exceptionButton);
toolBar.add(Box.createHorizontalStrut(5));
buttonIndex = 2;
toolBar.add(cancelButton);
JLabel l = new JLabel();
Font f = l.getFont();
l.setForeground(UIUtilities.LIGHT_GREY.darker());
l.setFont(f.deriveFont(f.getStyle(), f.getSize()-2));
String s = UIUtilities.formatDefaultDate(null);
String[] values = s.split(" ");
if (values.length > 1) {
String v = values[1];
if (values.length > 2) v +=" "+values[2];
l.setText(v);
toolBar.add(Box.createHorizontalStrut(5));
toolBar.add(l);
toolBar.add(Box.createHorizontalStrut(5));
}
return toolBar;
}
/** Resets the controls. */
private void reset()
{
toolBar.remove(buttonIndex);
toolBar.add(removeButton, buttonIndex);
removeButton.setEnabled(true);
exceptionButton.setVisible(false);
status.setBusy(false);
status.setVisible(false);
statusPane = iconLabel;
remove(statusPane);
add(statusPane, "0, 0, CENTER, CENTER");
repaint();
}
/**
* Converts the passed mapped.
*
* @param m The map to handle.
* @return See above.
*/
private Map<String, Object> convertResult(Map<String, Object> m)
{
Map<String, Object> objects = new HashMap<String, Object>();
if (m == null) return objects;
messageLabel.setText("");
Object v = m.get(MESSAGE);
if (v != null) {
if (v instanceof String)
messageLabel.setText((String) v);
}
m.remove(MESSAGE);
if (m.containsKey(STD_ERR)) {
errorObject = m.get(STD_ERR);
m.remove(STD_ERR);
}
if (m.containsKey(STD_OUT)) {
infoObject = m.get(STD_OUT);
m.remove(STD_OUT);
}
return m;
}
/** Shows the exception. */
private void showException()
{
if (exception == null) return;
viewer.notifyError(type.getText(), messageLabel.getText(), exception);
}
/**
* Returns the identifier of the plugin to run.
*
* @return See above.
*/
private int runAsPlugin()
{
Environment env = (Environment) registry.lookup(LookupNames.ENV);
if (env == null) return -1;
return env.runAsPlugin();
}
/**
* Creates a new instance.
*
* @param viewer The viewer this data loader is for.
* Mustn't be <code>null</code>.
* @param registry Convenience reference for subclasses.
* @param ctx The security context.
*/
ActivityComponent(UserNotifier viewer, Registry registry,
SecurityContext ctx)
{
if (viewer == null) throw new NullPointerException("No viewer.");
if (registry == null) throw new NullPointerException("No registry.");
this.viewer = viewer;
this.registry = registry;
this.ctx = ctx;
}
/**
* Initializes the components.
*
* @param text The text of the activity.
* @param icon The icon to display then done.
*/
void initialize(String text, Icon icon)
{
initComponents(text, icon);
buildGUI();
}
/**
* Creates a button.
*
* @param text The text of the button.
* @param actionID The action command id.
* @param l The action listener.
* @return See above.
*/
JButton createButton(String text, int actionID, ActionListener l)
{
JButton b = UIUtilities.createHyperLinkButton(text);
b.setActionCommand(""+actionID);
b.addActionListener(l);
return b;
}
/**
* Returns the name to give to the file.
*
* @param files Collection of files in the currently selected directory.
* @param fileName The name of the original file.
* @param original The name of the file.
* @param dirPath Path to the directory.
* @param index The index of the file.
* @param extension The extension to check or <code>null</code>.
* @return See above.
*/
String getFileName(File[] files, String fileName, String original,
String dirPath, int index, String extension)
{
String path = dirPath+original;
boolean exist = false;
if (files != null) {
for (int i = 0; i < files.length; i++) {
if ((files[i].getAbsolutePath()).equals(path)) {
exist = true;
break;
}
}
}
if (!exist) return original;
if (CommonsLangUtils.isEmpty(fileName)) return original;
if (CommonsLangUtils.isNotEmpty(extension)) {
int n = fileName.lastIndexOf(extension);
String v = fileName.substring(0, n)+"_("+index+")"+extension;
index++;
return getFileName(files, fileName, v, dirPath, index, extension);
} else {
int lastDot = fileName.lastIndexOf(".");
if (lastDot != -1) {
extension = fileName.substring(lastDot, fileName.length());
String v = fileName.substring(0, lastDot)+"_("+index+")"+
extension;
index++;
return getFileName(files, fileName, v, dirPath, index, null);
}
}
return original;
}
/** Invokes when the activity has been cancelled. */
public void onActivityCancelled()
{
reset();
firePropertyChange(UNREGISTER_ACTIVITY_PROPERTY, null, this);
notifyActivityCancelled();
EventBus bus = registry.getEventBus();
bus.post(new ActivityProcessEvent(this, false));
}
/** Invokes when the call-back has been set. */
public void onCallBackSet()
{
cancelButton.setEnabled(true);
}
/** Invokes when the activity starts. */
public void startActivity()
{
status.setBusy(true);
}
/**
* Returns <code>true</code> if the result can be displayed,
* <code>false</code> otherwise.
*
* @param object The object to handle.
* @return See above.
*/
boolean canPlotResult(Object object)
{
if (object instanceof FileAnnotationData) {
FileAnnotationData fa = (FileAnnotationData) object;
if (fa.isLoaded()) {
return fa.getFileName().endsWith("."+CSVFilter.CSV);
}
}
return false;
}
/**
* Downloads the passed object is supported.
*
* @param text The text used if the object is not loaded.
* @param object The object to handle.
* @param folder Indicates where to download the file or <code>null</code>.
* @param deleteWhenFinished If set file is deleted after download finished
*/
void download(String text, Object object, File folder, final boolean deleteWhenFinished)
{
if (!(object instanceof FileAnnotationData ||
object instanceof OriginalFile)) return;
int index = -1;
if (text == null) text = "";
String name = "";
String description = "";
long dataID = -1;
OriginalFile of = null;
FileAnnotationData fa = null;
if (object instanceof FileAnnotationData) {
fa = (FileAnnotationData) object;
if (fa.isLoaded()) {
name = fa.getFileName();
description = fa.getDescription();
of = (OriginalFile) fa.getContent();
} else {
of = null;
dataID = fa.getId();
index = DownloadActivityParam.FILE_ANNOTATION;
if (text.length() == 0) text = "Annotation";
name = text+"_"+dataID;
}
} else {
of = (OriginalFile) object;
if (!of.isLoaded()) {
dataID = of.getId().getValue();
index = DownloadActivityParam.ORIGINAL_FILE;
if (text.length() == 0) text = "File";
name = text+"_"+dataID;
of = null;
}
}
final OriginalFile original = of;
final int type = index;
final String desc = description;
final long id = dataID;
if (folder != null) {
if (original == null && type == -1) return;
DownloadActivityParam activity;
IconManager icons = IconManager.getInstance(registry);
if (original != null) {
activity = new DownloadActivityParam(original,
folder, icons.getIcon(IconManager.DOWNLOAD_22));
} else {
activity = new DownloadActivityParam(id, type,
folder, icons.getIcon(IconManager.DOWNLOAD_22));
}
activity.setLegend(desc);
activity.setUIRegister(true);
if (fa != null && deleteWhenFinished)
activity.setToDelete(fa);
activity.setOverwrite(true);
viewer.notifyActivity(ctx, activity);
return;
}
JFrame f = registry.getTaskBar().getFrame();
FileChooser chooser = new FileChooser(f, FileChooser.SAVE,
"Download", "Select where to download the file.", null,
true, true);
IconManager icons = IconManager.getInstance(registry);
chooser.setTitleIcon(icons.getIcon(IconManager.DOWNLOAD_48));
chooser.setSelectedFileFull(name);
chooser.setApproveButtonText("Download");
final FileAnnotationData anno = fa;
chooser.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if (FileChooser.APPROVE_SELECTION_PROPERTY.equals(name)) {
File[] files = (File[]) evt.getNewValue();
File folder = files[0];
if (original == null && type == -1) return;
IconManager icons = IconManager.getInstance(registry);
DownloadActivityParam activity;
if (original != null) {
activity = new DownloadActivityParam(original,
folder, icons.getIcon(IconManager.DOWNLOAD_22));
} else {
activity = new DownloadActivityParam(id, type,
folder, icons.getIcon(IconManager.DOWNLOAD_22));
}
activity.setLegend(desc);
if (anno != null && deleteWhenFinished)
activity.setToDelete(anno);
viewer.notifyActivity(ctx, activity);
}
}
});
chooser.centerDialog();
}
/**
* Downloads the passed object is supported.
*
* @param text The text used if the object is not loaded.
* @param object The object to handle.
*/
void download(String text, Object object)
{
download(text, object, null, false);
}
/**
* Views the passed object if supported.
*
* @param object The object to view.
* @param source The UI component invoking the method.
*/
void view(Object object, JComponent source)
{
if (object instanceof FileAnnotationData ||
object instanceof OriginalFile) {
open(object, null, source);
} else if (object instanceof File) {
viewer.openApplication(null, ((File) object).getAbsolutePath());
if (source != null) source.setEnabled(true);
} else {
EventBus bus = registry.getEventBus();
//Check if running as plug-in
ViewObjectEvent evt = new ViewObjectEvent(ctx, object, source);
evt.setPlugin(runAsPlugin());
bus.post(evt);
}
}
/**
* Browses the node.
*
* @param object The object to view.
* @param source The UI component invoking the method.
*/
void browse(Object object, JComponent source)
{
EventBus bus = registry.getEventBus();
ViewObjectEvent evt = new ViewObjectEvent(ctx, object, source);
evt.setBrowseObject(true);
bus.post(evt);
}
/**
* Returns <code>true</code> if information returned by script,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean hasInfo() { return infoObject != null; }
/**
* Returns <code>true</code> if information returned by script,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean hasError() { return errorObject != null; }
/**
* Returns <code>true</code> if the activity is still on-going,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean isOngoingActivity() { return status.isBusy(); }
/**
* Notifies that it was not possible to complete the activity.
*
* @param text The text to set.
* @param message The reason of the error.
* @param ex The exception to handle.
*/
public void notifyError(String text, String message, Throwable ex)
{
reset();
int status = -1;
if (ex != null) {
Throwable cause = ex.getCause();
if (cause instanceof ProcessException) {
status = ((ProcessException) cause).getStatus();
if (status == ProcessException.NO_PROCESSOR)
messageLabel.setText("No processor available. " +
"Please try later.");
}
}
if (text != null) {
type.setText(text);
if (message != null)
type.setToolTipText(message);
}
//if (message != null) messageLabel.setText(message);
exception = ex;
if (exception != null && status != ProcessException.NO_PROCESSOR) {
exceptionButton.setVisible(true);
exceptionButton.setToolTipText(
UIUtilities.formatExceptionForToolTip(ex));
}
firePropertyChange(UNREGISTER_ACTIVITY_PROPERTY, null, this);
notifyActivityError();
EventBus bus = registry.getEventBus();
bus.post(new ActivityProcessEvent(this, true));
}
/**
* Shows the menu corresponding to the passed index.
*
* @param src The source of the click
* @param index The index indicating which menu to show.
* @param x The x-coordinate of the mouse clicked.
* @param y The y-coordinate of the mouse clicked.
*/
private void showMenu(JComponent src, int index, int x, int y)
{
switch (index) {
case ERROR:
if (errorMenu == null)
errorMenu = new ActivityResultPopupMenu(errorObject, this);
errorMenu.show(src, x, y);
break;
case INFO:
if (infoMenu == null)
infoMenu = new ActivityResultPopupMenu(infoObject, this);
infoMenu.show(src, x, y);
}
}
/**
* Invokes when the activity end.
*
* @param result The result of the activity.
*/
public void endActivity(Object result)
{
this.result = result;
boolean busy = status.isBusy();
reset();
if (result instanceof Map) {
Map<String, Object> m = convertResult((Map<String, Object>) result);
int size = m.size();
this.result = m;
remove(resultPane);
Color c = getBackground();
if (size == 0) {
JToolBar row = new JToolBar();
row.setOpaque(false);
row.setFloatable(false);
row.setBorder(null);
row.setBackground(c);
JButton button;
if (errorObject != null) {
button = createButton(ActivityResultRow.ERROR_TEXT,
ERROR, this);
button.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
showMenu((JComponent) e.getSource(), ERROR,
e.getX(), e.getY());
}
});
row.add(button);
}
if (infoObject != null) {
button = createButton(ActivityResultRow.INFO_TEXT,
INFO, this);
button.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
showMenu((JComponent) e.getSource(), INFO,
e.getX(), e.getY());
}
});
row.add(button);
}
add(row, paneIndex);
} else {
Entry<String, Object> entry;
Iterator<Entry<String, Object>> i = m.entrySet().iterator();
ActivityResultRow row = null;
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.setBackground(c);
int index = 0;
int max = 2;
JButton moreButton = null;
while (i.hasNext()) {
entry = (Entry<String, Object>) i.next();
this.result = entry.getValue();
row = new ActivityResultRow((String) entry.getKey(),
entry.getValue(), this);
row.setBackground(c);
row.addPropertyChangeListener(listener);
resultButtons.add(row);
if (index < max)
content.add(row);
else {
if (moreButton == null) {
moreButton = createButton(""+(m.size()-max)+" more",
ALL_RESULT, this);
content.add(moreButton);
}
}
index++;
}
if (m.size() == 1) add(row, paneIndex);
else add(content, paneIndex);
resultPane = content;
}
repaint();
}
firePropertyChange(UNREGISTER_ACTIVITY_PROPERTY, null, this);
notifyActivityEnd();
//Post an event to
//if (busy) {
EventBus bus = registry.getEventBus();
bus.post(new ActivityProcessEvent(this, busy));
//}
}
/**
* Returns the type of activity.
*
* @return See above.
*/
public JComponent getActivityType()
{
return new JLabel(type.getText());
}
/** Subclasses should override the method. */
protected abstract void notifyActivityCancelled();
/** Subclasses should override the method. */
protected abstract void notifyActivityEnd();
/** Subclasses should override the method. */
protected abstract void notifyActivityError();
/** Creates a loader. */
protected abstract UserNotifierLoader createLoader();
/**
* Removes the activity from the display
* @see ActionListener#actionPerformed(ActionEvent)
*/
public void actionPerformed(ActionEvent e)
{
int index = Integer.parseInt(e.getActionCommand());
switch (index) {
case REMOVE:
firePropertyChange(REMOVE_ACTIVITY_PROPERTY, null, this);
break;
case CANCEL:
onActivityCancelled();
if (cancelButton != null) cancelButton.setEnabled(false);
if (loader != null) loader.cancel();
break;
case EXCEPTION:
showException();
break;
case ALL_RESULT:
Iterator<ActivityResultRow> i = resultButtons.iterator();
JPanel content = new JPanel();
content.setBackground(getBackground());
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
while (i.hasNext()) {
content.add(i.next());
}
remove(resultPane);
add(content, paneIndex);
resultPane = content;
validate();
repaint();
break;
}
}
/**
* Overridden to make sure that all the components have the correct
* background.
* @see JPanel#setBackground(Color)
*/
public void setBackground(Color color)
{
super.setBackground(color);
if (resultPane != null) resultPane.setBackground(color);
if (removeButton != null) removeButton.setBackground(color);
if (cancelButton != null) cancelButton.setBackground(color);
if (exceptionButton != null) exceptionButton.setBackground(color);
}
}