/* * @(#)DeleteAction.java * * Copyright (c) 1996-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 edu.umd.cs.findbugs.annotations.Nullable; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.text.*; import org.jhotdraw.util.*; import org.jhotdraw.gui.EditableComponent; import org.jhotdraw.beans.WeakPropertyChangeListener; /** * Deletes the region at (or after) the caret position. * <p> * This action acts on the last {@link org.jhotdraw.gui.EditableComponent} / * {@code JTextComponent} which had the focus when the {@code ActionEvent} * was generated. * <p> * This action is called when the user selects the Delete item in the Edit * menu. The menu item is automatically created by the application. * <p> * If you want this behavior in your application, you have to create an action * with this ID and put it in your {@code ApplicationModel} in method * {@link org.jhotdraw.app.ApplicationModel#initApplication}. * * <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 class DeleteAction extends TextAction { private static final long serialVersionUID = 1L; /** The ID for this action. */ public static final String ID = "edit.delete"; /** The target of the action or null if the action acts on the currently * focused component. */ @Nullable private JComponent target; /** This variable keeps a strong reference on the property change listener. */ private PropertyChangeListener propertyHandler; /** Creates a new instance which acts on the currently focused component. */ public DeleteAction() { this(null,ID); } /** 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 DeleteAction(@Nullable JComponent target) { this(target,ID); } /** Creates a new instance which acts on the specified component. * * @param target The target of the action. Specify null for the currently * focused component. */ protected DeleteAction(@Nullable JComponent target, String id) { super(id); this.target = target; if (target != null) { // Register with a weak reference on the JComponent. propertyHandler = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("enabled".equals(evt.getPropertyName())) { setEnabled((Boolean) evt.getNewValue()); } } }; target.addPropertyChangeListener(new WeakPropertyChangeListener(propertyHandler)); } ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.app.Labels"); labels.configureAction(this, ID); } @Override public void actionPerformed(ActionEvent evt) { JComponent c = target; if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager(). getPermanentFocusOwner() instanceof JComponent)) { c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager(). getPermanentFocusOwner(); } if (c != null && c.isEnabled()) { if (c instanceof EditableComponent) { ((EditableComponent) c).delete(); } else { deleteNextChar(evt); } } } /** This method was copied from * DefaultEditorKit.DeleteNextCharAction.actionPerformed(ActionEvent). */ public void deleteNextChar(ActionEvent e) { JTextComponent c = getTextComponent(e); boolean beep = true; if ((c != null) && (c.isEditable())) { try { javax.swing.text.Document doc = c.getDocument(); Caret caret = c.getCaret(); int dot = caret.getDot(); int mark = caret.getMark(); if (dot != mark) { doc.remove(Math.min(dot, mark), Math.abs(dot - mark)); beep = false; } else if (dot < doc.getLength()) { doc.remove(dot, 1); beep = false; } } catch (BadLocationException bl) { } } if (beep) { Toolkit.getDefaultToolkit().beep(); } } }