Package games.stendhal.client.gui

Source Code of games.stendhal.client.gui.DropAmountChooser

/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program 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     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.client.gui;

import games.stendhal.client.entity.StackableItem;
import games.stendhal.client.gui.layout.SBoxLayout;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;

import org.apache.log4j.Logger;

/**
* A class for showing a selector for dropped item amounts and taking control
* of the drop handling of those drops.
*/
public class DropAmountChooser {
  /** Space between the popup border and actual content components */
  private static final int BORDER = 2;
 
  /** Item to be dropped. */
  final StackableItem item;
  /** Target where the user is dropping the item. */
  final DropTarget target;
  /** Drop location within the target component */
  final Point location;
  /** Created selector popup menu */
  final JPopupMenu popup;
  /** Number selector within the popup menu */
  JSpinner spinner;
 
  /**
   * Create a new DropAmountChooser.
   *
   * @param item the item whose drop should be handled by the DropAmountChooser
   * @param target target where the item should be dropped if the user chooses
   *   an amount greater than 0
   * @param point drop location
   */
  DropAmountChooser(StackableItem item, DropTarget target, Point point) {
    this.item = item;
    this.target = target;
    location = point;
    popup = createPopup();
   
    /*
     * Select the text when the the popup is displayed. Unfortunately the
     * selection is normally cleared when the text field gets focus, so we
     * need to do it in a focus listener. Also the focus listener gets run
     * before the selection is cleared so to get the desired effect the
     * selection needs to be pushed to the event queue.
     */
    final JComponent field = getTextField();
    if (field instanceof JTextComponent) {
      field.addFocusListener(new FocusAdapter() {
        @Override
        public void focusGained(FocusEvent e) {
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              ((JTextComponent) field).selectAll();
            }
          });
        }
      });
    }
  }
 
  /**
   * Show the chooser popup.
   *
   * @param parent parent component
   * @param location location of the popup in parent coordinates
   */
  protected void show(Component parent, Point location) {
    popup.show(parent, location.x, location.y);
    // Needs to be after show()
    getTextField().requestFocus();
  }
 
  /**
   * Construct the popup.
   *
   * @return popup
   */
  private JPopupMenu createPopup() {
    JPopupMenu menu = new JPopupMenu();
   
    SpinnerModel model = new SpinnerNumberModel(1, 0, item.getQuantity(), 1);
    spinner = new JSpinner(model);
    /*
     * Setup a key listener for the editor field so that the drop is
     * performed when the user presses enter.
     */
    getTextField().addKeyListener(new KeyAdapter() {
      @Override
      public void keyTyped(KeyEvent e) {
        if (e.getKeyChar() == KeyEvent.VK_ENTER) {
          doDrop();
        }
      }
    });
    JButton button = new JButton("Drop");
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        doDrop();
      }
    });
   
    JComponent content = SBoxLayout.createContainer(SBoxLayout.HORIZONTAL, SBoxLayout.COMMON_PADDING);
    content.setBorder(BorderFactory.createEmptyBorder(BORDER, BORDER, BORDER, BORDER));
    content.add(spinner);
    content.add(button);
    menu.add(content);
   
    return menu;
  }
 
  /**
   * Perform the drop.
   */
  private void doDrop() {
    Object value = spinner.getValue();
    if (value instanceof Integer) {
      int amount = (Integer) value;
      // No need to send drop commands if the user does not want to
      // drop anything
      if (amount > 0) {
        target.dropEntity(item, amount, location);
      }
      popup.setVisible(false);
    }
  }
 
  /**
   * Get the editable text field component of the spinner.
   *
   * @return text field
   */
  private JComponent getTextField() {
    // There really seems to be no simpler way to do this
    JComponent editor = spinner.getEditor();
    if (editor instanceof JSpinner.DefaultEditor) {
      return ((JSpinner.DefaultEditor) editor).getTextField();
    } else {
      Logger.getLogger(DropAmountChooser.class).error("Unknown editor type", new Throwable());
      // This will not work, but at least it won't crash the client
      return editor;
    }
  }
}
TOP

Related Classes of games.stendhal.client.gui.DropAmountChooser

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.