jaxx.runtime.swing.help.JAXXHelpBroker Maven / Gradle / Ivy
/*
* *##%
* JAXX Runtime
* Copyright (C) 2008 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* ##%*
*/
package jaxx.runtime.swing.help;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;
import javax.help.CSH;
import javax.help.HelpBroker;
import javax.help.HelpSet;
import javax.swing.AbstractButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXObject;
import jaxx.runtime.SwingUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* La classe pour encapsuler l'aide de l'application.
*
* @author tony
* @since 1.4
*/
public class JAXXHelpBroker {
public static final String JAXX_CONTEXT_ENTRY = "jaxxcontext";
/**
* Logger
*/
static private Log log = LogFactory.getLog(JAXXHelpBroker.class);
/**
* name of helpset
*/
protected final String helpsetName;
/**
* default id to use if none given
*/
protected final String defaultID;
/**
* help key
*/
protected final String helpKey;
/**
* helpset to use
*/
protected HelpSet helpset;
/**
* help broker
*/
protected HelpBroker helpBroker;
/**
* current locale used
*/
protected Locale locale;
/**
* cache of cursors modified when in context-sensitive mode
*/
protected Hashtable cursors;
/**
* cursor to use in context-sensitive mode
*/
protected Cursor onItemCursor;
/**
* cache of component which cursor have been modified
*/
protected final Map cache;
/**
* help ui handler
*/
protected JAXXHelpUIHandler handler;
public JAXXHelpBroker(String helpsetName, String helpKey, String defaultID, JAXXHelpUIHandler handler) {
this(null, helpsetName, helpKey, defaultID, handler);
}
public JAXXHelpBroker(Locale locale, String helpsetName, String helpKey, String defaultID, JAXXHelpUIHandler handler) {
if (helpsetName == null) {
throw new NullPointerException("parameter helpsetName can not be null!");
}
if (handler == null) {
throw new NullPointerException("handler can not be null");
}
this.locale = locale;
this.helpsetName = helpsetName;
this.helpKey = helpKey;
this.defaultID = defaultID;
this.handler = handler;
this.cache = new HashMap();
}
public void prepareUI(JAXXObject c) {
if (c == null) {
throw new NullPointerException("parameter c can not be null!");
}
// l'ui doit avoir un boutton showHelp
AbstractButton help = getShowHelpButton(c);
if (help == null) {
// no showHelp button
return;
}
// attach context to button
if (log.isDebugEnabled()) {
log.debug("attach context to showhelp button " + c);
}
help.putClientProperty(JAXX_CONTEXT_ENTRY, c);
// add tracking action
ActionListener listener = getShowHelpAction();
if (log.isDebugEnabled()) {
log.debug("adding tracking action " + listener);
}
help.addActionListener(listener);
if (log.isDebugEnabled()) {
log.debug("done for " + c);
}
getHelpBroker().enableHelpKey(((Component) c), getDefaultID(), getHelpset());
}
public void showHelp(JAXXContext context, String helpId) {
getHandler().showHelp(context, this, helpId);
}
public JAXXHelpUIHandler getHandler() {
return handler;
}
public HelpBroker getHelpBroker() {
if (helpBroker == null) {
helpBroker = getHelpset().createHelpBroker();
}
return helpBroker;
}
public String getHelpKey() {
return helpKey;
}
public HelpSet getHelpset() {
if (helpset == null) {
try {
ClassLoader cl = getClass().getClassLoader();
URL url = HelpSet.findHelpSet(cl, helpsetName, locale);
helpset = new HelpSet(cl, url);
} catch (Exception ee) {
throw new IllegalStateException("could not find help set " + helpsetName + " for reason " + ee.getMessage(), ee);
}
}
return helpset;
}
public String getHelpsetName() {
return helpsetName;
}
public String getDefaultID() {
return defaultID;
}
public void setLocale(Locale locale) {
this.locale = locale;
// need to reload helpset and helpbroker
helpset = null;
helpBroker = null;
getHelpset();
getHelpBroker();
}
public void showHelpSet() {
if (log.isDebugEnabled()) {
log.debug(this);
}
new CSH.DisplayHelpFromSource(getHelpBroker());
}
public void installUI(Component comp, String helpId) {
CSH.setHelpIDString(comp, helpId);
if (log.isDebugEnabled()) {
log.debug(helpId + " : " + comp.getName());
}
cache.put(comp, helpId);
}
public class ShowHelpForTrackedComponentAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
AbstractButton source = (AbstractButton) e.getSource();
JAXXContext context = (JAXXContext) source.getClientProperty(JAXX_CONTEXT_ENTRY);
// prepare cursor
onItemCursor = (Cursor) UIManager.get("HelpOnItemCursor");
Vector> topComponents = null;
cursors = null;
if (onItemCursor != null) {
cursors = new Hashtable();
topComponents = getTopContainers(source);
Enumeration> enums = topComponents.elements();
while (enums.hasMoreElements()) {
setAndStoreCursors((Container) enums.nextElement(), onItemCursor);
}
}
// get the tracked component
Component comp = null;
try {
MouseEvent event = getMouseEvent();
if (event == null) {
// tracking canceled
return;
}
comp = (Component) event.getSource();
if (log.isDebugEnabled()) {
log.debug("component traking " + comp.getName() + " : " + comp.getClass().getName());
}
comp = SwingUtil.getDeepestObjectAt(comp, event.getX(), event.getY());
if (log.isDebugEnabled()) {
log.debug("deepest component " + comp.getName() + " : " + comp.getClass().getName());
}
} finally {
// restore the old cursors
if (topComponents != null) {
Enumeration> containers = topComponents.elements();
while (containers.hasMoreElements()) {
resetAndRestoreCursors((Container) containers.nextElement());
}
}
cursors = null;
}
String helpID = findHelpId(comp);
showHelp(context, helpID);
}
public String findHelpId(Component comp) {
String helpID = CSH.getHelpIDString(comp);
if (defaultID.equals(helpID)) {
String id = cache.get(comp);
// on verifie qu'on est bien sur sur le bon id
if (helpID.equals(id)) {
// ok
return helpID;
}
if (log.isDebugEnabled()) {
log.debug("will try to find better id for comp : " + comp.getName());
}
// on est pas sur le bon id
// on recherche parmis les parents
helpID = findExtactHelpId(comp);
}
if (log.isInfoEnabled()) {
log.info("helpID " + helpID + " for comp " + comp.getName() + " : " + comp.getClass().getName());
}
return helpID;
}
protected String findExtactHelpId(Component comp) {
Container parent = comp.getParent();
while (parent != null) {
String id = cache.get(parent);
if (id == null) {
// ce container n'a pas d'id
// on va directement sur le parent
parent = parent.getParent();
continue;
}
// le parent possède un id
// on utilise cet id
return id;
}
// on a pas trouve d'id
// on retourne l'id par defaut
return defaultID;
}
}
protected AbstractButton getShowHelpButton(JAXXObject c) {
return (AbstractButton) c.getObjectById("showHelp");
}
protected ActionListener getShowHelpAction() {
return new ShowHelpForTrackedComponentAction();
}
//-------------------------------------------------------------------------
//--- Copy CSH code but with accessible modifiers and little improvments
//-------------------------------------------------------------------------
/*
* Get all top level containers to change it's cursors
*/
protected Vector> getTopContainers(Object source) {
// This method is used to obtain all top level components of application
// for which the changing of cursor to question mark is wanted.
// Method Frame.getFrames() is used to get list of Frames and
// Frame.getOwnedWindows() method on elements of the list
// returns all Windows, Dialogs etc. It works correctly in application.
// Problem is in applets. There is no way how to get reference to applets
// from elsewhere than applet itself. So, if request for CSH (this means
// pressing help button or select help menu item) does't come from component
// in a Applet, cursor for applets is not changed to question mark. Only for
// Frames, Windows and Dialogs is cursor changed properly.
Vector containers = new Vector();
Component topComponent = null;
topComponent = getRoot(source);
if (topComponent instanceof Applet) {
try {
Enumeration
© 2015 - 2025 Weber Informatics LLC | Privacy Policy