/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ /* * The org.opensourcephysics.media.core package defines the Open Source Physics * media framework for working with video and other media. * * Copyright (c) 2014 Douglas Brown and Wolfgang Christian. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * For additional information and documentation on Open Source Physics, * please see <http://www.opensourcephysics.org/>. */ package org.opensourcephysics.media.core; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import javax.swing.JDialog; /** * This is a Filter that contains and manages a series of Filters. * * @author Douglas Brown * @version 1.0 */ public class FilterStack extends Filter implements PropertyChangeListener { // instance fields private ArrayList<Filter> filters = new ArrayList<Filter>(); private Filter postFilter; private int indexRemoved = -1; /** * Constructs a FilterStack object. */ public FilterStack() { /** empty block */ } /** * Adds a filter to the end of the stack. Multiple filters are applied * in the order they are added. * * @param filter the filter */ public void addFilter(Filter filter) { filters.add(filter); filter.stack = this; filter.removePropertyChangeListener(this); filter.addPropertyChangeListener(this); support.firePropertyChange("image", null, null); //$NON-NLS-1$ support.firePropertyChange("filter", null, filter); //$NON-NLS-1$ } /** * Adds a filter at the specified index. Multiple filters are applied * in index order. * * @param filter the filter * @param index the index */ public void insertFilter(Filter filter, int index) { index = Math.min(index, filters.size()); index = Math.max(index, 0); filters.add(index, filter); filter.stack = this; filter.addPropertyChangeListener(this); support.firePropertyChange("image", null, null); //$NON-NLS-1$ support.firePropertyChange("filter", null, filter); //$NON-NLS-1$ } /** * Gets the index of the last removed filter, or -1 if none removed. * * @return the stack index. */ public int lastIndexRemoved() { return indexRemoved; } /** * Sets the post filter. If non-null, the post filter is applied after all * other filters. * * @param filter a filter */ public void setPostFilter(Filter filter) { if(postFilter!=null) { postFilter.removePropertyChangeListener(this); } postFilter = filter; if(filter!=null) { filter.addPropertyChangeListener(this); support.firePropertyChange("image", null, null); //$NON-NLS-1$ support.firePropertyChange("filter", null, filter); //$NON-NLS-1$ } } /** * Gets the post filter. * * @return the post filter */ public Filter getPostFilter() { return postFilter; } /** * Gets the first instance of the specified filter class. May return null. * * @param filterClass the filter class * @return the first filter of the specified class, if any */ public Filter getFilter(Class<?> filterClass) { Iterator<Filter> it = filters.iterator(); while(it.hasNext()) { Filter filter = it.next(); if(filter.getClass()==filterClass) { return filter; } } return null; } /** * Removes the specified filter from the stack. * * @param filter the filter */ public void removeFilter(Filter filter) { indexRemoved = filters.indexOf(filter); if(indexRemoved>-1) { filters.remove(filter); filter.dispose(); support.firePropertyChange("image", null, null); //$NON-NLS-1$ support.firePropertyChange("filter", filter, null); //$NON-NLS-1$ } System.gc(); } /** * Clears the filter stack. */ public void clear() { for (Filter filter: filters) { filter.dispose(); } filters.clear(); support.firePropertyChange("image", null, null); //$NON-NLS-1$ support.firePropertyChange("filter", null, null); //$NON-NLS-1$ System.gc(); } /** * Returns true if this contains no filters. * * @return <code>true</code> if this is empty */ public boolean isEmpty() { return filters.isEmpty()&&(postFilter==null); } /** * Returns a copy of the filters in this filter stack. * * @return a collection of filters */ public ArrayList<Filter> getFilters() { return new ArrayList<Filter>(filters); } /** * Returns the current filtered image. * * @param image the image to filter * @return the filtered image */ public BufferedImage getFilteredImage(BufferedImage image) { if(!isEnabled()) { return image; } Iterator<Filter> it = filters.iterator(); while(it.hasNext()) { Filter filter = it.next(); image = filter.getFilteredImage(image); } if(postFilter!=null) { image = postFilter.getFilteredImage(image); } return image; } /** * Implements abstract Filter method. * * @return the inspector */ public JDialog getInspector() { return null; } /** * Shows/hides all inspectors. * * @param vis true to show inspectors */ public void setInspectorsVisible(boolean vis) { Collection<Filter> filters = getFilters(); Iterator<Filter> it = filters.iterator(); while(it.hasNext()) { Filter filter = it.next(); JDialog inspector = filter.getInspector(); if(inspector!=null) { if(!vis) { // set the inspector's current visibility flag filter.inspectorVisible = inspector.isVisible(); // make sure all inspectors are hidden inspector.setVisible(false); } else if(!inspector.isModal()) { // show only non-modal inspectors // use the visibility flag to set the visibility of every inspector inspector.setVisible(filter.inspectorVisible); } } } } /** * Refreshes this filter's GUI */ public void refresh() { Iterator<Filter> it = getFilters().iterator(); while(it.hasNext()) { it.next().refresh(); } } /** * Responds to property change events. FilterStack listens for the * following events: all events from its filters. * * @param e the property change event */ public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().equals("filterChanged")) { //$NON-NLS-1$ support.firePropertyChange("filterChanged", e.getOldValue(), e.getNewValue()); //$NON-NLS-1$ } else { support.firePropertyChange("image", null, null); //$NON-NLS-1$ } } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */