/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Stroke;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.util.ResourceBundle;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;

import ilog.views.IlvApplyObject;
import ilog.views.IlvGraphic;
import ilog.views.IlvHandlesSelection;
import ilog.views.IlvManager;
import ilog.views.IlvManagerView;
import ilog.views.IlvPoint;
import ilog.views.IlvRect;
import ilog.views.accelerator.IlvPopupMenuAccelerator;
import ilog.views.graphic.IlvZoomableLabel;
import ilog.views.interactor.IlvSelectInteractor;
import ilog.views.interactor.IlvZoomViewInteractor;
import ilog.views.swing.IlvJManagerViewControlBar;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.swing.IlvPopupMenuContext;
import ilog.views.swing.IlvPopupMenuManager;
import ilog.views.swing.IlvSimplePopupMenu;
import ilog.views.util.IlvLocaleUtil;
// import ilog.views.util.IlvProductUtil;
import ilog.views.util.IlvResourceUtil;

/**
 * This is a very simple application that shows how to use pop-up
 * menus on <code>IlvGraphic</code> objects inside a manager.
 */
SuppressWarnings("serial")
public class PopupMenuApp extends JRootPane {

  {
    // This sample uses JViews Diagrammer features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Perforce JViews Diagrammer Deployment license.
    // IlvProductUtil.DeploymentLicenseRequired(
    // IlvProductUtil.JViews_Diagrammer_Deployment);
  }

  /**
   * Color constants used in this demo.
   */
  Color GREEN = new Color(128, 255, 128);
  Color RED = new Color(255, 128, 128);
  Color BLUE = new Color(128, 128, 255);

