⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialog.java

📁 关于J4ME J2ME实例
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.j4me.ui;

import java.util.*;
import javax.microedition.lcdui.*;
import org.j4me.ui.components.*;
import org.j4me.util.*;

/**
 * The <code>Dialog</code> class is a base class for any screen that accepts user input
 * using standard components like the text box.  It is similar to the MIDP <code>Form</code> class
 * except that it uses the J4ME control flow and has an OK and Cancel button built in.
 * <p>
 * Form classes can only have component objects, like the text box or label, placed on them.
 * The class handles layout, painting, and management of the components.
 * If you need direct control over the appearance of the screen use the <code>DeviceScreen</code>
 * class.
 * 
 * @see javax.microedition.lcdui.Form
 */
public abstract class Dialog
	extends DeviceScreen
{
	/**
	 * The collection of all components on this form.  Components are displayed
	 * as ordered from top to bottom.
	 */
	private Vector components = new Vector();
	
	/**
	 * The index of <code>component</code> the user currently has highlighted.
	 * If this is not an index of <code>component</code> nothing is highlighted.
	 */
	private int highlightedComponent = -1;
	
	/**
	 * The number of pixels between the left and right of the screen and the
	 * components.  This also pads the top and bottom of the form; however,
	 * scrolling can make the text appear at the very top and bottom of the
	 * screen.
	 */
	private int margin = 5;

	/**
	 * The number of pixels above and below components.
	 */
	private int spacing = margin;
	
	/**
	 * The offset into the form that has been scrolled down.  0 indicates
	 * the very top of the form is shown at the top of the screen.  100
	 * would indicate that the current top of the screen (i.e. y == 0)
	 * shows the 100th pixel down in the form.  If the first component
	 * were 80 pixels tall and the second 40, 100 would mean the bottom
	 * half of the second component would be at the top of the screen.
	 */
	private int topOfScreen = 0;
	
	/**
	 * The number of pixels wide each component is.
	 * <p>
	 * When the form is painted for the first time this number will be
	 * calculated.  If the components on the form are changed, this will be
	 * reset back to <code>null</code>.
	 * <p>
	 * The last element in this array is a dummy element.
	 */
	private int[] componentWidths = null;
	
	/**
	 * The number of pixels high the entire form is with all the components
	 * on it.  If this number is greater than the height of the screen, a
	 * vertical scrollbar will be added to the side.
	 * <p>
	 * When the form is painted for the first time this number will be
	 * calculated.  If the components on the form are changed, this will be
	 * reset back to <code>null</code>.
	 * <p>
	 * The last element in this array is a dummy element.  Its value helps
	 * determine the bottom of the last component.
	 */
	private int[] absoluteHeights = null;
	
	/**
	 * Implicitly called by derived classes to setup a new J4ME form.
	 */
	public Dialog ()
	{
		super();
		
		// Set the default menu options.
		Theme theme = UIManager.getTheme();
		String cancel = theme.getMenuTextForCancel();
		String ok = theme.getMenuTextForOK();
		setMenuText( cancel, ok );
	}

	/**
	 * Called immediately before this screen is replaced by another screen.
	 * <p>
	 * Notifies all the components they are hidden.  Classes that override
	 * this method should be sure to call <code>super.onDeselection</code>.
	 * 
	 * @see DeviceScreen#hideNotify()
	 */
	public void hideNotify ()
	{
		// Hide all the components on the screen.
		Enumeration e = components.elements();
		
		while ( e.hasMoreElements() )
		{
			Component c = (Component)e.nextElement();
			c.show( false );
		}
		
		// Continue deselection.
		super.hideNotify();
	}

	/**
	 * Adds the <code>component</code> to the end of this form.
	 * 
	 * @param component is the UI component to add to the bottom of the form.
	 */
	public void append (Component component)
	{
		clearLayout();
		components.addElement( component );
	}
	
	/**
	 * Inserts the <code>component</code> in this form at the specified <code>index</code>.
	 * Each component on this form with an index greater or equal to the
	 * specified <code>index</code> is shifted upward to have an index one greater
	 * than the value it had previously.
	 * 
	 * @param component is the UI component to insert.
	 * @param index is where to insert <code>component</code> on the form.  It must
	 *  greater than or equal to 0 and less than or equal to the number of
	 *  components already on the form.
	 * @throws ArrayIndexOutOfBoundsException if the index was invalid.
	 */
	public void insert (Component component, int index)
	{
		clearLayout();
		components.insertElementAt( component, index );
	}
	
	/**
	 * Sets the <code>component</code> in this form at the specified <code>index</code>.
	 * The previous component at that position is discarded.
	 * 
	 * @param component is the UI component to set to.
	 * @param index is where to set <code>component</code> on the form.  It must
	 *  greater than or equal to 0 and less than the number of
	 *  components already on the form.
	 * @throws ArrayIndexOutOfBoundsException if the index was invalid.
	 */
	public void set (Component component, int index)
	{
		clearLayout();
		components.setElementAt( component, index );
	}
	
	/**
	 * Removes the first occurrence of the <code>component</code> from this form.
	 * If <code>component</code> is found on this form, each component on the form
	 * with an index greater or equal to the <code>component</code>'s index is
	 * shifted downward to have an index one smaller than the value it had
	 * previously.
	 * 
	 * @param component is the UI component to remove.
	 */
	public void delete (Component component)
	{
		clearLayout();
		components.removeElement( component );
	}
	
	/**
	 * Deletes the <code>component</code> at the specified <code>index</code>.  Each
	 * component in this vector with an index greater or equal to the
	 * specified index is shifted downward to have an index one smaller
	 * than the value it had previously.
	 *  
	 * @param index is the index of the component to remove.  It must be
	 *  a value greater than or equal to 0 and less than the current
	 *  number of components on the form.
	 * @throws ArrayIndexOutOfBoundsException if the index was invalid.
	 */
	public void delete (int index)
	{
		clearLayout();
		components.removeElementAt( index );
	}
	
	/**
	 * Removes all of the components from this form.
	 */
	public void deleteAll ()
	{
		clearLayout();
		components.removeAllElements();
	}
	
	/**
	 * Returns an enumeration of the components on this form.
	 * 
	 * @return An enumeration of the components on this form.
	 */
	public Enumeration components ()
	{
		clearLayout();
		return components.elements();
	}
	
	/**
	 * Returns the number of components on this form.
	 * 
	 * @return The number of components on this form.
	 */
	public int size ()
	{
		return components.size();
	}
	
	/**
	 * Returns the component at the specified index.
	 * 
	 * @param index is the value into the component list to get.
	 * @return The component at <code>index</code> or <code>null</code> if the
	 *  index is invalid.
	 */
	public Component get (int index)
	{
		Component c = null;
		
		if ( (index >= 0) && (index < components.size()) )
		{
			c = (Component)components.elementAt( index );
		}
		
		return c; 
	}
	
	/**
	 * Returns the index of the currently selected component.  It is
	 * the one the user can currently enter data into.
	 * 
	 * @return The index of the component on the form that is currently
	 *  selected.
	 */
	public int getSelected ()
	{
		if ( highlightedComponent < 0 )
		{
			return 0;
		}
		else
		{
			return highlightedComponent;
		}
	}
	
	/**
	 * Returns the index of the component that contains the given pixel.
	 * If no component is at that location, for example it is in the
	 * spacing between components, then <code>-1</code> is returned.
	 * <p>
	 * This method assumes that the click is relative to the form
	 * area.  It may not address the title bar, menu bar, or a
	 * scroll bar.
	 * 
	 * @param x is the X-coordinate of the pixel on the form.
	 * @param y is the Y-coordinate of the pixel on the form.
	 * @return The index of the component containing the pixel
	 *  (<code>x</code>, <code>y</code>) or <code>-1</code> if no component contains it.
	 */
	private int getAt (int x, int y)
	{
		int matched = -1;
		
		// Get the absolute position of y on the form.
		int absY = topOfScreen + y;
		
		// Walk the list of component positions until absY is found.
		for ( int i = 0; i < absoluteHeights.length - 1; i++ )
		{
			// Get the dimensions of this component.
			int top = absoluteHeights[i];
			int topOfNext = absoluteHeights[i + 1];
			int bottom = topOfNext - spacing;
			
			int left = margin;
			int right = left + componentWidths[i];
			
			// Does the point fall within this component?
			if ( (absY >= top) && (absY < bottom) &&
				 (x >= left) && (x < right) )
			{
				// This is the component that (x, y) falls within.
				matched = i;
			}
			
			// Stop processing if point is above the top of the component.
			if ( absY < topOfNext )
			{
				break;
			}
		}
		
		return matched;
	}
	
	/**
	 * Sets the selected component.  It is the one the user can input
	 * data into and that the screen is scrolled to.
	 * 
	 * @param index is the new selected component.
	 */
	public void setSelected (int index)
	{
		if ( (index < 0) || (index >= components.size()) )
		{
			throw new IndexOutOfBoundsException( String.valueOf(index) );
		}
		
		highlightedComponent = index;

		// Scroll screen to this component.
		if ( absoluteHeights == null )
		{
			calculateLayout( UIManager.getTheme(), getWidth(), getHeight() );
		}
		
		// Set the top of the screen. 
		if ( index == 0 )
		{
			// The top of the screen will be the very start.
			topOfScreen = 0;
		}
		else
		{
			// The top of the screen will be the top of the component.
			topOfScreen = absoluteHeights[index] - spacing;  
		}
		
		// Adjust the top of the screen for scrolling.
		int maxScroll = absoluteHeights[absoluteHeights.length - 1] - getHeight();
		
		if ( maxScroll <= 0 )
		{
			// All the components fit on one form.
			topOfScreen = 0;
		}
		else if ( topOfScreen > maxScroll )
		{
			// Scroll all the way to the bottom.  The highlighted 
			// component will be visible, but not at the top of the page.
			topOfScreen = maxScroll;
		}
	}
	
	/**
	 * Sets the selected component.  It is the one the user can input
	 * data into and that the screen is scrolled to.
	 * 
	 * @param component is the new selected component.  If it is not
	 *  on the form this has no effect.
	 */
	public void setSelected (Component component)
	{
		int index = 0;
		
		// Walk the list of components until we find it.
		Enumeration e = components.elements();
		
		while ( e.hasMoreElements() )
		{
			Component c = (Component)e.nextElement();

			if ( c == component )
			{
				// This is the component.
				break;
			}
			
			index++;
		}
		
		// Set the component as the selected one.
		if ( index < size() )
		{
			setSelected( index );
		}
	}

	/**
	 * Paints the form and its components.  The layout is calculated from the
	 * components and their order.
	 * 
	 * @param g is the <code>Graphics</code> object to paint with.
	 */
	protected synchronized void paint (Graphics g)
	{
		// Have we determined the layout?
		Theme theme = UIManager.getTheme();
		int height = getHeight();
		
		// Add a vertical scrollbar?
		if ( hasVerticalScrollbar() )
		{
			// Paint the scrollbar.
			int width = super.getWidth();  // Exclude the margins and scrollbar
			int heightOfAllComponents = absoluteHeights[absoluteHeights.length - 1];
			paintVerticalScrollbar( g, 0, 0, width, height, topOfScreen, heightOfAllComponents );
		}
		
		// Walk the list of components and paint them.
		int formWidth = getWidth();
		int bottomOfScreen = topOfScreen + height;
		
		Enumeration list = components.elements();
		
		for ( int i = 0; i < absoluteHeights.length - 1; i++ )
		{
			Component c = (Component)list.nextElement();
			int componentTop = absoluteHeights[i];
			int componentBottom = absoluteHeights[i + 1] - spacing; 
			
			// Is the component visible on the screen?
			if ( componentTop >= bottomOfScreen )
			{
				// Skip drawing components below the screen.
				c.show( false );
			}
			else if ( componentBottom <= topOfScreen )
			{
				// Skip drawing components above the screen.
				c.show( false );
			}
			else  // visible
			{
				c.show( true );
				
				// Calculate the position of the component.
				int componentX = margin;
				int componentY = componentTop - topOfScreen;
				int componentWidth = formWidth;
				int componentHeight = componentBottom - componentTop;
				
				// Paint this component.
				if ( intersects(g, componentX, componentY, componentWidth, componentHeight) )
				{
					boolean selected = (i == highlightedComponent);
					
					c.paint( g, theme, this,
							 componentX, componentY,
							 componentWidth, componentHeight,
							 selected );
				}
			}
		}
	}
	
	/**
	 * Returns the margin for the left and right of the screen.  This
	 * also pads the top and bottom of the form; however, scrolling can
	 * make the text appear at the very top and bottom of the screen.
	 * 
	 * @return The number of pixels between components and the edges
	 *  of the screen.
	 */
	public int getMargin ()
	{
		return margin;
	}
	
	/**
	 * Sets the margin for the left and right of the screen.  This
	 * also pads the top and bottom of the form; however, scrolling can
	 * make the text appear at the very top and bottom of the screen.
	 * 
	 * @param margin is the number of pixels between components and
	 *  the edges of the screen.  Values less than 0 are ignored.
	 */
	public void setMargin (int margin)
	{
		if ( (margin >= 0) && (this.margin != margin) )
		{
			this.margin = margin;
			
			// Recalculate the layout with the new margins later.
			clearLayout();
		}
	}
	
	/**
	 * Returns the vertical spacing between components.
	 * 
	 * @return The number of pixels that vertically separate components.
	 */
	public int getSpacing ()
	{
		return spacing;
	}
	
	/**
	 * Sets the vertical spacing between components. 
	 * 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -