Package net.sf.latexdraw.ui

Source Code of net.sf.latexdraw.ui.WidgetMiniToolbar$WindowWidgets

package net.sf.latexdraw.ui;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.IllegalComponentStateException;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.image.BufferedImage;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import net.sf.latexdraw.badaboom.BadaboomCollector;

import org.malai.interaction.Eventable;
import org.malai.picking.Pickable;
import org.malai.picking.Picker;
import org.malai.swing.interaction.SwingEventManager;
import org.malai.swing.widget.MToolBar;
import org.malai.swing.widget.SwingWidgetUtilities;

/**
* This class defines a button which displays a frame containing
* others buttons; a kind of menu with buttons.<br>
*<br>
* This file is part of LaTeXDraw<br>
* Copyright (c) 2005-2014 Arnaud BLOUIN<br>
*<br>
*  LaTeXDraw is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  any later version.<br>
*<br>
*  LaTeXDraw is distributed without any warranty; without even the
*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
*  PURPOSE. See the GNU General Public License for more details.<br>
*<br>
* 05/02/06<br>
* @author Arnaud BLOUIN
* @version 3.0
*/
public class WidgetMiniToolbar extends JButton implements ActionListener, WindowFocusListener, Picker, Eventable {
  private static final long serialVersionUID = 1L;

  /** The event manager that listens events produced by the list of toogle buttons. May be null. */
  protected SwingEventManager eventManager;

  /** The frame which displays the toolbar */
  protected WindowWidgets buttonsFrame;

  /** The toolbar which contains the buttons */
  protected MToolBar toolbar;

  /** The width of the triangle drawn in the button */
  public static final int WIDTH_TRIANGLE = 8;

  /** The height of the triangle drawn in the button */
  public static final int HEIGHT_TRIANGLE = 6;

  /** Define the location of the panel of buttons. */
  protected int location;

  /** The component to give the focus when the toolbar is closed. */
  protected Component componentFocusOnClose;

  /** The frame is at the north of the button. */
  public static final int LOCATION_NORTH = 1;

  /** The frame is at the south of the button. */
  public static final int LOCATION_SOUTH = 2;

  private static final int WIDTH_ICON = 10;

  private static final int HEIGHT_ICON = 20;

  private static final int TRIANGLE_NB_POINT = 3;

  private static final int TRIANGLE_GAP = 4;



  /**
   * The constructor using a text.
   * @param txt The text of the ListJToggleButton.
   * @param locate The position of the mini toolbar.
   * @param componentFocusOnClose The component to give the focus when the toolbar is closed. Can be null.
   * @since 3.0
   */
  public WidgetMiniToolbar(final String txt, final int locate, final Component componentFocusOnClose) {
    super(txt);

    setIcon();
    intializing(locate);
    this.componentFocusOnClose = componentFocusOnClose;
  }



  /**
   * The constructor using an icon.
   * @param icon The icon of the ListJToggleButton.
   * @param locate The position of the mini toolbar.
   * @param componentFocusOnClose The component to give the focus when the toolbar is closed. Can be null.
   */
  public WidgetMiniToolbar(final Icon icon, final int locate, final Component componentFocusOnClose) {
    super(icon);

    intializing(locate);
    this.componentFocusOnClose = componentFocusOnClose;
  }



  /**
   * Initialises the ListJToggleButton.
   * @param locate The position of the mini toolbar.
   * @since 1.9.1
   */
  protected void intializing(final int locate) {
    try{ setLocation(locate); }
    catch(final IllegalArgumentException e) {location = LOCATION_SOUTH;}

    toolbar = new MToolBar(true);
    toolbar.setFloatable(false);

    final JPanel buttonsPanel = new JPanel();
    buttonsPanel.add(toolbar);
    buttonsPanel.setBorder(BorderFactory.createEtchedBorder());

    buttonsFrame = new WindowWidgets(buttonsPanel);

    addActionListener(this);
    setMargin(new Insets(1,1,1,1));
    addComponent(new CloseButton());

    // The mini-toolbar must disappear when a click or a press occurs somewhere else.
    Toolkit.getDefaultToolkit().addAWTEventListener( new ListToggleButtonAWTEventListener(), AWTEvent.MOUSE_EVENT_MASK);
  }


  /**
   * @return True if at least one of the widgets of the list is visible.
   * @since 3.0
   */
  public boolean isContentVisible() {
    return isContentVisibleContainer(toolbar);
  }


  private static boolean isContentVisibleContainer(final Container cont) {
    boolean visible = false;
    Component comp;

    for(int i=0, size=cont.getComponentCount(); i<size && !visible; i++) {
      comp = cont.getComponent(i);

      if(!(comp instanceof JToolBar.Separator) && !(comp instanceof CloseButton) && !(comp instanceof Box.Filler) && !(comp instanceof JLabel))
        visible = comp.isVisible() && (!(comp instanceof JPanel) || isContentVisibleContainer((JPanel)comp));
    }

    return visible;
  }


  /**
   * @return Creates an imageIcon containing the triangle icon.
   * @since 1.9.1
   */
  protected ImageIcon createTriangleIcon() {
    final BufferedImage bufferImage = new BufferedImage(WIDTH_ICON, HEIGHT_ICON, BufferedImage.TYPE_INT_ARGB);
    paintTriangle(bufferImage.createGraphics(), WIDTH_ICON, HEIGHT_ICON);

    return new ImageIcon(bufferImage);
  }



  /**
   * Sets the location of the mini toolbar.
   * @param locat The position of the mini toolbar.
   * @throws IllegalArgumentException If the location is neither <code>LOCATION_NORTH</code> nor <code>LOCATION_SOUTH</code>.
   */
  public void setLocation(final int locat) {
    if(locat==LOCATION_NORTH || locat==LOCATION_SOUTH)
      location = locat;
    else
      throw new IllegalArgumentException();
  }


  /**
   * Adds a separator to the toolbar.
   */
  public void addSeparator() {
    final Component c = toolbar.getComponentAtIndex(toolbar.getComponentCount()-1);
    toolbar.remove(c);
    toolbar.addSeparator();
    toolbar.add(c);
    buttonsFrame.pack();
  }



  /**
   * Adds a button to the toolbar of the listJToggleButton.
   * @param comp The new button to add.
   */
  public void addComponent(final Component comp) {
    toolbar.add(comp, null, toolbar.getComponentCount()-1);
    buttonsFrame.pack();

    if(comp instanceof AbstractButton) {
      final AbstractButton ab = (AbstractButton) comp;
      ab.addActionListener(this);
    }

    attachAddedComponent(comp);
  }


  @Override
  public Component add(final Component comp) {
    addComponent(comp);
    return comp;
  }


  /**
   * Paints the triangle icon in a graphic.
   * @param g The graphic.
   * @param width The width of the object.
   * @param height The height of the object.
   * @since 1.9.1
   */
  public void paintTriangle(final Graphics g, final int width, final int height) {
    if(g==null || width<1 || height<1)
      return ;

    if(g instanceof Graphics2D) {
      final Graphics2D g2 = (Graphics2D) g;

      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
      g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    }

    final int xs[] = new int[TRIANGLE_NB_POINT];
    final int ys[] = new int[TRIANGLE_NB_POINT];

    if(location==LOCATION_SOUTH) {
      xs[0] = width-WIDTH_TRIANGLE>>1;
      xs[1] = width+WIDTH_TRIANGLE>>1;
      xs[2] = width>>1;

      ys[0] = height-HEIGHT_TRIANGLE-TRIANGLE_GAP;
      ys[1] = height-HEIGHT_TRIANGLE-TRIANGLE_GAP;
      ys[2] = height-TRIANGLE_GAP;
    }
    else {
      xs[0] = width-WIDTH_TRIANGLE>>1;
      xs[1] = width+WIDTH_TRIANGLE>>1;
      xs[2] = width>>1;

      ys[0] = HEIGHT_TRIANGLE+TRIANGLE_GAP;
      ys[1] = HEIGHT_TRIANGLE+TRIANGLE_GAP;
      ys[2] = TRIANGLE_GAP;
    }

    g.setColor(Color.red);
    g.fillPolygon(xs, ys, TRIANGLE_NB_POINT);
    g.setColor(Color.black);
    g.drawPolygon(xs, ys, TRIANGLE_NB_POINT);
  }



  @Override
  protected void paintComponent(final Graphics g) {
    super.paintComponent(g);

    if(getText().isEmpty())
      paintTriangle(g, getSize().width, getSize().height);
  }



  /**
   * Defines the position of the mini-toolbar.
   * @since 1.9.1
   */
  public void defineToolbarLocation() {
    buttonsFrame.setLocation(getLocationOnScreen().x, getLocationOnScreen().y +
                (location==LOCATION_SOUTH ? getHeight() : -buttonsFrame.getHeight()));
  }



  @Override
  public void actionPerformed(final ActionEvent e) {
    final Object src = e.getSource();

    if(src instanceof WidgetMiniToolbar) {
      final boolean visible = !buttonsFrame.isVisible();

      defineToolbarLocation();
      setButtonsFrameVisible(visible);
      return ;
    }

    if(src instanceof JCheckBox || src instanceof JRadioButton)
      return ;

    if(src instanceof CloseButton) {
      setButtonsFrameVisible(false);
      return;
    }

    if(src instanceof JToggleButton || src instanceof JButton) {
      setButtonsFrameVisible(false);
    }
  }


