jaxx.runtime.swing.help.JAXXHelpBroker Maven / Gradle / Ivy
/*
* #%L
* JAXX :: Runtime
*
* $Id: JAXXHelpBroker.java 2766 2014-01-10 16:52:31Z tchemit $
* $HeadURL: https://nuiton.org/svn/jaxx/tags/jaxx-2.8.2/jaxx-runtime/src/main/java/jaxx/runtime/swing/help/JAXXHelpBroker.java $
* %%
* Copyright (C) 2008 - 2010 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
* .
* #L%
*/
package jaxx.runtime.swing.help;
import com.google.common.base.Preconditions;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXObject;
import jaxx.runtime.awt.visitor.BuildTreeVisitor;
import jaxx.runtime.awt.visitor.ComponentTreeNode;
import jaxx.runtime.awt.visitor.GetCompopentAtPointVisitor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.help.CSH;
import javax.help.HelpBroker;
import javax.help.HelpSet;
import javax.help.plaf.basic.BasicCursorFactory;
import javax.swing.AbstractButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.ActiveEvent;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.MenuComponent;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
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.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;
/**
* La classe pour encapsuler l'aide de l'application.
*
* @author tchemit
* @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");
if (onItemCursor == null) {
onItemCursor = BasicCursorFactory.getOnItemCursor();
UIManager.put("HelpOnItemCursor", onItemCursor);
}
Preconditions.checkNotNull(onItemCursor, "A cursor is missing (add HelpOnItemCursor cursor in UIManager).");
Vector> topComponents = null;
cursors = null;
if (onItemCursor != null) {
cursors = new Hashtable();
topComponents = getTopContainers(source);
for (Object topComponent : topComponents) {
setAndStoreCursors((Container) topComponent, 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 = getDeppestComponent(comp, event);
if (log.isDebugEnabled()) {
log.debug("deepest component " + comp.getName() + " : " + comp.getClass().getName());
}
} finally {
// restore the old cursors
if (topComponents != null) {
for (Object topComponent : topComponents) {
resetAndRestoreCursors((Container) topComponent);
}
}
cursors = null;
}
String helpID = findHelpId(comp);
showHelp(context, helpID);
}
}
protected AbstractButton getShowHelpButton(JAXXObject c) {
return (AbstractButton) c.getObjectById("showHelp");
}
protected ActionListener getShowHelpAction() {
return new ShowHelpForTrackedComponentAction();
}
protected Component getDeppestComponent(Component mouseComponent, MouseEvent event) {
ComponentTreeNode tree = BuildTreeVisitor.buildTree(mouseComponent);
Point point = event.getLocationOnScreen();
Component component = GetCompopentAtPointVisitor.get(tree, point);
if (log.isDebugEnabled()) {
log.debug("Component at (" + point + "): " + component);
}
return component;
// return SwingUtil.getDeepestObjectAt(mouseComponent, event.getX(), event.getY());
}
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;
}
//-------------------------------------------------------------------------
//--- 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