All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.guise.framework.component.ImageActionControl Maven / Gradle / Ivy

There is a newer version: 0.5.3
Show newest version
/*
 * Copyright © 2005-2008 GlobalMentor, Inc. 
 *
 * 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 io.guise.framework.component;

import static java.util.Objects.*;

import com.globalmentor.beans.*;
import com.globalmentor.java.Objects;

import io.guise.framework.event.*;
import io.guise.framework.model.*;
import io.guise.framework.prototype.ActionPrototype;

/**
 * An image component that is also an action control.
 * @author Garret Wilson
 */
public class ImageActionControl extends AbstractImageComponent implements ActionControl {

	/** The action model used by this component. */
	private final ActionModel actionModel;

	/** @return The action model used by this component. */
	protected ActionModel getActionModel() {
		return actionModel;
	}

	/** The enableable object decorated by this component. */
	private final Enableable enableable;

	/** @return The enableable object decorated by this component. */
	protected Enableable getEnableable() {
		return enableable;
	}

	/** Whether the component is in a rollover state. */
	private boolean rollover = false;

	@Override
	public boolean isRollover() {
		return rollover;
	}

	@Override
	public void setRollover(final boolean newRollover) {
		if(rollover != newRollover) { //if the value is really changing
			final boolean oldRollover = rollover; //get the current value
			rollover = newRollover; //update the value
			firePropertyChange(ROLLOVER_PROPERTY, Boolean.valueOf(oldRollover), Boolean.valueOf(newRollover));
		}
	}

	/** The status of the current user input, or null if there is no status to report. */
	private Status status = null;

	@Override
	public Status getStatus() {
		return status;
	}

	/**
	 * Sets the status of the current user input. This is a bound property.
	 * @param newStatus The new status of the current user input, or null if there is no status to report.
	 * @see #STATUS_PROPERTY
	 */
	protected void setStatus(final Status newStatus) {
		if(status != newStatus) { //if the value is really changing
			final Status oldStatus = status; //get the current value
			status = newStatus; //update the value
			firePropertyChange(STATUS_PROPERTY, oldStatus, newStatus);
		}
	}

	/**
	 * Rechecks user input status of this component, and updates the status.
	 * @see #setStatus(Control.Status)
	 */
	protected void updateStatus() {
		setStatus(determineStatus()); //update the status after rechecking it
	}

	/**
	 * Checks the user input status of the control. If the component has a notification of {@link Notification.Severity#WARN}, the status is determined to be
	 * {@link Status#WARNING}. If the component has a notification of {@link Notification.Severity#ERROR}, the status is determined to be {@link Status#ERROR}.
	 * Otherwise, this version returns null. If the control is disabled null is returned.
	 * @return The current user input status of the control.
	 */
	protected Status determineStatus() {
		if(isEnabled()) { //if the control is enabled
			final Notification notification = getNotification(); //get the current notification
			if(notification != null) { //if there is a notification
				switch(notification.getSeverity()) { //see how severe the notification is
					case WARN:
						return Status.WARNING;
					case ERROR:
						return Status.ERROR;
				}
			}
		}
		return null; //default to no status to report
	}

