/*
* Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org
* Use is subject to license terms. See license.txt.
*/
package org.beanfabrics.swing;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import javax.swing.JProgressBar;
import org.beanfabrics.IModelProvider;
import org.beanfabrics.Link;
import org.beanfabrics.ModelProvider;
import org.beanfabrics.ModelSubscriber;
import org.beanfabrics.Path;
import org.beanfabrics.View;
import org.beanfabrics.event.WeakPropertyChangeListener;
import org.beanfabrics.model.AbstractPM;
import org.beanfabrics.model.ConversionException;
import org.beanfabrics.model.IIntegerPM;
/**
* The <code>BnProgressBar</code> is a {@link JProgressBar} that can subscribe to an {@link IIntegerPM}.
*
* @author Frederik Leonhardt
* @author Michael Karneim
* @beaninfo
*/
@SuppressWarnings("serial")
public class BnProgressBar extends JProgressBar implements View<IIntegerPM>, ModelSubscriber {
private final Link link = new Link(this);
private final PropertyChangeListener listener = new MyWeakPropertyChangeListener();
private class MyWeakPropertyChangeListener implements WeakPropertyChangeListener, Serializable {
public void propertyChange(PropertyChangeEvent evt) {
refresh();
}
};
private IIntegerPM pModel;
/**
* Constructs a <code>BnProgressBar</code>.
*/
public BnProgressBar() {
}
/**
* Constructs a <code>BnProgressBar</code> and binds it to the specified model.
*
* @param pModel
* the model
*/
public BnProgressBar(IIntegerPM pModel) {
this();
setPresentationModel(pModel);
}
/**
* Constructs a <code>BnProgressBar</code> and subscribes it for the model at the specified Path provided by the
* given provider.
*
* @param provider
* @param path
*/
public BnProgressBar(ModelProvider provider, Path path) {
this.setModelProvider(provider);
this.setPath(path);
}
/**
* Constructs a <code>BnProgressBar</code> and subscribes it for the model at the root level provided by the given
* provider.
*
* @param provider
*/
public BnProgressBar(ModelProvider provider) {
this.setModelProvider(provider);
this.setPath(new Path());
}
/**
* Returns whether this component is connected to the target {@link AbstractPM} to synchronize with.
*
* @return <code>true</code> when this component is connected, else <code>false</code>
*/
boolean isConnected() {
return this.pModel != null;
}
/**
* Configures this component depending on the target {@link AbstractPM} s attributes.
*/
private void refresh() {
refreshProgressBar();
}
/**
* Configures the progress of this component on the depending on the target {@link IIntegerPM}s attributes.
*/
private void refreshProgressBar() {
if (this.pModel == null) {
this.setValue(0);
this.setToolTipText(null);
this.setEnabled(false);
} else {
try {
Integer value = pModel.getInteger();
if (value != null) {
this.setValue(value);
} else {
this.setValue(0);
}
} catch (ConversionException ex) {
this.setValue(0);
}
this.setToolTipText(pModel.isValid() == false ? pModel.getValidationState().getMessage() : pModel
.getDescription());
this.setEnabled(true);
}
}
@Override
public IIntegerPM getPresentationModel() {
return pModel;
}
@Override
public void setPresentationModel(IIntegerPM newModel) {
IIntegerPM oldModel = this.pModel;
if (this.pModel != null) {
this.pModel.removePropertyChangeListener(listener);
}
this.pModel = newModel;
if (this.pModel != null) {
this.pModel.addPropertyChangeListener(listener);
}
refresh();
this.firePropertyChange("presentationModel", oldModel, newModel);
}
@Override
public IModelProvider getModelProvider() {
return this.link.getModelProvider();
}
@Override
public Path getPath() {
return this.link.getPath();
}
@Override
public void setModelProvider(IModelProvider provider) {
this.link.setModelProvider(provider);
}
@Override
public void setPath(Path path) {
this.link.setPath(path);
}
}