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

net.sf.cuf.fw2.AbstractSwingAppPc Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.fw2;

import net.sf.cuf.appevent.AppEvent;
import net.sf.cuf.appevent.AppEventSupport;
import net.sf.cuf.appevent.AppEventUtil;
import net.sf.cuf.appevent.BindEvent;
import net.sf.cuf.fw.Dc;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import java.awt.Component;
import java.awt.Cursor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The AbstractSwingAppPc implements the common stuff of the AppPc interface.
 * The abstract implementation supports the handling of
 * 
    *
  • a menu bar, *
  • a button bar, *
  • a status line and *
  • the blocking/unblocking of the UI *
* via the *
    *
  • MenuToolBarEvent, *
  • BlockEvent and *
  • ShowStatusEvent *
* AppEvent's. * A project specific AppPc is usually derived from AbstractSwingAppPc and * must only (optionally) set the mMenuBar, mToolBar and mStatusLabel * members in its init() method. */ public abstract class AbstractSwingAppPc implements AppPc { /** The separator of menu names */ public static final String SEPARATOR = "/"; /** The next object in the AppEvent responder chain. */ protected AppEventSupport mAppEventSupport; /** Null or the toolbar we manage (must be set by the derived class). */ protected JToolBar mToolBar; /** Null or the menubar we manage (must be set by the derived class). */ protected JMenuBar mMenuBar; /** Maps between a menu name (this is the component name, not the displayed text!) * and the actual menu. * key: hierarchical menu name as String, value: MenuElement object */ protected Map mMenuMap= new HashMap<>(); /** Null or the JFrame/JDialog container to manage for block/unblock events * (must be set by the derived class). */ protected Object mFrameOrDialog; // helper for the block/unblock stuff private GlassPane mGlassPane= new GlassPane(); // null or the last focused component before blocking private Component mLastFocusOwner; /** Null or the label we use for status text events * (must be set by the derived class). */ protected JLabel mStatusLabel; /** * This method is called by the dialog controller peer during * the initialisation phase of an application.
* * @param pDc our peer dialog controller, must implement AppEventSupport * @param pArgs variable argument list modeled as a key/value map, * never null. */ public void init(final Dc pDc, final Map pArgs) { mAppEventSupport= (AppEventSupport)pDc; // register ourselfs for changes in the menu/toolbar structure BindEvent bindMenuToolBar= new BindEvent<>(this, this::menuToolbarChanged, MenuToolBarEvent.class); postAppEvent(bindMenuToolBar ); // register ourselfs for handling gui blocking/unblocking BindEvent bindBlock = new BindEvent<>(this, this::blockChanged, BlockEvent.class); postAppEvent(bindBlock); // register ourselfs for status text handling BindEvent bindShowStatus= new BindEvent<>(this, this::statusChanged, ShowStatusEvent.class); postAppEvent(bindShowStatus); } /** * Process/Dispatch an AppEvent. * * @param pAppEvent event that should be routed/processes * @throws IllegalArgumentException if pAppEvent is null */ public void postAppEvent(AppEvent pAppEvent) { AppEventUtil.postAppEvent(mAppEventSupport, pAppEvent); } /** * Handling of the MenuToolBarEvent. We assume that the derived class * has initialized mToolBar, mMenuBar and mMenuMap. * @param pEvent the event with added/removed toolbar/menu entries */ public void menuToolbarChanged(MenuToolBarEvent pEvent) { boolean delete= pEvent.isDelete(); /* * toolbar stuff */ if (mToolBar!=null) { List toolBarButtons= pEvent.getToolBarButtons(); for (Component component : toolBarButtons) { if (delete) { mToolBar.remove(component); } else { mToolBar.add(component); } mToolBar.repaint(); } } else { if (pEvent.getToolBarButtons().size()>0) { System.err.println("derived class forgot to set our tool bar"); } } /* * menu stuff */ if (mMenuBar!=null) { Map insertionMap = pEvent.getMenuInsertionIndeces(); // loop over all menus to be added/removed for (Map.Entry entry : pEvent.getMenus().entrySet()) { String fullParentMenuName = entry.getKey(); Object value = entry.getValue(); // check value if (!((value instanceof List) || (value instanceof JMenuItem))) { throw new IllegalArgumentException("menuItem value is not a List/JMenuItem but " + value + ", the key was " + fullParentMenuName); } if (!fullParentMenuName.startsWith(SEPARATOR)) { throw new IllegalArgumentException("menuItem name must start with a " + SEPARATOR); } // if we have just on entry, make a list out of it to simplify the code below List menuItems; if (value instanceof JMenuItem) { menuItems = new ArrayList<>(1); menuItems.add((JMenuItem) value); } else { menuItems = (List) value; } // iterate over all items to be added/removed for (final JMenuItem menuItem : menuItems) { // search our parent menuItem if (!mMenuMap.containsKey(fullParentMenuName) && !fullParentMenuName.equals(SEPARATOR)) { throw new IllegalArgumentException( "could not add/delete menuItem for parent " + fullParentMenuName); } // update our menuItem map if we add a named menu if ((menuItem instanceof JMenu) && (menuItem.getName() != null)) { String menuName; if (fullParentMenuName.endsWith(SEPARATOR)) { menuName = fullParentMenuName + menuItem.getName(); } else { menuName = fullParentMenuName + SEPARATOR + menuItem.getName(); } if (delete) { mMenuMap.remove(menuName); } else { if (mMenuMap.containsKey(menuName)) { // the menu to add is already known - we ignore the add request. // At some later point in time we could try an intelligent merge between // the existing and the new menu, but that is fairly complicated. continue; } else { mMenuMap.put(menuName, menuItem); } } } // special handling for top-level menus if (fullParentMenuName.equals(SEPARATOR)) { if (delete) { mMenuBar.remove(menuItem); } else { int index = 0; if (insertionMap.containsKey(fullParentMenuName)) { index = insertionMap.get(fullParentMenuName); } if (index > 0) { // adjust the logical to the real index index--; mMenuBar.add(menuItem, index); } else if (index < 0) { // adjust the logical to the real index index = mMenuBar.getComponentCount() + index + 1; mMenuBar.add(menuItem, index); } else { mMenuBar.add(menuItem); } } mMenuBar.repaint(); } else { // handle normal menus JMenu parentMenu = (JMenu) mMenuMap.get(fullParentMenuName); if (delete) { parentMenu.remove(menuItem); } else { int index = 0; if (insertionMap.containsKey(fullParentMenuName)) { index = insertionMap.get(fullParentMenuName); } if (index > 0) { // adjust the logical to the real index index--; parentMenu.add(menuItem, index); } else if (index < 0) { // adjust the logical to the real index index = parentMenu.getItemCount() + index + 1; parentMenu.add(menuItem, index); } else { parentMenu.add(menuItem); } } } } } } else { if (pEvent.getMenus().size()>0) { System.err.println("derived class forgot to set our menu bar"); } } } /** * Handling of BlockEvent's. We assume that the derived class * has initialized mFrame, otherwise we do nothing. * @param pEvent the event with the block information */ public void blockChanged(BlockEvent pEvent) { // check if we can do something at all JFrame frame = null; JDialog dialog= null; if (mFrameOrDialog instanceof JFrame) { frame=(JFrame)mFrameOrDialog; } else if (mFrameOrDialog instanceof JDialog) { dialog=(JDialog)mFrameOrDialog; } if ((frame==null) && (dialog==null)) { System.err.println("derived class forgot to set our frame/dialog"); return; } if ((frame!=null) && (frame.getGlassPane()!=mGlassPane)) { frame.setGlassPane(mGlassPane); } if ((dialog!=null) && (dialog.getGlassPane()!=mGlassPane)) { dialog.setGlassPane(mGlassPane); } if (pEvent.isBlock()) { mGlassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); mGlassPane.setVisible(true); mLastFocusOwner= (frame!=null) ? frame.getFocusOwner() : dialog.getFocusOwner(); mGlassPane.requestFocus(); } else { mGlassPane.setCursor(Cursor.getDefaultCursor()); mGlassPane.setVisible(false); if (mLastFocusOwner != null && pEvent.isReFocus()) { if (mLastFocusOwner instanceof JComponent) { if (((JComponent)mLastFocusOwner).isRequestFocusEnabled()) { mLastFocusOwner.requestFocus(); } } else { if (mLastFocusOwner.isEnabled()) { mLastFocusOwner.requestFocus(); } } } } } /** * Handling of ShowStatusEvent 's. We assume that the derived class * has initialized mStatusLabel, otherwise we do nothing. * @param pEvent the event with the status text information */ public void statusChanged(ShowStatusEvent pEvent) { if (mStatusLabel!=null) { mStatusLabel.setText(pEvent.getStatusText()); } else { System.err.println("derived class forgot to set our status label"); } } /** * Called from the AppDc peer to cleanup all resources. * The base implementation does nothing. * @param pArgs arguments, key is a String, * value is any suitable objekt for the key */ public void dispose(final Map pArgs) { } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy