/* * @(#)DefaultActivityModel.java * * Copyright (c) 2011 The authors and contributors of JHotDraw. * * You may not use, copy or modify this file, except in compliance with the * license agreement you entered into with the copyright holders. For details * see accompanying license terms. */ package org.jhotdraw.gui; import javax.annotation.Nullable; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Formatter; import java.util.Locale; import javax.swing.DefaultBoundedRangeModel; import org.jhotdraw.beans.WeakPropertyChangeListener; /** * Default implementation of {@link ActivityModel}. * * @author Werner Randelshofer * @version $Id$ */ public class DefaultActivityModel extends DefaultBoundedRangeModel implements ActivityModel { private static final long serialVersionUID = 1L; private boolean canceled, closed, cancelable = true; private Runnable doCancel; private final String title; private String note; private boolean isIndeterminate; private String warning; private String error; private Formatter formatter; private final Object owner; protected PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); /** Creates a new DefaultActivityModel. */ public DefaultActivityModel(Object owner, String title, String note, boolean isIndeterminate) { this(owner, title, note, 0, 100, isIndeterminate); } /** Creates a new DefaultActivityModel. */ public DefaultActivityModel(Object owner, String title, @Nullable String note, int min, int max) { this(owner, title, note, min, max, false); } /** Creates a new DefaultActivityModel. */ public DefaultActivityModel(Object owner, String title, @Nullable String note, int min, final int max, final boolean isIndeterminate) { super(min, 0, min, max); this.owner = owner; this.title = title; this.note = note; this.isIndeterminate = isIndeterminate; ActivityManager.getInstance().add(this); } /** Creates a new indeterminate DefaultActivityModel. */ public DefaultActivityModel(Object owner, String title) { this(owner, title, null, 0, 100, true); } /** * Set cancelable to false if the operation can not be canceled. */ @Override public void setCancelable(boolean newValue) { boolean oldValue=cancelable; cancelable = newValue; firePropertyChange(CANCELABLE_PROPERTY, oldValue,newValue ); } /** * The specified Runnable is executed when the user presses * the cancel button. */ @Override public void setDoCancel(Runnable doCancel) { this.doCancel = doCancel; } /** * Indicate that the operation is closed. */ @Override public void close() { if (!closed) { closed = true; firePropertyChange(CLOSED_PROPERTY, false,true); ActivityManager.getInstance().remove(this); } } /** * Closes the progress view. */ /** * Returns true if the user has hit the Cancel button in the progress dialog. */ @Override public boolean isCanceled() { return canceled; } /** * Returns true if the operation is completed. */ @Override public boolean isClosed() { return closed; } /** * Cancels the operation. * This method must be invoked from the user event dispatch thread. */ @Override public void cancel() { if (cancelable && !canceled) { canceled = true; firePropertyChange(CANCELED_PROPERTY, false,true); if (doCancel!=null) doCancel.run(); } } /** * Specifies the additional note that is displayed along with the * progress message. Used, for example, to show which file the * is currently being copied during a multiple-file copy. * * @param newValue a String specifying the note to display * @see #getNote */ @Override public void setNote(String newValue) { String oldValue=note; this.note = newValue; firePropertyChange(NOTE_PROPERTY, oldValue, newValue); } /** * Specifies the additional note that is displayed along with the * progress message. * * @return a String specifying the note to display * @see #setNote */ @Override public String getNote() { return note; } @Override public void setWarning(String newValue) { String oldValue=warning; this.warning = newValue; firePropertyChange(WARNING_PROPERTY, oldValue, newValue); } @Override public String getWarning() { return warning; } @Override public void setError(String newValue) { String oldValue=error; this.error = newValue; firePropertyChange(ERROR_PROPERTY, oldValue, newValue); } @Override public String getError() { return error; } @Override public void setIndeterminate(boolean newValue) { boolean oldValue=isIndeterminate; isIndeterminate = newValue; firePropertyChange(INDETERMINATE_PROPERTY, oldValue, newValue); } @Override public boolean isIndeterminate() { return isIndeterminate; } @Override public void printf(String format, Object... args) { if ((formatter == null)// || (formatter.locale() != Locale.getDefault())) { formatter = new Formatter(); } formatter.format(Locale.getDefault(), format, args); StringBuilder buf = (StringBuilder) formatter.out(); setNote(buf.toString()); } @Override public Object getOwner() { return owner; } @Override public String getTitle() { return title; } /** Adds a {@code PropertyChangeListener} which can optionally be wrapped * into a {@code WeakPropertyChangeListener}. * @param listener */ @Override public void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } /** Adds a {@code PropertyChangeListener} which can optionally be wrapped * into a {@code WeakPropertyChangeListener}. * @param listener */ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(propertyName, listener); } /** Removes a {@code PropertyChangeListener}. If the listener was added * wrapped into a {@code WeakPropertyChangeListener}, the * {@code WeakPropertyChangeListener} is removed. * * @param listener */ @Override public void removePropertyChangeListener(PropertyChangeListener listener) { // Removes a property change listener from our list. // We need a somewhat complex procedure here in case a listener // has been registered using addPropertyChangeListener(new WeakPropertyChangeListener(listener)); for (PropertyChangeListener l : propertySupport.getPropertyChangeListeners()) { if (l == listener) { propertySupport.removePropertyChangeListener(l); break; } if (l instanceof WeakPropertyChangeListener) { WeakPropertyChangeListener wl = (WeakPropertyChangeListener) l; PropertyChangeListener target = wl.getTarget(); if (target == listener) { propertySupport.removePropertyChangeListener(l); break; } } } } protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } protected void firePropertyChange(String propertyName, int oldValue, int newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } protected void firePropertyChange(String propertyName, @Nullable Object oldValue, @Nullable Object newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } @Override public boolean isCancelable() { return cancelable; } }