/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * 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 org.arakhne.afc.ui.swing.undo; import java.awt.event.ActionEvent; import java.lang.reflect.Constructor; import javax.swing.Icon; import javax.swing.undo.UndoManager; import org.arakhne.afc.ui.swing.StandardAction; import org.arakhne.afc.vmutil.ReflectionUtil; /** Implementation of an action that is creating and * adding an UndoableEdit into the given undo manager. * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @deprecated see JavaFX API */ @Deprecated public class UndoableAction extends StandardAction { private static final long serialVersionUID = 7640859658516394571L; private final UndoManager undoManager; private final Class<? extends AbstractCallableUndoableEdit> type; private final Object[] constructorParameters; /** * @param label * @param tooltip * @param icon * @param manager * @param type * @param constructorParameters */ public UndoableAction( String label, String tooltip, Icon icon, UndoManager manager, Class<? extends AbstractCallableUndoableEdit> type, Object... constructorParameters) { this.undoManager = manager; this.type = type; this.constructorParameters = constructorParameters; setText(label); setToolTipText(tooltip); setIcon(icon); } /** * @param manager * @param type * @param constructorParameters */ public UndoableAction( UndoManager manager, Class<? extends AbstractCallableUndoableEdit> type, Object... constructorParameters) { this(null, null, null, manager, type, constructorParameters); } /** * @param label * @param icon * @param manager * @param type * @param constructorParameters */ public UndoableAction( String label, Icon icon, UndoManager manager, Class<? extends AbstractCallableUndoableEdit> type, Object... constructorParameters) { this(label, null, icon, manager, type, constructorParameters); } /** * @param label * @param manager * @param type * @param constructorParameters */ public UndoableAction( String label, UndoManager manager, Class<? extends AbstractCallableUndoableEdit> type, Object... constructorParameters) { this(label, null, null, manager, type, constructorParameters); } /** * @param icon * @param manager * @param type * @param constructorParameters */ public UndoableAction( Icon icon, UndoManager manager, Class<? extends AbstractCallableUndoableEdit> type, Object... constructorParameters) { this(null, null, icon, manager, type, constructorParameters); } @Override public final void actionPerformed(ActionEvent e) { AbstractCallableUndoableEdit undo; try { undo = newEditInstance(this.type, this.constructorParameters); } catch (Exception ex) { throw new RuntimeException(ex); } undo.doEdit(); this.undoManager.addEdit(undo); } /** Invoked to create an instance of undoable edit. * By default, this function invokes the constructor by * reflection. * This function may be overridden to provide an other mean to * create the edit instance. * * @param type is the type of edit to create. * @param constructorParameters are the parameters to pass to the constructor. * @return the edit instance, never <code>null</code>. * @throws Exception */ @SuppressWarnings("static-method") protected AbstractCallableUndoableEdit newEditInstance(Class<? extends AbstractCallableUndoableEdit> type, Object[] constructorParameters) throws Exception { for(Constructor<?> cons : type.getDeclaredConstructors()) { if (matches(cons.getParameterTypes(), constructorParameters)) { boolean b = cons.isAccessible(); try { cons.setAccessible(true); return type.cast(cons.newInstance(constructorParameters)); } catch(Throwable e) { // } finally { cons.setAccessible(b); } } } throw new InstantiationException(); } /** Test if the instances are matching the types. * * @param types * @param instances * @return <code>true</code> if the instances are matching the types; * otherwise <code>false</code>. */ protected static boolean matches(Class<?>[] types, Object[] instances) { if (types==null) return instances==null || instances.length==0; assert(types!=null); if (instances==null) return types.length==0; if (types.length==instances.length) { for(int i=0; i<types.length; ++i) { // Use the reflection util that supports the base types. if (!ReflectionUtil.isInstance(types[i],instances[i])) return false; } return true; } return false; } }