	/**
	 * {@inheritDoc}
	 * 

* This version also updates the status. *

* @see #updateStatus() */ @Override protected void updateValid() { super.updateValid(); //update validity normally updateStatus(); //update user input status } @Override public void setNotification(final Notification newNotification) { final Notification oldNotification = getNotification(); //get the old notification super.setNotification(newNotification); //update the old notification normally if(!Objects.equals(oldNotification, newNotification)) { //if the notification changed updateStatus(); //update the status } } /** * {@inheritDoc} *

* This version clears any notification. *

* @see #setNotification(Notification) */ @Override public void reset() { setNotification(null); //clear any notification } /** Default constructor. */ public ImageActionControl() { this(new DefaultInfoModel(), new DefaultImageModel(), new DefaultActionModel(), new DefaultEnableable()); //construct the class with default models } /** * Image model constructor. * @param imageModel The component image model. */ public ImageActionControl(final ImageModel imageModel) { this(new DefaultInfoModel(), imageModel, new DefaultActionModel(), new DefaultEnableable()); //construct the class with an image model and other default models } /** * Info model, image model, action model, and enableable object constructor. * @param infoModel The component info model. * @param imageModel The component image model. * @param actionModel The component action model. * @param enableable The enableable object in which to store enabled status. * @throws NullPointerException if the given info model, image model, action model, and/or enableable object is null. */ public ImageActionControl(final InfoModel infoModel, final ImageModel imageModel, final ActionModel actionModel, final Enableable enableable) { super(infoModel, imageModel); //construct the parent class this.actionModel = requireNonNull(actionModel, "Action model cannot be null."); //save the action model if(actionModel != infoModel && actionModel != imageModel) { //if the action model isn't the same as another model (we don't want to repeat property change events twice) TODO eventually just listen to specific events for each object this.actionModel.addActionListener(new ActionListener() { //create an action repeater to forward events to this component's listeners @Override public void actionPerformed(final ActionEvent actionEvent) { //if the action is performed final ActionEvent repeatActionEvent = new ActionEvent(ImageActionControl.this, actionEvent); //copy the action event with this class as its source fireActionPerformed(repeatActionEvent); //fire the repeated action } }); } this.enableable = requireNonNull(enableable, "Enableable object cannot be null."); //save the enableable object if(enableable != infoModel) { //if the enableable and the info model are two different objects (we don't want to repeat property change events twice) TODO eventually just listen to specific events for each object this.enableable.addPropertyChangeListener(getRepeatPropertyChangeListener()); //listen and repeat all property changes of the enableable object } addPropertyChangeListener(ENABLED_PROPERTY, new AbstractGenericPropertyChangeListener() { //listen for the "enabled" property changing @Override public void propertyChange(GenericPropertyChangeEvent genericPropertyChangeEvent) { //if the "enabled" property changes setNotification(null); //clear any notification updateValid(); //update the valid status, which depends on the enabled status } }); } /** * Prototype constructor. * @param actionPrototype The prototype on which this component should be based. * @throws NullPointerException if the given prototype is null. */ public ImageActionControl(final ActionPrototype actionPrototype) { this(actionPrototype, new DefaultImageModel(), actionPrototype, actionPrototype); //use the action prototype as every needed model except the image model TODO see if we need a separate image action prototype } @Override public void addActionListener(final ActionListener actionListener) { getEventListenerManager().add(ActionListener.class, actionListener); //add the listener } @Override public void removeActionListener(final ActionListener actionListener) { getEventListenerManager().remove(ActionListener.class, actionListener); //remove the listener } @Override public Iterable getActionListeners() { return getEventListenerManager().getListeners(ActionListener.class); } @Override public void performAction() { getActionModel().performAction(); //delegate to the installed action model, which will fire an event which we will catch and queue for refiring } @Override public void performAction(final int force, final int option) { getActionModel().performAction(force, option); //delegate to the installed action model, which will fire an event which we will catch and refire } /** * Fires an action event to all registered action listeners. This method delegates to {@link #fireActionPerformed(ActionEvent)}. * @param force The zero-based force, such as 0 for no force or 1 for an action initiated by from a mouse single click. * @param option The zero-based option, such as 0 for an event initiated by a mouse left button click or 1 for an event initiaged by a mouse right button * click. * @see ActionListener * @see ActionEvent */ protected void fireActionPerformed(final int force, final int option) { if(getEventListenerManager().hasListeners(ActionListener.class)) { //if there are action listeners registered fireActionPerformed(new ActionEvent(this, force, option)); //create and fire a new action event } } /** * Fires a given action event to all registered action listeners. * @param actionEvent The action event to fire. */ protected void fireActionPerformed(final ActionEvent actionEvent) { for(final ActionListener actionListener : getEventListenerManager().getListeners(ActionListener.class)) { //for each action listener actionListener.actionPerformed(actionEvent); //dispatch the action to the listener } } //Enableable delegations @Override public boolean isEnabled() { return enableable.isEnabled(); } @Override public void setEnabled(final boolean newEnabled) { enableable.setEnabled(newEnabled); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy