Button.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:12k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit;
  26. import com.sun.lwuit.util.EventDispatcher;
  27. import com.sun.lwuit.geom.Dimension;
  28. import com.sun.lwuit.events.ActionEvent;
  29. import com.sun.lwuit.events.ActionListener;
  30. import com.sun.lwuit.plaf.Border;
  31. import com.sun.lwuit.plaf.Style;
  32. import com.sun.lwuit.plaf.UIManager;
  33. /**
  34.  * Button is the base class for several UI widgets allowing clickability.
  35.  * It has 3 states: rollover, pressed and the default state it 
  36.  * can also have ActionListeners that react when the Button is clicked.
  37.  * 
  38.  * @author Chen Fishbein
  39.  */
  40. public class Button extends Label {
  41.     /**
  42.      * Indicates the rollover state of a button which is equivalent to focused for
  43.      * most uses
  44.      */
  45.     public static final int STATE_ROLLOVER = 0;
  46.     
  47.     /**
  48.      * Indicates the pressed state of a button 
  49.      */
  50.     public static final int STATE_PRESSED = 1;
  51.     
  52.     /**
  53.      * Indicates the default state of a button which is neither pressed nor focused
  54.      */
  55.     public static final int STATE_DEFAULT = 2;
  56.     
  57.     private EventDispatcher dispatcher = new EventDispatcher();
  58.     
  59.     private int state = STATE_DEFAULT;
  60.     
  61.     private Image pressedIcon;
  62.     
  63.     private Image rolloverIcon;
  64.   
  65.     private Command cmd;
  66.     private Style pressedStyle;
  67.     
  68.     /** 
  69.      * Constructs a button with an empty string for its text.
  70.      */
  71.     public Button() {
  72.         this("");
  73.     }
  74.     
  75.     /**
  76.      * Constructs a button with the specified text.
  77.      * 
  78.      * @param text label appearing on the button
  79.      */
  80.     public Button(String text) {
  81.         this(text, null);
  82.     }
  83.     
  84.     /**
  85.      * Allows binding a command to a button for ease of use
  86.      * 
  87.      * @param cmd command whose text would be used for the button and would recive action events
  88.      * from the button
  89.      */
  90.     public Button(Command cmd) {
  91.         this(cmd.getCommandName(), cmd.getIcon());
  92.         addActionListener(cmd);
  93.         this.cmd = cmd;
  94.     }
  95.     
  96.     /**
  97.      * Constructs a button with the specified image.
  98.      * 
  99.      * @param icon appearing on the button
  100.      */
  101.     public Button(Image icon) {
  102.         this("", icon);
  103.     }
  104.     
  105.     /**
  106.      * Constructor a button with text and image
  107.      * 
  108.      * @param text label appearing on the button
  109.      * @param icon image appearing on the button
  110.      */
  111.     public Button(String text, Image icon) {
  112.         super(text);
  113.         setUIID("Button");
  114.         setFocusable(true);
  115.         setIcon(icon);
  116.         this.pressedIcon = icon;
  117.         this.rolloverIcon = icon;
  118.     }
  119.     /**
  120.      * @inheritDoc
  121.      */
  122.     void focusGainedInternal() {
  123.         super.focusGainedInternal();
  124.         state = STATE_ROLLOVER;
  125.     }
  126.     
  127.     /**
  128.      * @inheritDoc
  129.      */
  130.     void focusLostInternal() {
  131.         super.focusLostInternal();
  132.         state = STATE_DEFAULT;
  133.     }
  134.     
  135.     /**
  136.      * Returns the button state
  137.      * 
  138.      * @return One of STATE_ROLLOVER, STATE_DEAFULT, STATE_PRESSED
  139.      */
  140.     public int getState() {
  141.         return state;
  142.     }
  143.     
  144.     /**
  145.      * Indicates the icon that is displayed on the button when the button is in 
  146.      * pressed state
  147.      * 
  148.      * @return icon used
  149.      * @see #STATE_PRESSED
  150.      */
  151.     public Image getPressedIcon() {
  152.         return pressedIcon;
  153.     }
  154.     
  155.     /**
  156.      * Indicates the icon that is displayed on the button when the button is in 
  157.      * rolled over state
  158.      * 
  159.      * @return icon used
  160.      * @see #STATE_ROLLOVER
  161.      */
  162.     public Image getRolloverIcon() {
  163.         return rolloverIcon;
  164.     }
  165.     
  166.     /**
  167.      * Indicates the icon that is displayed on the button when the button is in 
  168.      * rolled over state
  169.      * 
  170.      * @param rolloverIcon icon to use
  171.      * @see #STATE_ROLLOVER
  172.      */
  173.     public void setRolloverIcon(Image rolloverIcon) {
  174.         this.rolloverIcon = rolloverIcon;
  175.         setShouldCalcPreferredSize(true);
  176.         checkAnimation();
  177.         repaint();        
  178.     }
  179.     
  180.     /**
  181.      * Indicates the icon that is displayed on the button when the button is in 
  182.      * pressed state
  183.      * 
  184.      * @param pressedIcon icon used
  185.      * @see #STATE_PRESSED
  186.      */
  187.     public void setPressedIcon(Image pressedIcon) {
  188.         this.pressedIcon = pressedIcon;
  189.         setShouldCalcPreferredSize(true);
  190.         checkAnimation();
  191.         repaint();
  192.     }
  193.     void checkAnimation() {
  194.         super.checkAnimation();
  195.         if((pressedIcon != null && pressedIcon.isAnimation()) || 
  196.             (rolloverIcon != null && rolloverIcon.isAnimation())) {
  197.             Form parent = getComponentForm();
  198.             if(parent != null) {
  199.                 // animations are always running so the internal animation isn't
  200.                 // good enough. We never want to stop this sort of animation
  201.                 parent.registerAnimated(this);
  202.             }
  203.         }
  204.     }
  205.     
  206.     /**
  207.      * Adds a listener to the button which will cause an event to dispatch on click
  208.      * 
  209.      * @param l implementation of the action listener interface
  210.      */
  211.     public void addActionListener(ActionListener l){
  212.         dispatcher.addListener(l);
  213.     }
  214.     
  215.     /**
  216.      * Removes the given action listener from the button
  217.      * 
  218.      * @param l implementation of the action listener interface
  219.      */
  220.     public void removeActionListener(ActionListener l){
  221.         dispatcher.removeListener(l);
  222.     }
  223.     /**
  224.      * Returns the icon for the button based on its current state
  225.      *
  226.      * @return the button icon based on its current state
  227.      */
  228.     public Image getIconFromState() {
  229.         Image icon = null;
  230.         switch (getState()) {
  231.             case Button.STATE_DEFAULT:
  232.                 icon = getIcon();
  233.                 break;
  234.             case Button.STATE_PRESSED:
  235.                 icon = getPressedIcon();
  236.                 if (icon == null) {
  237.                     icon = getIcon();
  238.                 }
  239.                 break;
  240.             case Button.STATE_ROLLOVER:
  241.                 icon = getRolloverIcon();
  242.                 if (icon == null) {
  243.                     icon = getIcon();
  244.                 }
  245.                 break;
  246.         }
  247.         return icon;
  248.     }
  249.     /**
  250.      * @inheritDoc
  251.      */
  252.     void fireActionEvent(){
  253.         super.fireActionEvent();
  254.         if(cmd != null) {
  255.             ActionEvent ev = new ActionEvent(cmd);
  256.             dispatcher.fireActionEvent(ev);
  257.             if(!ev.isConsumed()) {
  258.                 Form f = getComponentForm();
  259.                 if(f != null) {
  260.                     f.actionCommandImpl(cmd);
  261.                 }
  262.             }
  263.         } else {
  264.             dispatcher.fireActionEvent(new ActionEvent(this));
  265.         }
  266.     }
  267.     
  268.     /**
  269.      * Invoked to change the state of the button to the pressed state
  270.      */
  271.     void pressed(){
  272.         if(isEnabled()) {
  273.             state=STATE_PRESSED;
  274.             repaint();
  275.         }
  276.     }
  277.     
  278.     /**
  279.      * Invoked to change the state of the button to the released state
  280.      */
  281.     void released(){
  282.         if(isEnabled()) {
  283.             state=STATE_ROLLOVER;
  284.             repaint();
  285.             fireActionEvent();
  286.         }
  287.     }
  288.     
  289.     /**
  290.      * @inheritDoc
  291.      */
  292.     public void keyPressed(int keyCode) {
  293.         if (Display.getInstance().getGameAction(keyCode) == Display.GAME_FIRE){
  294.             pressed();
  295.         }
  296.     }
  297.     
  298.     /**
  299.      * @inheritDoc
  300.      */
  301.     public void keyReleased(int keyCode) {
  302.         if (Display.getInstance().getGameAction(keyCode) == Display.GAME_FIRE){
  303.             released();
  304.         }
  305.     }
  306.     
  307.     /**
  308.      * @inheritDoc
  309.      */
  310.     public void keyRepeated(int keyCode) {
  311.     }
  312.     
  313.     /**
  314.      * @inheritDoc
  315.      */
  316.     protected void fireClicked() {
  317.         pressed();
  318.         released();
  319.     }
  320.     
  321.     /**
  322.      * @inheritDoc
  323.      */
  324.     protected boolean isSelectableInteraction() {
  325.         return true;
  326.     }
  327.     /**
  328.      * @inheritDoc
  329.      */
  330.     public void pointerHover(int[] x, int[] y) {
  331.         requestFocus();
  332.     }
  333.     
  334.     /**
  335.      * @inheritDoc
  336.      */
  337.     public void pointerHoverReleased(int[] x, int[] y) {
  338.         requestFocus();
  339.     }
  340.     /**
  341.      * @inheritDoc
  342.      */
  343.     public void pointerPressed(int x, int y) {
  344.         clearDrag();
  345.         setDragActivated(false);
  346.         pressed();
  347.     }
  348.     
  349.     /**
  350.      * @inheritDoc
  351.      */
  352.     public void pointerReleased(int x, int y) {
  353.         released();
  354.     }
  355.     
  356.     /**
  357.      * @inheritDoc
  358.      */
  359.     public void paint(Graphics g) {
  360.         UIManager.getInstance().getLookAndFeel().drawButton(g, this);
  361.     }
  362.     
  363.     /**
  364.      * @inheritDoc
  365.      */
  366.     protected Dimension calcPreferredSize(){
  367.         return UIManager.getInstance().getLookAndFeel().getButtonPreferredSize(this);
  368.     }
  369.     
  370.     /**
  371.      * @inheritDoc
  372.      */
  373.     protected Border getBorder() {
  374.         return getStyle().getBorder();
  375.     }
  376.     /**
  377.      * Returns the Component Style for the pressed state allowing us to manipulate
  378.      * the look of the component when it is pressed
  379.      *
  380.      * @return the component Style object
  381.      */
  382.     public Style getPressedStyle() {
  383.         if (pressedStyle == null) {
  384.             pressedStyle = UIManager.getInstance().getComponentCustomStyle(getUIID(), "press");
  385.             pressedStyle.addStyleListener(this);
  386.             if(pressedStyle.getBgPainter() == null){
  387.                 pressedStyle.setBgPainter(new BGPainter());
  388.             }
  389.         }
  390.         return pressedStyle;
  391.     }
  392.     /**
  393.      * Sets the Component Style for the pressed state allowing us to manipulate
  394.      * the look of the component when it is pressed
  395.      *
  396.      * @param style the component Style object
  397.      */
  398.     public void setPressedStyle(Style style) {
  399.         if (pressedStyle != null) {
  400.             pressedStyle.removeStyleListener(this);
  401.         }
  402.         pressedStyle = style;
  403.         pressedStyle.addStyleListener(this);
  404.         if (pressedStyle.getBgPainter() == null) {
  405.             pressedStyle.setBgPainter(new BGPainter());
  406.         }
  407.         setShouldCalcPreferredSize(true);
  408.         checkAnimation();
  409.     }
  410.     /**
  411.      * @inheritDoc
  412.      */
  413.     protected void refreshTheme(String id) {
  414.         if(pressedStyle != null) {
  415.             setPressedStyle(mergeStyle(pressedStyle, UIManager.getInstance().getComponentCustomStyle(id, "press")));
  416.         }
  417.         super.refreshTheme(id);
  418.     }
  419.     /**
  420.      * @inheritDoc
  421.      */
  422.     public Style getStyle() {
  423.         if(state == STATE_PRESSED) {
  424.             return getPressedStyle();
  425.         }
  426.         return super.getStyle();
  427.     }
  428.     /**
  429.      * This method return the Button Command if exists
  430.      * 
  431.      * @return Command Object or null if a Command not exists
  432.      */
  433.     public Command getCommand() {
  434.         return cmd;
  435.     }
  436.     /**
  437.      * Returns true if the button is selected for toggle buttons,
  438.      * throws an exception if this is not a toggle button
  439.      *
  440.      * @return true if the button is selected
  441.      */
  442.     public boolean isSelected() {
  443.         throw new RuntimeException();
  444.     }
  445. }