/**
* Copyright (c) 2009 Juwi MacMillan Group GmbH
*
* 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.juwimm.cms.util;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventListener;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;
import org.apache.log4j.Logger;
import de.juwimm.cms.common.Constants;
import de.juwimm.cms.gui.event.ExitEvent;
import de.juwimm.cms.gui.event.ExitListener;
import de.juwimm.cms.gui.event.FinishedActionListener;
import de.juwimm.cms.gui.event.ViewComponentEvent;
import de.juwimm.cms.gui.event.ViewComponentListener;
/**
* <b>Tizzit Enterprise Content Management</b><br/>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="mailto:s.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Id$
*/
public final class ActionHub {
private static Logger log = Logger.getLogger(ActionHub.class);
private static EventListenerList listenerList = new EventListenerList();
private static int loadingProcesses = 0;
private ActionHub() {
}
/* ---------------------------------------------------------------------------------------------
* KEY / MOUSE LISTENER FOR CONTENT EDITING MODE
* ---------------------------------------------------------------------------------------------
*/
/**
* This KeyListener is the default KeyListener for all GUI Elements which want to
* get an "Do you want to save" Dialog if someone changes content and will switch
* between the Nodes in the Tree
*/
private static KeyListener klContentEdit = new KeyAdapter() {
@Override
public void keyTyped(KeyEvent ke) {
if (!Constants.EDIT_CONTENT) {
Constants.EDIT_CONTENT = true;
}
}
};
private static MouseListener mlContentEdit = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!Constants.EDIT_CONTENT) {
Constants.EDIT_CONTENT = true;
}
}
};
public static KeyListener getContentEditKeyListener() {
return klContentEdit;
}
public static MouseListener getContentEditMouseListener() {
return mlContentEdit;
}
/* ---------------------------------------------------------------------------------------------
* PROPAGATION OF PROPERTIES
* ---------------------------------------------------------------------------------------------
*/
private static Hashtable<String, PropertyActionEvent> htPropProperties = new Hashtable<String, PropertyActionEvent>();
public static void registerProperty(int propertyType, String uniqueId, String parentId, String descName, String descDetail, String actionCommand) {
PropertyActionEvent pae = null;
if (!htPropProperties.containsKey(uniqueId)) {
pae = new PropertyActionEvent(UIConstants.getMainFrame(), ActionEvent.ACTION_PERFORMED, Constants.PROPERTY_PROPAGATION, uniqueId, propertyType);
pae.setParentId(parentId);
pae.setDescName(descName);
pae.setDescDetail(descDetail);
pae.setAction(actionCommand);
htPropProperties.put(uniqueId, pae);
} else {
pae = htPropProperties.get(uniqueId);
}
ActionHub.fireActionPerformed(pae, true);
}
public static void unregisterProperty(String uniqueId) {
if (htPropProperties.containsKey(uniqueId)) {
PropertyActionEvent pae = new PropertyActionEvent(UIConstants.getMainFrame(), ActionEvent.ACTION_PERFORMED, Constants.PROPERTY_DEPROPAGATION, uniqueId, -1);
ActionHub.fireActionPerformed(pae, true);
}
}
public static void configureProperty(String uniqueId, String key, String value) {
if (htPropProperties.containsKey(uniqueId)) {
PropertyConfigurationEvent pce = new PropertyConfigurationEvent(UIConstants.getMainFrame(), ActionEvent.ACTION_PERFORMED, Constants.PROPERTY_CONFIGURATION, uniqueId);
pce.setKey(key);
pce.setValue(value);
ActionHub.fireActionPerformed(pce, true);
}
}
/* ---------------------------------------------------------------------------------------------
* ACTION HANDLING
* ---------------------------------------------------------------------------------------------
*/
public static void addActionListener(ActionListener l) {
EventListener[] el = listenerList.getListeners(ActionListener.class);
boolean found = false;
for (int i = 0; i < el.length; i++) {
if (el[i] == l) {
found = true;
break;
}
}
if (!found) listenerList.add(ActionListener.class, l);
}
public static void addExitListener(ExitListener l) {
listenerList.add(ExitListener.class, l);
}
public static void addViewComponentListener(ViewComponentListener l) {
listenerList.add(ViewComponentListener.class, l);
}
public static void removeActionListener(ActionListener l) {
listenerList.remove(ActionListener.class, l);
}
// Notify all listeners that have registered interest for
// notification on this event type. The event instance
// is lazily created using the parameters passed into
// the fire method.
public static void fireActionPerformed(ActionEvent event) {
fireActionPerformed(event, false);
}
public static void fireActionPerformed(ActionEvent event, boolean ensureOrder) {
loadingProcesses++;
UIConstants.setWorker(true);
if (log.isDebugEnabled()) log.debug("Fired Action: " + event.getActionCommand() + " loading processes: " + loadingProcesses);
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
UIConstants.setActionStatus(event.getActionCommand());
// Process the listeners last to first, notifying
// those that are interested in this event
Vector<Thread> regThreads = new Vector<Thread>();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ActionListener.class) {
ActionListener al = ((ActionListener) listeners[i + 1]);
Thread t = new Thread(new FireActionPerformedEvent(al, event, ensureOrder));
t.setName("FireActionPerformedEvent");
if (ensureOrder) {
t.run();
} else {
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
regThreads.add(t);
}
}
Thread t = new Thread(new JoinThreadsAndResetStatusInfo(regThreads, event));
t.setName("JoinThreadsAndResetStatusInfo");
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
/**
* <p>Title: Tizzit</p>
* <p>Description: Enterprise Content Management</p>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Revision: 3168 $
*/
private static class FireActionPerformedEvent implements Runnable {
private ActionListener al = null;
private ActionEvent event = null;
private boolean eventDispatcherThread = false;
public FireActionPerformedEvent(ActionListener actionListener, ActionEvent actionEvent, boolean isEventDispatcherThread) {
this.al = actionListener;
this.event = actionEvent;
this.eventDispatcherThread = isEventDispatcherThread;
}
public void run() {
try {
if (eventDispatcherThread) {
al.actionPerformed(event);
} else {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
al.actionPerformed(event);
}
});
}
} catch (Exception exe) {
}
}
}
public static boolean fireExitPerformed(ExitEvent event) {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ExitListener.class) {
if (!((ExitListener) listeners[i + 1]).exitPerformed(event)) { return false; }
}
}
return true;
}
public static void fireViewComponentPerformed(ViewComponentEvent event) {
loadingProcesses++;
UIConstants.setWorker(true);
Object[] listeners = listenerList.getListenerList();
Vector<Thread> regThreads = new Vector<Thread>();
String actionMessage = new Integer(event.getType()).toString();
UIConstants.setActionStatus(actionMessage);
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ViewComponentListener.class) {
ViewComponentListener vcl = ((ViewComponentListener) listeners[i + 1]);
Thread t = new Thread(new FireViewComponentPerformedEvent(vcl, event));
t.setName("FireViewComponentPerformedEvent");
t.setPriority(Thread.NORM_PRIORITY);
t.start();
synchronized (regThreads) {
regThreads.add(t);
}
}
}
Thread t = new Thread(new JoinThreadsAndResetStatusInfo(regThreads, new ActionEvent(UIConstants.getMainFrame(), ActionEvent.ACTION_PERFORMED, actionMessage)));
t.setName("JoinThreadsAndResetStatusInfo");
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
/**
* <p>Title: Tizzit</p>
* <p>Description: Enterprise Content Management</p>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Revision: 3168 $
*/
private static class FireViewComponentPerformedEvent implements Runnable {
private ViewComponentListener vcl = null;
private ViewComponentEvent event = null;
public FireViewComponentPerformedEvent(ViewComponentListener vcListener, ViewComponentEvent vcEvent) {
this.vcl = vcListener;
this.event = vcEvent;
}
public void run() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
vcl.actionViewComponentPerformed(event);
UIConstants.repaintApp();
}
});
} catch (Exception exe) {
}
}
}
/**
* <p>Title: Tizzit</p>
* <p>Description: Enterprise Content Management</p>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Revision: 3168 $
*/
private static class JoinThreadsAndResetStatusInfo implements Runnable {
private Vector regThreads = null;
private ActionEvent event = null;
public JoinThreadsAndResetStatusInfo(Vector vecRegThreads, ActionEvent actionEvent) {
this.regThreads = vecRegThreads;
this.event = actionEvent;
}
public void run() {
//String idName = System.currentTimeMillis() + " " + event.getActionCommand();
synchronized (regThreads) {
Iterator it = regThreads.iterator();
while (it.hasNext()) {
UIConstants.setActionStatus(event.getActionCommand());
Thread t = (Thread) it.next();
try {
t.join();
} catch (Exception exe) {
}
}
}
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
UIConstants.setActionStatus("");
if (--loadingProcesses == 0) {
if (log.isDebugEnabled()) log.debug("finished all processes");
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ActionListener.class) {
if (listeners[i + 1] instanceof FinishedActionListener) {
FinishedActionListener fal = (FinishedActionListener) listeners[i + 1];
if (log.isDebugEnabled()) log.debug("Sending finishedinfo to " + fal.toString());
fal.actionFinished();
}
}
}
UIConstants.setWorker(false);
UIConstants.repaintApp();
} else {
if (log.isDebugEnabled()) log.debug("finished process. remaining: " + loadingProcesses);
}
}
});
} catch (Exception exe) {
}
}
}
/**
* This is a nonblocking method to show a message window.
* @param message The message to show
* @param messageType The JOptionPane-messageType
*/
public static void showMessageDialog(String message, int messageType) {
new MessageDlgOwnerThread(message, messageType).start();
}
/**
* <p>Title: Tizzit</p>
* <p>Description: Enterprise Content Management</p>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Revision: 3168 $
*/
private static class MessageDlgOwnerThread extends Thread {
private String message = "";
private int messageType = JOptionPane.ERROR_MESSAGE;
public MessageDlgOwnerThread(String strMessage, int msgType) {
this.setName("MessageDlgOwnerThread");
this.message = strMessage;
this.messageType = msgType;
}
@Override
public void run() {
try {
SwingUtilities.invokeAndWait(new MessageDlgSwingRunnable(message, messageType));
} catch (Exception exe) {
log.error("Error showing OptionPane", exe);
}
}
}
/**
* <p>Title: Tizzit</p>
* <p>Description: Enterprise Content Management</p>
* <p>Copyright: Copyright (c) 2004</p>
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Revision: 3168 $
*/
private static class MessageDlgSwingRunnable implements Runnable {
private String message = null;
private final int messageType;
public MessageDlgSwingRunnable(String strMessage, int msgType) {
this.message = strMessage;
this.messageType = msgType;
}
public void run() {
JOptionPane.showMessageDialog(UIConstants.getMainFrame(), message, Constants.rb.getString("dialog.title"), messageType);
}
}
}