/* * @(#)AbstractSelectionAction.java * * Copyright (c) 2010 The authors and contributors of JHotDraw. * * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.app.action.edit; import javax.annotation.Nullable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.AbstractAction; import javax.swing.JComponent; import org.jhotdraw.gui.EditableComponent; import org.jhotdraw.beans.WeakPropertyChangeListener; /** * {@code AbstractSelectionAction} acts on the selection of a target component. * <p> * By default, the action is disabled when the target component is disabled or has * no selection. If the target component is null, updateEnabled does nothing. * You can change this behavior by overriding method {@code updateEnabled()}. * <p> * This action registers a {@link WeakPropertyChangeListener} on the component. * * <hr> * <b>Design Patterns</b> * * <p><em>Framework</em><br> * The interfaces and classes listed below work together: * <br> * Contract: {@link org.jhotdraw.gui.EditableComponent}, {@code JTextComponent}.<br> * Client: {@link org.jhotdraw.app.action.edit.AbstractSelectionAction}, * {@link org.jhotdraw.app.action.edit.DeleteAction}, * {@link org.jhotdraw.app.action.edit.DuplicateAction}, * {@link org.jhotdraw.app.action.edit.SelectAllAction}, * {@link org.jhotdraw.app.action.edit.ClearSelectionAction}. * <hr> * * @author Werner Randelshofer * @version $Id$ */ public abstract class AbstractSelectionAction extends AbstractAction { private static final long serialVersionUID = 1L; /** The target of the action or null if the action acts on the currently * focused component. */ @Nullable protected JComponent target; /** This variable keeps a strong reference on the property change listener. */ private PropertyChangeListener propertyHandler; /** Creates a new instance which acts on the specified component. * * @param target The target of the action. Specify null for the currently * focused component. */ public AbstractSelectionAction(@Nullable JComponent target) { this.target = target; if (target != null) { // Register with a weak reference on the JComponent. propertyHandler = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String n = evt.getPropertyName(); if ("enabled".equals(n)) { updateEnabled(); } else if (n.equals(EditableComponent.SELECTION_EMPTY_PROPERTY)) { updateEnabled(); } } }; target.addPropertyChangeListener(new WeakPropertyChangeListener(propertyHandler)); } } protected void updateEnabled() { if (target instanceof EditableComponent) { setEnabled(target.isEnabled() && !((EditableComponent) target).isSelectionEmpty()); } else if (target != null) { setEnabled(target.isEnabled()); } } }