  /**
   * Initializes the application.
   */
  public void init() {
    // create a manager
    final IlvManager manager = new IlvManager();

    // create a manager view
    final IlvManagerView mgrview = new IlvManagerView(manager);

    // create the scroll manager view
    IlvJScrollManagerView scrollManView = new IlvJScrollManagerView(mgrview);

    // Some settings on the manager view and on the scroll manager view
    mgrview.setAntialiasing(true);
    mgrview.setKeepingAspectRatio(true);
    mgrview.setBackground(Color.white);
    mgrview.setForeground(SystemColor.windowText);
    Color xc = SystemColor.windowText;
    xc = new Color(255 - xc.getRed(), 255 - xc.getGreen(), 255 - xc.getBlue());
    mgrview.setDefaultXORColor(xc);
    mgrview.setDefaultGhostColor(SystemColor.windowText);
    mgrview.setZoomFactorRange(0.02, 10.0);

    // Settings parameters for selection handles
    IlvHandlesSelection.defaultHandleColor = Color.black;
    IlvHandlesSelection.defaultHandleBackgroundColor = Color.white;
    IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE;

    // create the standard control bar
    IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar();
    controlBar.setView(mgrview);

    // modify the interactors such that the demo looks better
    ((IlvSelectInteractor) controlBar.getSelectInteractor()).setOpaqueMove(true);
    ((IlvZoomViewInteractor) controlBar.getZoomViewInteractor()).setPermanent(true);

    // set the initial interactor
    mgrview.setInteractor(controlBar.getSelectInteractor());

    final IlvPopupMenuAccelerator popupKeyboardAccel =
        new IlvPopupMenuAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_F1, 0);
    final IlvPopupMenuAccelerator popupKeyboardAccel2 =
        new IlvPopupMenuAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_P, 0);
    manager.addAccelerator(popupKeyboardAccel);
    manager.addAccelerator(popupKeyboardAccel2);

    // -----------------------------------------------------------------------
    // Now, fill the manager and set up the pop-up menus

    // register view view to the pop-up manager
    IlvPopupMenuManager.registerView(mgrview);

    // register the menus under different names
    IlvPopupMenuManager.registerMenu("MENU1", createVerySimpleMenu());
    IlvPopupMenuManager.registerMenu("MENU2", createSimpleMenu());
    IlvPopupMenuManager.registerMenu("MENU3", createFancyMenu());
    IlvPopupMenuManager.registerMenu("MENU4", createI18NMenu());

    // fill the manager with graphic objects that use menu1
    for (int j = 0; j < 4; j++) {
      for (int i = 0; i < 10; i++) {
        double x = 10 + j * 130;
        double y = (i + 1) * 30;
        IlvZoomableLabel graphic = new IlvZoomableLabel(new IlvPoint(x, y), "Label" + i, false);
        graphic.setAntialiasing(true);
        graphic.setLeftMargin(6);
        graphic.setRightMargin(6);
        graphic.setTopMargin(4);
        graphic.setBottomMargin(4);
        graphic.setBorderOn(true);
        graphic.setBackgroundOn(true);
        switch (i % 3) {
          case 0:
            graphic.setBackgroundPaint(GREEN);
            break;
          case 1:
            graphic.setBackgroundPaint(RED);
            break;
          case 2:
            graphic.setBackgroundPaint(BLUE);
            break;
        }

        // set the pop-up menu or the graphic
        switch (j) {
          case 0:
            graphic.setPopupMenuName("MENU1");
            break;
          case 1:
            graphic.setPopupMenuName("MENU2");
            break;
          case 2:
            graphic.setPopupMenuName("MENU3");
            break;
          case 3:
            graphic.setPopupMenuName("MENU4");
            break;
        }

        // Alternatively, it is possible to set the pop-up menu directly
        // without using its name, e.g.,
        //
        // graphic.setPopupMenu(createSimpleMenu());
        //
        // This has however several disadvantages:
        // 1) If possible, pop-up menus should be shared among graphic objects
        // to avoid wasting memory
        // 2) If pop-up menus are set directly, they are not persistent, i.e.,
        // they are not stored in IVL files and are not preserved during
        // copy + paste operations.


        // add the graphic to the manager
        manager.addObject(graphic, true);
      }
    }

    // create the pop-up for the top level manager
    manager.setPopupMenu(createManagerMenu());

    // create a checkbox that allows to disable the pop-up menus in the view
    JCheckBox usePopupMenus = new JCheckBox("Pop-up Menus", true);
    usePopupMenus.setToolTipText("Enable or disable the pop-up menus in the view");
    usePopupMenus.addItemListener(new ItemListener() {
      Override
      public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
          IlvPopupMenuManager.registerView(mgrview);
          manager.addAccelerator(popupKeyboardAccel);
          manager.addAccelerator(popupKeyboardAccel2);
        } else if (e.getStateChange() == ItemEvent.DESELECTED) {
          IlvPopupMenuManager.unregisterView(mgrview);
          manager.removeAccelerator(popupKeyboardAccel);
          manager.removeAccelerator(popupKeyboardAccel2);
        }
      }
    });


    // create the top panel with the toolbar and the pop-up checkbox
    JPanel topPanel = new JPanel();
    topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    topPanel.add(controlBar);
    topPanel.add(usePopupMenus);

    // put manager view, top panel and bottom panel together
    getContentPane().setLayout(new BorderLayout(0, 0));
    getContentPane().add(scrollManView, BorderLayout.CENTER);
    getContentPane().add(topPanel, BorderLayout.NORTH);
  }

  /**
   * Creates a very simple pop-up menu.
   * In principle, you can use any JPopupMenu at the graphic object.
   * However, the IlvSimplePopupMenu is very conveniant to configure, hence
   * we use it in this sample.
   */
  private JPopupMenu createVerySimpleMenu() {
    // create the action listener for the pop-up menu
    ActionListener actionListener = new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {

        // retrieve the selected menu item
        JMenuItem m = (JMenuItem) e.getSource();

        // retrieve the graphic that has this pop-up menu
        IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
        IlvGraphic graphic = context.getGraphic();

        // do the action.
        // Use IlvSimplePopupMenu.getMenuItemText(m) to get the original
        // menu item text that is not affected by base text direction Bidi
        // control characters. Only needed if base text direction is not
        // UNDEFINED_DIRECTION
        if (IlvSimplePopupMenu.getMenuItemText(m).equals("Make larger"))
          makeLarger(graphic);
        else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Make smaller"))
          makeSmaller(graphic);
      }
    };

    // create a simple pop-up menu with the following items
    // - Make larger: makes the graphic larger
    // - Make smaller: makes the graphic smaller
    // Note about the format: the first leading blanc character, and the
    // last trailing blanc character of each item is option; if it is there
    // then it is ignored. Hence "Make larger | Make smaller" and
    // "Make larger|Make smaller" mean the same.
    IlvSimplePopupMenu menu =
        new IlvSimplePopupMenu("Menu1", "Make larger | Make smaller", null, actionListener);

    return menu;
  }

  /**
   * Creates a simple pop-up menu.
   * In principle, you can use any JPopupMenu at the graphic object.
   * However, the IlvSimplePopupMenu is very conveniant to configure, hence
   * we use it in this sample.
   */
  private JPopupMenu createSimpleMenu() {
    // create the action listener for the pop-up menu
    ActionListener actionListener = new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {

        // retrieve the selected menu item
        JMenuItem m = (JMenuItem) e.getSource();

        // retrieve the graphic that has this pop-up menu
        IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
        IlvGraphic graphic = context.getGraphic();

        // do the action
        // Use IlvSimplePopupMenu.getMenuItemText(m) to get the original
        // menu item text that is not affected by base text direction Bidi
        // control characters. Only needed if base text direction is not
        // UNDEFINED_DIRECTION
        if (IlvSimplePopupMenu.getMenuItemText(m).equals("Make larger"))
          makeLarger(graphic);
        else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Make smaller"))
          makeSmaller(graphic);
        else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Green"))
          setColor(graphic, GREEN);
        else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Red"))
          setColor(graphic, RED);
        else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Blue"))
          setColor(graphic, BLUE);
      }
    };

    // create a simple pop-up menu with the following items
    // - Make larger: makes the graphic larger
    // - Make smaller: makes the graphic smaller
    // - a separator line
    // - Green: colors the graphic green
    // - Red: colors the graphic red
    // - Blue: colors the graphic blue
    // The Green, Red, Blue act as radio buttons, i.e., only one is selected
    // at any time
    IlvSimplePopupMenu menu = new IlvSimplePopupMenu("Menu2",
        "Make larger | Make smaller | - | { Green | Red | Blue }", null, actionListener) {

      // configure checkbox of the pop-up before it gets displayed
      Override
      protected void beforeDisplay(IlvPopupMenuContext context) {
        // always call super.beforeDisplay first
        super.beforeDisplay(context);
        // retrieve the graphic
        IlvGraphic graphic = context.getGraphic();
        // select the graphic
        IlvManager manager = (IlvManager) graphic.getGraphicBag();
        manager.deSelectAll(true);
        manager.setSelected(graphic, true, true);

        // update the radio menu items according to the graphic's color
        if (graphic instanceof IlvZoomableLabel) {
          IlvZoomableLabel label = (IlvZoomableLabel) graphic;
          if (label.getBackgroundPaint().equals(GREEN))
            getItemForText("Green").setSelected(true);
          else if (label.getBackgroundPaint().equals(RED))
            getItemForText("Red").setSelected(true);
          else if (label.getBackgroundPaint().equals(BLUE))
            getItemForText("Blue").setSelected(true);
        }
      }
    };

    return menu;
  }

  /**
   * Creates a fancy pop-up menu.
   * In principle, you can use any JPopupMenu at the graphic object.
   * However, the IlvSimplePopupMenu is very conveniant to configure, hence
   * we use it in this sample.
   */
  private JPopupMenu createFancyMenu() {
    // create the action listener for the pop-up menu
    ActionListener actionListener = new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {

        // retrieve the selected menu item
        JMenuItem m = (JMenuItem) e.getSource();

        // retrieve the graphic that has this pop-up menu
        IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
        IlvGraphic graphic = context.getGraphic();

        // do the action
        if (e.getActionCommand().equals("LARGER"))
          makeLarger(graphic);
        else if (e.getActionCommand().equals("SMALLER"))
          makeSmaller(graphic);
        else if (e.getActionCommand().equals("GREEN"))
          setColor(graphic, GREEN);
        else if (e.getActionCommand().equals("RED"))
          setColor(graphic, RED);
        else if (e.getActionCommand().equals("BLUE"))
          setColor(graphic, BLUE);
        else if (e.getActionCommand().equals("CHECK"))
          setBorder(graphic, m.isSelected());
      }
    };

    // create a fancy pop-up menu with the following items
    // - Green: colors the graphic green
    // with tooltip "Set green"
    // with mnemonic "G"
    // with icon data/tgreen.gif
    // as radio button menu item in the group "Colors"
    // - Red: colors the graphic red
    // with tooltip "Set red"
    // with mnemonic "R"
    // with icon data/tred.gif
    // as radio button menu item in the group "Colors"
    // - Blue: colors the graphic blue
    // with tooltip "Set blue"
    // with mnemonic "B"
    // with icon data/tblue.gif
    // as radio button menu item in the group "Colors"
    // - Emphasized: sets the border thick or thin
    // as checkbox menu item
    // with mnemonic "E"
    // - Make larger: makes the graphic larger
    // with tooltop "Make graphic larger"
    // with mnemonic "L"
    // - Make smaller: makes the graphic smaller
    // with tooltop "Make graphic smaller"
    // with mnemonic "S"
    IlvSimplePopupMenu menu = new IlvSimplePopupMenu("Menu3",
        "Green A=GREEN M=G G=Colors T=Set green I=data/tgreen.gif |"
            + "Red A=RED M=R G=Colors T=Set red I=data/tred.gif |"
            + "Blue A=BLUE M=B G=Colors T=Set blue I=data/tblue.gif |" + " - |"
            + "Emphasized A=CHECK M=E C=false |" + " - |"
            + "Make Larger A=LARGER M=L T=Make graphic larger|"
            + "Make Smaller A=SMALLER M=S T=Make graphic smaller",
        null, actionListener) {

      // configure checkbox of the pop-up before it gets displayed
      Override
      protected void beforeDisplay(IlvPopupMenuContext context) {
        // always call super.beforeDisplay first
        super.beforeDisplay(context);
        // retrieve the graphic
        IlvGraphic graphic = context.getGraphic();
        // select the graphic
        IlvManager manager = (IlvManager) graphic.getGraphicBag();
        manager.deSelectAll(true);
        manager.setSelected(graphic, true, true);

        if (graphic instanceof IlvZoomableLabel) {
          // update the radio menu items according to the graphic's color
          IlvZoomableLabel label = (IlvZoomableLabel) graphic;
          if (label.getBackgroundPaint().equals(GREEN))
            getItemForActionCommand("GREEN").setSelected(true);
          else if (label.getBackgroundPaint().equals(RED))
            getItemForActionCommand("RED").setSelected(true);
          else if (label.getBackgroundPaint().equals(BLUE))
            getItemForActionCommand("BLUE").setSelected(true);

          // update the checkbox
          Stroke str = label.getStroke();
          float lineWidth = 1;
          if (str != null && str instanceof BasicStroke)
            lineWidth = ((BasicStroke) str).getLineWidth();
          if (lineWidth <= 1)
            getItemForActionCommand("CHECK").setSelected(false);
          else
            getItemForActionCommand("CHECK").setSelected(true);
        }
      }
    };

    return menu;
  }

  /**
   * Creates a pop-up menu with i18n.
   * In principle, you can use any JPopupMenu at the graphic object.
   * However, the IlvSimplePopupMenu is very conveniant to configure, hence
   * we use it in this sample.
   */
  private JPopupMenu createI18NMenu() {
    // create the action listener for the pop-up menu
    ActionListener actionListener = new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {

        // retrieve the selected menu item
        JMenuItem m = (JMenuItem) e.getSource();

        // retrieve the graphic that has this pop-up menu
        IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
        IlvGraphic graphic = context.getGraphic();

        // do the action
        if (e.getActionCommand().equals("GREEN"))
          setColor(graphic, GREEN);
        else if (e.getActionCommand().equals("RED"))
          setColor(graphic, RED);
        else if (e.getActionCommand().equals("BLUE"))
          setColor(graphic, BLUE);
        else if (e.getActionCommand().equals("CHECK"))
          setBorder(graphic, m.isSelected());
      }
    };

    // allocate a resource bundle that contains the strings for the keys
    // EItem, GItem, RItem, BItem etc.
    ResourceBundle bundle = IlvResourceUtil.getBundle("messages", IlvLocaleUtil.getCurrentLocale(),
        getClass().getClassLoader());

    // create a fancy pop-up menu with the following items
    // - Emphasized: sets the border thick or thin
    // as checkbox menu item
    // with tooltip read from the resource bundle
    // with mnemonic read from the resource bundle
    // - Green: colors the graphic green
    // with tooltip read from the resource bundle
    // with mnemonic read from the resource bundle
    // with icon data/tgreen.gif
    // as radio button menu item in the group "Colors"
    // - Red: colors the graphic red
    // with tooltip read from the resource bundle
    // with mnemonic read from the resource bundle
    // with icon data/tred.gif
    // as radio button menu item in the group "Colors"
    // - Blue: colors the graphic blue
    // with tooltip read from the resource bundle
    // with mnemonic read from the resource bundle
    // with icon data/tblue.gif
    // as radio button menu item in the group "Colors"
    IlvSimplePopupMenu menu = new IlvSimplePopupMenu("Menu4",
        "EItem A=CHECK M=EItem.Mnemonic T=ETooltip C=false |" + " - |"
            + "GItem A=GREEN M=GItem.Mnemonic G=Colors T=GTooltip I=data/tgreen.gif |"
            + "RItem A=RED M=RItem.Mnemonic G=Colors T=RTooltip I=data/tred.gif |"
            + "BItem A=BLUE M=BItem.Mnemonic G=Colors T=BTooltip I=data/tblue.gif",
        bundle, actionListener) {

      // configure checkbox of the pop-up before it gets displayed
      Override
      protected void beforeDisplay(IlvPopupMenuContext context) {
        // always call super.beforeDisplay first
        super.beforeDisplay(context);
        // retrieve the graphic
        IlvGraphic graphic = context.getGraphic();
        // select the graphic
        IlvManager manager = (IlvManager) graphic.getGraphicBag();
        manager.deSelectAll(true);
        manager.setSelected(graphic, true, true);

        if (graphic instanceof IlvZoomableLabel) {
          // update the radio menu items according to the graphic's color
          IlvZoomableLabel label = (IlvZoomableLabel) graphic;
          if (label.getBackgroundPaint().equals(GREEN))
            getItemForActionCommand("GREEN").setSelected(true);
          else if (label.getBackgroundPaint().equals(RED))
            getItemForActionCommand("RED").setSelected(true);
          else if (label.getBackgroundPaint().equals(BLUE))
            getItemForActionCommand("BLUE").setSelected(true);

          // update the checkbox
          Stroke str = label.getStroke();
          float lineWidth = 1;
          if (str != null && str instanceof BasicStroke)
            lineWidth = ((BasicStroke) str).getLineWidth();
          if (lineWidth <= 1)
            getItemForActionCommand("CHECK").setSelected(false);
          else
            getItemForActionCommand("CHECK").setSelected(true);
        }
      }
    };

    return menu;
  }

  /**
   * Creates a very simple pop-up menu for the main manager.
   * In principle, you can use any JPopupMenu at the graphic object.
   * However, the IlvSimplePopupMenu is very conveniant to configure, hence
   * we use it in this sample.
   */
  private JPopupMenu createManagerMenu() {
    // create the action listener for the pop-up menu
    ActionListener actionListener = new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {

        // retrieve the selected menu item
        JMenuItem m = (JMenuItem) e.getSource();

        // retrieve the graphic that has this pop-up menu
        IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
        IlvGraphic graphic = context.getGraphic();
        IlvManagerView mgrview = context.getManagerView();

        if (mgrview.getManager() == graphic) {
          // It is the pop-up of the top level manager. Do the action.
          // Use IlvSimplePopupMenu.getMenuItemText(m) to get the original
          // menu item text that is not affected by base text direction Bidi
          // control characters. Only needed if base text direction is not
          // UNDEFINED_DIRECTION
          if (IlvSimplePopupMenu.getMenuItemText(m).equals("Zoom")) {
            Dimension size = mgrview.getSize();
            IlvPoint p = new IlvPoint(size.width / 2, size.height / 2);
            mgrview.zoom(p, 1.5, 1.5, true);
          } else if (IlvSimplePopupMenu.getMenuItemText(m).equals("Unzoom")) {
            Dimension size = mgrview.getSize();
            IlvPoint p = new IlvPoint(size.width / 2, size.height / 2);
            mgrview.zoom(p, 1.0 / 1.5, 1.0 / 1.5, true);
          }
        }
        // else ... could define here what zoom/unzoom means if it is not
        // the top level manager. But this does not happen in this simple
        // demo.
      }
    };

    // create a simple pop-up menu with the following items
    // - Zoom: zooms the view
    // - Unzoom: unzooms the view
    IlvSimplePopupMenu menu =
        new IlvSimplePopupMenu("Grapher Menu", "Zoom | Unzoom", null, actionListener);

    return menu;
  }

  /**
   * Makes a graphic larger.
   */
  private void makeLarger(IlvGraphic g) {
    IlvRect bbox = g.boundingBox();
    bbox.width *= 1.2;
    bbox.height *= 1.2;
    IlvManager manager = (IlvManager) g.getGraphicBag();
    manager.reshapeObject(g, bbox, true);
  }

  /**
   * Makes a graphic smaller.
   */
  private void makeSmaller(IlvGraphic g) {
    IlvRect bbox = g.boundingBox();
    bbox.width /= 1.2;
    bbox.height /= 1.2;
    IlvManager manager = (IlvManager) g.getGraphicBag();
    manager.reshapeObject(g, bbox, true);
  }

  /**
   * Sets the background color of the graphic.
   */
  private void setColor(IlvGraphic g, final Color c) {
    g.getGraphicBag().applyToObject(g, new IlvApplyObject() {
      Override
      public void apply(IlvGraphic g, Object arg) {
        IlvZoomableLabel label = (IlvZoomableLabel) g;
        label.setBackgroundPaint(c);
      }
    }, null, true);
  }

  /**
   * Sets the border of the graphic large or small.
   */
  private void setBorder(IlvGraphic g, final boolean largeBorder) {
    g.getGraphicBag().applyToObject(g, new IlvApplyObject() {
      Override
      public void apply(IlvGraphic g, Object arg) {
        IlvZoomableLabel label = (IlvZoomableLabel) g;
        if (largeBorder)
          label.setStroke(new BasicStroke(4));
        else
          label.setStroke(new BasicStroke(1));
      }
    }, null, true);
  }

  /**
   * Allows you to run the demo as a standalone application.
   */
  public static void main(String[] arg) {
    // Sun recommends that to put the entire GUI initialization into the
    // AWT thread
    SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        PopupMenuApp app = new PopupMenuApp();
        app.init();

        JFrame frame = new JFrame("Pop-up Menu Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.getContentPane().add(app);
        frame.setVisible(true);
      }
    });
  }
}