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

de.schlichtherle.swing.EnhancedPanel Maven / Gradle / Ivy

Go to download

TrueZIP is a Java based Virtual File System (VFS) to enable transparent, multi-threaded read/write access to archive files (ZIP, TAR etc.) as if they were directories. Archive files may be arbitrarily nested and the nesting level is only limited by heap and file system size.

The newest version!
/*
 * Copyright (C) 2006-2010 Schlichtherle IT Services
 *
 * 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 de.schlichtherle.swing;

import de.schlichtherle.swing.event.PanelEvent;
import de.schlichtherle.swing.event.PanelListener;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.Window;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.util.EventListener;
import java.util.logging.Logger;

import javax.swing.JPanel;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.EventListenerList;

/**
 * This class adds methods to fire {@link PanelEvent}s.
 * 

* Note that in TrueZIP 6.1, this class has been refactored to coalesce * multiple panel events for the same cause by posting them to the AWT's * Event Queue, from which the coalesced event would then be dispatched by * AWT's Event Dispatching Thread. *

* However, since TrueZIP 6.4, these events are fired synchronously * again, whereby it is ensured that only a single event is fired for each * cause. * * @author Christian Schlichtherle * @version $Id$ * @since TrueZIP 5.1 */ public class EnhancedPanel extends JPanel { private static final Logger logger = Logger.getLogger(EnhancedPanel.class.getName()); /** * Creates a new {@code EnhancedPanel} with the specified layout * manager and buffering strategy. * * @param layout The {@link LayoutManager} to use. * @param isDoubleBuffered A boolean, true for double-buffering, which * uses additional memory space to achieve fast, flicker-free * updates. */ public EnhancedPanel(LayoutManager layout, boolean isDoubleBuffered) { super(layout, isDoubleBuffered); init(); } /** * Create a new buffered {@code EnhancedPanel} with the specified * layout manager. * * @param layout The {@link LayoutManager} to use. */ public EnhancedPanel(LayoutManager layout) { super(layout); init(); } /** * Creates a new {@code EnhancedPanel} with {@code FlowLayout} * and the specified buffering strategy. * If {@code isDoubleBuffered} is true, the {@code EnhancedPanel} * will use a double buffer. * * @param isDoubleBuffered A boolean, true for double-buffering, which * uses additional memory space to achieve fast, flicker-free * updates. */ public EnhancedPanel(boolean isDoubleBuffered) { super(isDoubleBuffered); init(); } /** * Creates a new {@code EnhancedPanel} with a double buffer * and a flow layout. */ public EnhancedPanel() { init(); } private void init() { addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(final HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != HierarchyEvent.SHOWING_CHANGED) return; /*if (!isVisible()) return;*/ final Window window = getAncestorWindow(); final boolean windowShown = window.isShowing(); if (windowShown != isShowing()) return; processPanelEvent(new PanelEvent(EnhancedPanel.this, windowShown ? PanelEvent.ANCESTOR_WINDOW_SHOWN : PanelEvent.ANCESTOR_WINDOW_HIDDEN)); } }); /*final ComponentListener cl = new ComponentAdapter() { public void componentShown(ComponentEvent evt) { // Depending on which method the ancestor window uses to show // itself, multiple ComponentEvents may occur for the same event. // By posting the subsequent PanelEvents to the AWT Event Queue, // they can be coalesced into one event again. final PanelEvent event = new PanelEvent(EnhancedPanel.this, PanelEvent.ANCESTOR_WINDOW_SHOWN); logger.finer("Posting " + event); getToolkit().getSystemEventQueue().postEvent(event); //processPanelEvent(event); } public void componentHidden(ComponentEvent evt) { // Depending on which method the ancestor window uses to hide // itself, multiple ComponentEvents may occur for the same event. // By posting the subsequent PanelEvents to the AWT Event Queue, // they can be coalesced into one event again. final PanelEvent event = new PanelEvent(EnhancedPanel.this, PanelEvent.ANCESTOR_WINDOW_HIDDEN); logger.finer("Posting " + event); getToolkit().getSystemEventQueue().postEvent(event); //processPanelEvent(event); } }; addAncestorListener(new AncestorListener() { public void ancestorAdded(final AncestorEvent evt) { // Note that with J2SE 1.4.2_10 this event happens BEFORE // the ancestor window is made visible, while with // J2SE 1.5.0_06 this event happens AFTER the ancestor is // made visible. final Window window = getAncestorWindow(evt.getAncestor()); window.addComponentListener(cl); final boolean windowShown = window.isShowing(); //assert windowShown == isShowing(); if (windowShown) cl.componentShown(null); } public void ancestorRemoved(final AncestorEvent evt) { // Note that with J2SE 1.4.2_10 this event happens BEFORE // the ancestor window is made visible, while with // J2SE 1.5.0_06 this event happens AFTER the ancestor is // made visible. final Window window = getAncestorWindow(evt.getAncestor()); window.removeComponentListener(cl); final boolean windowShown = window.isShowing(); //assert windowShown == isShowing(); if (!windowShown) cl.componentHidden(null); } public void ancestorMoved(AncestorEvent evt) { } });*/ } /** * Overridden in order to prevent this component to deliver a * {@link PanelEvent} multiple times from the same source. * * @deprecated See {@link EnhancedPanel}. */ protected AWTEvent coalesceEvents( final AWTEvent existingEvent, final AWTEvent newEvent) { assert existingEvent.getSource() == newEvent.getSource(); // Coalesce arbitrary sequences of ANCESTOR_WINDOW_* events into // the last one. if (existingEvent instanceof PanelEvent && newEvent instanceof PanelEvent) { assert false : "This is dead code since the refactoring for TrueZIP 6.4!"; final int id = newEvent.getID(); assert id == existingEvent.getID(); switch (id) { case PanelEvent.ANCESTOR_WINDOW_SHOWN: case PanelEvent.ANCESTOR_WINDOW_HIDDEN: return newEvent; } } return super.coalesceEvents(existingEvent, newEvent); } /** * Overridden in order to process {@link PanelEvent}s. * * @deprecated See {@link EnhancedPanel}. */ protected void processEvent(final AWTEvent event) { if (event instanceof PanelEvent) { //assert false : "This is dead code since the refactoring for TrueZIP 6.4!"; processPanelEvent((PanelEvent) event); } else { super.processEvent(event); } } /** * Calls {@link #fireAncestorWindowShown} or * {@link #fireAncestorWindowHidden}, depending on the ID of the given * {@code event}. */ protected void processPanelEvent(final PanelEvent event) { logger.fine("Processing " + event); switch (event.getID()) { case PanelEvent.ANCESTOR_WINDOW_SHOWN: fireAncestorWindowShown(event); break; case PanelEvent.ANCESTOR_WINDOW_HIDDEN: fireAncestorWindowHidden(event); break; default: throw new AssertionError(); } } /** * Returns the ancestor {@link Window} of this {@code Panel} or * {@code null} if the component is not (yet) placed in a * {@code Window}. */ public Window getAncestorWindow() { return getAncestorWindow(this); } private static final Window getAncestorWindow(Component c) { while (c != null && !(c instanceof Window)) c = c.getParent(); return (Window) c; } /** * Utility field used by event firing mechanism. * Note that the listeners don't get serialized with this component! */ private transient EventListenerList listenerList; /** * Adds the {@code listener} to the list of receivers for * {@link PanelEvent}s. *

* Note that the listener doesn't get serialized with this component! * * @param listener The listener to add. * If this method is called {@code n} times with the same * listener, any events generated will be delivered to this * listener {@code n} times. * * @throws NullPointerException If {@code listener} is * {@code null}. */ public void addPanelListener(final PanelListener listener) { if (listener == null) throw new NullPointerException(); if (listenerList == null ) listenerList = new EventListenerList(); listenerList.add(PanelListener.class, listener); } /** * Removes the {@code listener} from the list of receivers for * {@link PanelEvent}s. * * @param listener The listener to remove. * If this listener has been {@link #addPanelListener added} * multiple times, it is removed from the list only once. * * @throws NullPointerException If {@code listener} is * {@code null}. */ public void removePanelListener(final PanelListener listener) { if (listener == null) throw new NullPointerException(); if (listenerList == null) return; listenerList.remove(PanelListener.class, listener); } /** * Returns an array of all the panel listeners * registered on this component. * * @return All of this panel's {@code PanelListener}s or an empty * array if no panel listeners are currently registered. * * @see #addPanelListener * @see #removePanelListener */ public PanelListener[] getPanelListeners() { if (listenerList != null) return (PanelListener[]) listenerList.getListeners(PanelListener.class); else return new PanelListener[0]; } public EventListener[] getListeners(Class listenerType) { if (listenerType == PanelListener.class) return getPanelListeners(); else return super.getListeners(listenerType); } /** * Notifies all registered listeners about the event. * This is a synchronous operation. * * @param event The event to be fired. * * @deprecated You should not call this method directly. */ protected void fireAncestorWindowShown(final PanelEvent event) { if (listenerList == null) return; final Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == PanelListener.class) ((PanelListener) listeners[i+1]).ancestorWindowShown(event); } } /** * Notifies all registered listeners about the event. * This is a synchronous operation. * * @param event The event to be fired. * * @deprecated You should not call this method directly. */ protected void fireAncestorWindowHidden(final PanelEvent event) { if (listenerList == null) return; final Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == PanelListener.class) ((PanelListener) listeners[i+1]).ancestorWindowHidden(event); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy