InternalManagedDialog.java :  » Game » Arianne-RPG-0.83 » games » stendhal » client » gui » wt » Java Open Source

Java Open Source » Game » Arianne RPG 0.83 
Arianne RPG 0.83 » games » stendhal » client » gui » wt » InternalManagedDialog.java
/*
 * @(#) src/games/stendhal/client/gui/wt/InternalManagedDialog.java
 *
 * $Id: InternalManagedDialog.java,v 1.22 2009/05/10 22:25:23 astridemma Exp $
 */

package games.stendhal.client.gui.wt;

//
//

import games.stendhal.client.gui.ManagedWindow;
import games.stendhal.client.gui.styled.Style;
import games.stendhal.client.gui.styled.WoodStyle;
import games.stendhal.client.gui.styled.swing.StyledJPanel;
import games.stendhal.client.gui.wt.core.WtCloseListener;
import games.stendhal.client.gui.wt.core.WtWindowManager;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

/**
 * A base internal dialog in swing that implements ManagedWindow.
 * 
 */
public class InternalManagedDialog implements ManagedWindow {
  /** size of the titlebar. */
  private static final int TITLEBAR_HEIGHT = 13;

  /**
   * The close button.
   */
  private JButton closeButton;

  /**
   * The window content.
   */
  private JComponent content;

  /**
   * Listeners interesting in close notifications.
   */
  private List<WtCloseListener> closeListeners;

  /**
   * The simulated dialog.
   */
  private Panel dialog;

  /**
   * Start of a window drag.
   */
  private Point dragStart;

  /**
   * The content pane.
   */
  private StyledJPanel contentPane;

  /**
   * Whether the dialog is minimized.
   */
  private boolean minimized;

  /**
   * The minimize button.
   */
  private JButton minimizeButton;

  /**
   * If the window can be moved.
   */
  private boolean movable;

  /**
   * The window name.
   */
  private String name;

  private ContentSizeChangeCB sizeChangeListener;

  /**
   * The titlebar.
   */
  private JComponent titlebar;

  /**
   * The title label.
   */
  private JLabel titleLabel;

  /**
   * Create a managed dialog window.
   * 
   * @param name
   *            The logical name.
   * @param title
   *            The dialog window title.
   */
  public InternalManagedDialog(final String name, final String title) {
    Style style;
    Font font;
    Color color;

    this.name = name;

    style = WoodStyle.getInstance();

    minimized = false;
    movable = true;
    closeListeners = new LinkedList<WtCloseListener>();

    /*
     * Heavy weight to work with AWT canvas
     */
    dialog = new Panel();
    dialog.setLayout(null);

    contentPane = new StyledJPanel(style);
    contentPane.setLayout(null);

    dialog.add(contentPane);

    /*
     * Titlebar
     */
    titlebar = new StyledJPanel(style);
    titlebar.setMinimumSize(new Dimension(1, TITLEBAR_HEIGHT));
    titlebar.setLayout(new BoxLayout(titlebar, BoxLayout.X_AXIS));
    titlebar.addMouseListener(new TBDragClickCB());
    titlebar.addMouseMotionListener(new TBDragMoveCB());

    contentPane.add(titlebar);

    /*
     * Title
     */
    titleLabel = new JLabel(title, SwingConstants.LEFT);
    titleLabel.setOpaque(false);
    titleLabel.setBorder(BorderFactory.createEmptyBorder());
    font = style.getFont();
    if (font == null) {
      font = titleLabel.getFont();
    }

    titleLabel.setFont(font.deriveFont(Font.BOLD));
    color = style.getForeground();
    if (color != null) {
      titleLabel.setForeground(color);
    }

    titlebar.add(titleLabel);

    /*
     * Spacing
     */
    titlebar.add(Box.createHorizontalGlue());

    /*
     * Minimize button
     */
    minimizeButton = new JButton(new MinimizeIcon());
    minimizeButton.setDisabledIcon(new DisabledIcon());
    minimizeButton.setFocusable(false);
    minimizeButton.setMargin(new Insets(0, 0, 0, 0));
    minimizeButton.setBorder(BorderFactory.createEmptyBorder());
    minimizeButton.setContentAreaFilled(false);
    minimizeButton.addActionListener(new MinimizeCB());
    titlebar.add(minimizeButton);

    /*
     * Spacer
     */
    titlebar.add(Box.createHorizontalStrut(1));

    /*
     * Close button
     */
    closeButton = new JButton(new CloseIcon());
    closeButton.setDisabledIcon(new DisabledIcon());
    closeButton.setFocusable(false);
    closeButton.setMargin(new Insets(0, 0, 0, 0));
    closeButton.setBorder(BorderFactory.createEmptyBorder());
    closeButton.setContentAreaFilled(false);
    closeButton.addActionListener(new CloseCB());
    titlebar.add(closeButton);

    sizeChangeListener = new ContentSizeChangeCB();

    pack();
    WtWindowManager.getInstance().formatWindow(this);
  }

  //
  // InternalManagedDialog
  //

  /**
   * Close window.
   */
  private void closeCB() {
    setVisible(false);
  }

  /**
   * Toggle minimization.
   */
  private void minimizeCB() {
    setMinimized(!isMinimized());
  }

  /**
   * Do simulated dialog layout.
   */
  private void pack() {
    Dimension tbSize;
    Dimension cSize;
    int width;

    tbSize = titlebar.getPreferredSize();

    if (content != null) {
      cSize = content.getPreferredSize();
    } else {
      cSize = new Dimension(0, 0);
    }

    width = Math.max(tbSize.width, cSize.width);

    titlebar.setBounds(0, 0, width, tbSize.height);
    titlebar.validate();

    if (content != null) {
      content.setBounds(0, tbSize.height, width, cSize.height);

      content.validate();
    }

    if (isMinimized()) {
      dialog.setBounds(0, 0, width, tbSize.height);
      contentPane.setBounds(0, 0, width, tbSize.height);
    } else {
      dialog.setSize(width, tbSize.height + cSize.height);

      contentPane.setSize(width, tbSize.height + cSize.height);
    }
  }

  //
  // ManagedDialog
  //

  /**
   * Handle titlebar clicks.
   * 
   * @param count
   *            The click count.
   */
  private void tbClicked(final int count) {
    if (count == 1) {
      /*
       * Raise the window if possible.
       */
      final Container parent = dialog.getParent();

      if (parent instanceof JLayeredPane) {
        ((JLayeredPane) parent).moveToFront(dialog);
      }
    } else if (count == 2) {
      /*
       * Toggle minimization
       */
      if (isMinimizable()) {
        setMinimized(!isMinimized());
      }
    }
  }

  /**
   * Handle begining of titlebar drag.
   * 
   * @param x
   *            The X coordinate.
   * @param y
   *            The Y coordinate.
   */
  private void tbDragBegin(final int x, final int y) {
    if (isMovable()) {
      dragStart = SwingUtilities.convertPoint(titlebar, x, y, dialog);
    }
  }

  /**
   * Handle end of titlebar drag.
   * 
   * @param x
   *            The X coordinate.
   * @param y
   *            The Y coordinate.
   */
  private void tbDragEnd(final int x, final int y) {
    tbDragMovement(x, y);
    dragStart = null;
    windowMoved();
  }

  /**
   * Handle titlebar drag movement.
   * 
   * @param x
   *            The X coordinate.
   * @param y
   *            The Y coordinate.
   */
  private void tbDragMovement(final int x, final int y) {
    Point p;
    Container parent;

    if (dragStart != null) {
      parent = dialog.getParent();

      p = SwingUtilities.convertPoint(titlebar, x, y, parent);
      p.x -= dragStart.x;
      p.y -= dragStart.y;

      /*
       * Keep in parent window
       */
      if (p.x < 0) {
        p.x = 0;
      } else if ((p.x + dialog.getWidth()) > parent.getWidth()) {
        p.x = parent.getWidth() - dialog.getWidth();
      }

      if (p.y < 0) {
        p.y = 0;
      } else if ((p.y + dialog.getHeight()) > parent.getHeight()) {
        p.y = parent.getHeight() - dialog.getHeight();
      }

      dialog.setLocation(p);
    }
  }

  /**
   * Get the actual dialog.
   * 
   * @return The dialog.
   */
  public Container getDialog() {
    return dialog;
  }

  /**
   * Call all registered close listeners.
   */
  private void fireCloseListeners() {
    WtCloseListener[] listeners;

    listeners = closeListeners.toArray(new WtCloseListener[closeListeners.size()]);

    for (final WtCloseListener l : listeners) {
      l.onClose(getName());
    }
  }

  /**
   * Set the content component. For now, if the content wishes to resize the
   * dialog, it should set a client property named <code>size-change</code>
   * on itself.
   * 
   * @param content
   *            A component to implement the content.
   */
  public void setContent(final JComponent content) {
    if (this.content != null) {
      this.content.removePropertyChangeListener(sizeChangeListener);

      contentPane.remove(this.content);
    }

    this.content = content;

    contentPane.add(content);

    content.addPropertyChangeListener("size-change", sizeChangeListener);

    pack();
  }

  /**
   * Called when the window's position changes.
   */
  private void windowMoved() {
    /*
     * Update saved state
     */
    WtWindowManager.getInstance().moveTo(this, getX(), getY());
  }

  //
  // ManagedWindow
  //

  /**
   * Get the managed window name.
   * 
   * @return The logical window name (not title).
   */
  public String getName() {
    return name;
  }

  /**
   * Get X coordinate of the window.
   * 
   * @return A value suitable for passing to <code>moveTo()</code>.
   */
  public int getX() {
    return dialog.getX();
  }

  /**
   * Get Y coordinate of the window.
   * 
   * @return A value suitable for passing to <code>moveTo()</code>.
   */
  public int getY() {
    return dialog.getY();
  }

  /**
   * Determine if the window is minimizable.
   * 
   * @return <code>true</code> if minimizable.
   */
  public boolean isMinimizable() {
    return minimizeButton.isEnabled();
  }

  /**
   * Determine if the window is minimized.
   * 
   * @return <code>true</code> if the window is minimized.
   */
  public boolean isMinimized() {
    return minimized;
  }

  /**
   * Determine if the window is movable.
   * 
   * @return <code>true</code> if the window is movable.
   */
  public boolean isMovable() {
    return movable;
  }

  /**
   * Determine if the window is visible.
   * 
   * @return <code>true</code> if the window is visible.
   */
  public boolean isVisible() {
    return dialog.isVisible();
  }

  /**
   * Move to a location. This may be subject to internal representation, and
   * should only use what was passed from <code>getX()</code> and
   * <code>getY()</code>.
   * 
   * @param x
   *            The X coordinate
   * @param y
   *            The Y coordinate
   * 
   * @return <code>true</code> if the move was allowed.
   */
  public boolean moveTo(final int x, final int y) {
    dialog.setLocation(x, y);
    return true;
  }

  /**
   * Register a close listener.
   * 
   * @param listener
   *            A close listener.
   */
  public void registerCloseListener(final WtCloseListener listener) {
    closeListeners.add(listener);
  }

  /**
   * Unregister a close listener.
   * 
   * @param listener
   *            A close listener.
   */
  public void removeCloseListener(final WtCloseListener listener) {
    closeListeners.remove(listener);
  }

  /**
   * Set whether the window is minimizable.
   * 
   * @param minimizable
   *            <code>true</code> if minimizable.
   */
  public void setMinimizable(final boolean minimizable) {
    minimizeButton.setEnabled(minimizable);
  }

  /**
   * Set the window as minimized.
   * 
   * @param minimized
   *            Whether the window should be minimized.
   */
  public void setMinimized(final boolean minimized) {
    int cheight;

    this.minimized = minimized;

    if (minimized) {
      if (content != null) {
        content.setVisible(false);
      }

      dialog.setSize(titlebar.getWidth(), titlebar.getHeight());

      contentPane.setSize(titlebar.getWidth(), titlebar.getHeight());
    } else {
      if (content != null) {
        content.setVisible(true);
        cheight = content.getHeight();
      } else {
        cheight = 0;
      }

      dialog.setSize(titlebar.getWidth(), titlebar.getHeight() + cheight);

      contentPane.setSize(titlebar.getWidth(), titlebar.getHeight()
          + cheight);
    }
  }

  /**
   * Set whether the window is movable.
   * 
   * @param movable
   *            <code>true</code> if movable.
   */
  public void setMovable(final boolean movable) {
    this.movable = movable;
  }

  /**
   * Set the window as visible (or hidden).
   * 
   * @param visible
   *            Whether the window should be visible.
   */
  public void setVisible(final boolean visible) {
    dialog.setVisible(visible);

    /*
     * Update saved state
     */
    WtWindowManager.getInstance().setVisible(this, visible);

    /*
     * Notify close listeners
     */
    if (!visible) {
      fireCloseListeners();
    }
  }