  /**
   * Sets id the toolbar must be visible or not.
   * @param visible True: the toolbar will be visible.
   * @since 3.0
   */
  public void setButtonsFrameVisible(final boolean visible) {
    if(visible)
      update();

    buttonsFrame.setVisible(visible);

    if(visible)
      buttonsFrame.requestFocusInWindow();

    if(!visible && componentFocusOnClose!=null)
      componentFocusOnClose.requestFocus();
  }



  /**
   * @return The location of the panel of buttons.
   */
  public int getLocationButtonPanel() {
    return location;
  }



  @Override
  public void windowGainedFocus(final WindowEvent e) {
//    toolbar.requestFocusInWindow();
  }



  @Override
  public void windowLostFocus(final WindowEvent e) {
    if(e.getOppositeWindow()==null)
      buttonsFrame.setVisible(false);
  }



  /**
   * The icon of the button will be the red triangle.
   * @since 1.9.1
   */
  public void setIcon() {
    super.setIcon(createTriangleIcon());
  }



  @Override
  public void setIcon(final Icon defaultIcon) {
        if(getText().isEmpty()) super.setIcon(defaultIcon);
        else setIcon();
  }


  @Override
  public boolean contains(final Object obj) {
    return SwingWidgetUtilities.INSTANCE.contains(toolbar.getComponents(), obj);
  }



  @Override
  public Pickable getPickableAt(final double x, final double y) {
    return SwingWidgetUtilities.INSTANCE.getPickableAt(this, toolbar.getComponents(), x, y);
  }



  @Override
  public Picker getPickerAt(final double x, final double y) {
    return SwingWidgetUtilities.INSTANCE.getPickerAt(this, toolbar.getComponents(), x, y);
  }


  /**
   * Attaches the given component to the event manager of the panel if it exists.
   * @param comp
   * @since 3.0
   */
  private void attachAddedComponent(final Component comp) {
    if(comp!=null && eventManager!=null)
      eventManager.attachTo(comp);
  }



  @Override
  public boolean hasEventManager() {
    return eventManager!=null;
  }


  @Override
  public SwingEventManager getEventManager() {
    return eventManager;
  }


  /**
   * @return The toolbar associated to the toggle button.
   * @since 3.0
   */
  public MToolBar getToolbar() {
    return toolbar;
  }


  public JFrame getWindowToolBar() {
    return buttonsFrame;
  }


  /**
   * Updates the shape of the widgets using its components.
   * @since 3.0
   */
  public void update() {
    if(buttonsFrame!=null)
      buttonsFrame.pack();
  }


  class ListToggleButtonAWTEventListener implements AWTEventListener {
    protected ListToggleButtonAWTEventListener() {
      super();
    }

    @Override
    public void eventDispatched(final AWTEvent event) {
        // Only if the toolbar is visible and the event is a mouse event.
        if(buttonsFrame.isVisible() && (event.getID()==MouseEvent.MOUSE_PRESSED || event.getID()==MouseEvent.MOUSE_CLICKED) &&
           event.getSource() instanceof Component && event instanceof MouseEvent) {
          final MouseEvent me   = (MouseEvent)event;
          final Component comp   = (Component)me.getSource();
          final Point pt       = new Point(me.getPoint());

          // Converting the mouse event point into a screen point.
          SwingUtilities.convertPointToScreen(pt, comp);

          // The toolbar is hidden if:
          // - the button of the toolbar does not contain the point of the event.
          // - the toolbar does not contain the point of the event.
          // - the widget concerned by the event is not a widget of the toolbar (necessary to manage widgets
          // which size is not contained into the toolbar such as ComboBoxes).
          try{
          if(buttonsFrame.isVisible() && !new Rectangle(buttonsFrame.getLocationOnScreen(), buttonsFrame.getSize()).contains(pt) &&
            WidgetMiniToolbar.this.isVisible() && !new Rectangle(WidgetMiniToolbar.this.getLocationOnScreen(), WidgetMiniToolbar.this.getSize()).contains(pt) &&
            SwingUtilities.getAncestorOfClass(WindowWidgets.class, comp)!=buttonsFrame) {
            WidgetMiniToolbar.this.buttonsFrame.setVisible(false);
          }
          }catch(final IllegalComponentStateException ex){ BadaboomCollector.INSTANCE.add(ex); }
        }
    }

  }


  private class WindowWidgets extends JFrame {
    private static final long serialVersionUID = 1L;

    protected WindowWidgets(final JPanel buttonsPanel) {
      super();
      setType(Window.Type.UTILITY);
      setFocusable(false);
      setUndecorated(true);
      setVisible(false);
      setAlwaysOnTop(true);
      add(buttonsPanel);
      pack();
    }
  }
}
TOP

Related Classes of net.sf.latexdraw.ui.WidgetMiniToolbar$WindowWidgets

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.