  //
  //

  /**
   * Handle content resize required property change.
   */
  private class ContentSizeChangeCB implements PropertyChangeListener {

    //
    // PropertyChangeListener
    //

    public void propertyChange(final PropertyChangeEvent ev) {
      pack();
    }
  }

  /**
   * Handle close button.
   */
  private class CloseCB implements ActionListener {
    public void actionPerformed(final ActionEvent ev) {
      closeCB();
    }
  }

  /**
   * Handle minimzation button.
   */
  private class MinimizeCB implements ActionListener {
    public void actionPerformed(final ActionEvent ev) {
      minimizeCB();
    }
  }

  /**
   * Disabled button icon.
   */
  private static class DisabledIcon implements Icon {
    //
    // Icon
    //

    public int getIconHeight() {
      return TITLEBAR_HEIGHT;
    }

    public int getIconWidth() {
      return TITLEBAR_HEIGHT;
    }

    public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
      // do nothing
    }
  }

  /**
   * Close button icon.
   */
  private static class CloseIcon implements Icon {
    //
    // Icon
    //

    public int getIconHeight() {
      return TITLEBAR_HEIGHT;
    }

    public int getIconWidth() {
      return TITLEBAR_HEIGHT;
    }

    public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
      Color oldColor;
      int height;
      int width;

      oldColor = g.getColor();

      height = getIconHeight();
      width = getIconWidth();

      g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.5f));
      g.fillRect(x, y, width, height);

      g.setColor(Color.BLACK);

      /*
       * \\ \\\ \\
       */
      g.drawLine(x + 1, y + 2, x + width - 3, y + height - 2);

      g.drawLine(x + 1, y + 1, x + width - 2, y + height - 2);

      g.drawLine(x + 2, y + 1, x + width - 2, y + height - 3);

      /*
       * // /// //
       */
      g.drawLine(x + width - 3, y + 1, x + 1, y + height - 3);

      g.drawLine(x + width - 2, y + 1, x + 1, y + height - 2);

      g.drawLine(x + width - 2, y + 2, x + 2, y + height - 2);

      g.setColor(oldColor);
    }
  }

  /**
   * Minmization button icon.
   */
  private static class MinimizeIcon implements Icon {
    //
    // Icon
    //

    public int getIconHeight() {
      return TITLEBAR_HEIGHT;
    }

    public int getIconWidth() {
      return TITLEBAR_HEIGHT;
    }

    public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
      Color oldColor;
      int height;
      int width;

      oldColor = g.getColor();

      height = getIconHeight();
      width = getIconWidth();

      g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.5f));
      g.fillRect(x, y, width, height);

      g.setColor(Color.BLACK);
      g.fillRect(x + 1, y + height - 3, width - 2, 2);

      g.setColor(oldColor);
    }
  }

  /**
   * Mouse drag event handler for the titlebar.
   */
  private class TBDragMoveCB extends MouseMotionAdapter {
    /**
     * Handle mouse drag event.
     * 
     * @param ev
     *            The mouse event.
     */
    @Override
    public void mouseDragged(final MouseEvent ev) {
      tbDragMovement(ev.getX(), ev.getY());
    }
  }

  /**
   * Mouse click event handler for the titlebar.
   */
  private class TBDragClickCB extends MouseAdapter {
    /**
     * Handle mouse pressed event.
     * 
     * @param ev
     *            The mouse event.
     */
    @Override
    public void mousePressed(final MouseEvent ev) {
      if (ev.getButton() == MouseEvent.BUTTON1) {
        tbDragBegin(ev.getX(), ev.getY());
      }
    }

    /**
     * Handle mouse released event.
     * 
     * @param ev
     *            The mouse event.
     */
    @Override
    public void mouseReleased(final MouseEvent ev) {
      if (ev.getButton() == MouseEvent.BUTTON1) {
        tbDragEnd(ev.getX(), ev.getY());
      }
    }

    /**
     * Handle mouse click event.
     * 
     * @param ev
     *            The mouse event.
     */
    @Override
    public void mouseClicked(final MouseEvent ev) {
      if (ev.getButton() == MouseEvent.BUTTON1) {
        tbClicked(ev.getClickCount());
      }
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.