modules/midp-lcdui/src/main/java/javax/microedition/lcdui/Command.java
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the Mozilla Public License Version 2.0.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package javax.microedition.lcdui;
import cc.squirreljme.runtime.cldc.annotation.Api;
import cc.squirreljme.runtime.cldc.annotation.ImplementationNote;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
@Api
public class Command
extends __Action__
{
/** Returns the user to the previous screen.. */
@Api
public static final int BACK =
2;
/** Specified a standard negative to something on the screen. */
@Api
public static final int CANCEL =
3;
/** A command that is used to exit the application. */
@Api
public static final int EXIT =
7;
/** A request for on-line help. */
@Api
public static final int HELP =
5;
/** System specific type. */
@Api
public static final int ITEM =
8;
/** Specified as a standard affirmative to something on the screen. */
@Api
public static final int OK =
4;
/** A command which pertains to the current screen. */
@Api
public static final int SCREEN =
1;
/** A command which will stop an in-progress operation. */
@Api
public static final int STOP =
6;
/** The first command type. */
private static final int _FIRST_TYPE = Command.SCREEN;
/** The last command type. */
private static final int _LAST_TYPE = Command.ITEM;
/** The command type. */
final int _type;
/** The priority. */
@ImplementationNote("In SquirrelJME if the priority is " +
"Integer.MAX_VALUE then it will not be displayed.")
private final int _priority;
/** Is this an implementation specific command with fixed text? */
private final boolean _implspec;
/** The widgets this command is being used by. */
private final Collection<Reference<__CommandWidget__>> _widgets =
new LinkedList<>();
/**
* Creates a new command with the specified parameters.
*
* @param __sl The short label of the command.
* @param __type The type of command this is.
* @param __pri The priority of the command.
* @throws IllegalArgumentException If the command type is not valid.
* @throws NullPointerException If no short label was specified.
* @since 2017/02/28
*/
@Api
public Command(String __sl, int __type, int __pri)
throws IllegalArgumentException, NullPointerException
{
this(__sl, null, null, __type, __pri, false);
}
/**
* Creates a new command with the specified parameters.
*
* @param __sl The short label of the command.
* @param __type The type of command this is.
* @param __pri The priority of the command.
* @param __implspec If true this is an implementation specific command
* which the returned labels are always blank except that internally they
* use the passed strings.
* @throws IllegalArgumentException If the command type is not valid.
* @throws NullPointerException If no short label was specified.
* @since 2017/02/28
*/
Command(String __sl, int __type, int __pri, boolean __implspec)
throws IllegalArgumentException, NullPointerException
{
this(__sl, null, null, __type, __pri, __implspec);
}
/**
* Creates a new command with the specified parameters.
*
* @param __sl The short label of the command.
* @param __ll The long label of the command, may be {@code null}.
* @param __type The type of command this is.
* @param __pri The priority of the command.
* @throws IllegalArgumentException If the command type is not valid.
* @throws NullPointerException If no short label was specified.
* @since 2017/02/28
*/
@Api
public Command(String __sl, String __ll, int __type, int __pri)
throws IllegalArgumentException, NullPointerException
{
this(__sl, null, null, __type, __pri, false);
}
/**
* Creates a new command with the specified parameters.
*
* @param __sl The short label of the command.
* @param __ll The long label of the command, may be {@code null}.
* @param __i The image used on the command, may be {@code null}.
* @param __type The type of command this is.
* @param __pri The priority of the command.
* @throws IllegalArgumentException If the command type is not valid.
* @throws NullPointerException If no short label was specified.
* @since 2017/02/28
*/
@Api
public Command(String __sl, String __ll, Image __i, int __type, int __pri)
throws IllegalArgumentException, NullPointerException
{
this(__sl, __ll, __i, __type, __pri, false);
}
/**
* Creates a new command with the specified parameters.
*
* @param __sl The short label of the command.
* @param __ll The long label of the command, may be {@code null}.
* @param __i The image used on the command, may be {@code null}.
* @param __type The type of command this is.
* @param __pri The priority of the command.
* @param __implspec If true this is an implementation specific command
* which the returned labels are always blank except that internally they
* use the passed strings.
* @throws IllegalArgumentException If the command type is not valid.
* @throws NullPointerException If no short label was specified.
* @since 2018/03/29
*/
Command(String __sl, String __ll, Image __i, int __type, int __pri,
boolean __implspec)
throws IllegalArgumentException, NullPointerException
{
// Check
if (__sl == null)
throw new NullPointerException("NARG");
/* {@squirreljme.error EB1f And invalid command type was specified.
(The command type)} */
if (__type < Command._FIRST_TYPE || __type > Command._LAST_TYPE)
throw new IllegalArgumentException(
String.format("EB1f %d", __type));
// Set
this._implspec = __implspec;
this._type = __type;
this._priority = __pri;
// Part of action
this._shortLabel = __sl;
this._longLabel = __ll;
this._image = __i;
}
/**
* Returns the type of command this is.
*
* @return The command type.
* @since 2018/03/31
*/
@Api
public int getCommandType()
{
return this._type;
}
@Api
public boolean getEnabled()
{
throw Debugging.todo();
}
/**
* Returns the font that is used as a hint for rendering the text in
* a command, it may be disregarded by the implementation.
*
* @return The font that should be used as a hint.
* @since 2018/03/31
*/
@Api
public Font getFont()
{
throw Debugging.todo();
/*
return this._font;
*/
}
/**
* Returns the image the command.
*
* @return The image of the command or {@code null} if it has none.
* @since 2018/03/29
*/
@Api
public Image getImage()
{
// Do not provide implementation specific images
if (this._implspec)
return null;
throw Debugging.todo();
}
/**
* Returns the label used for this command.
*
* @return The label used for the command.
* @since 2018/03/29
*/
@Api
public String getLabel()
{
// Do not provide implementation specific labels
if (this._implspec)
return "";
return this._shortLabel;
}
/**
* Returns the long label of the command.
*
* @return The long label of the command or {@code null} if it has none.
* @since 2018/03/29
*/
@Api
public String getLongLabel()
{
// Do not provide implementation specific labels
if (this._implspec)
return null;
return this._longLabel;
}
/**
* Returns the priority of the command.
*
* @return The command priority.
* @since 2018/12/03
*/
@Api
public int getPriority()
{
return this._priority;
}
/**
* This is called when the enabled state of the parent has changed.
*
* @param __e The new state of the parent.
* @since 2018/04/01
*/
@Override
public void onParentEnabled(boolean __e)
{
// The default implementation does nothing
}
/**
* Sets whether this command is enabled or disabled.
*
* @param __e If the command is enabled or not.
* @since 2018/04/01
*/
@Api
public void setEnabled(boolean __e)
{
// Do nothing for implementation specific commands
if (this._implspec)
return;
throw Debugging.todo();
}
/**
* Sets the font used to be used as a hint when rendering the command.
*
* @param __f The font to use as a hint when rendering the command,
* {@code null} will use the default.
* @since 2018/03/31
*/
@Api
public void setFont(Font __f)
{
// Do nothing for implementation specific commands
if (this._implspec)
return;
throw Debugging.todo();
/*
// Just cache the font but do nothing as it is not supported in
// SquirrelJME (it would complicate command handling) although it
// could potentially be supported in the future for stuff such as
// word processors and such
this._font = __f;
*/
}
/**
* Sets the image to be displayed for this command. If the image is mutable
* then this will take a snapshot of the image and use that snapshot
* instead of the normal image.
*
* A new snapshot from a mutable image can be created by performing:
* {@code command.setImage(command.getImage())}.
*
* @param __i The image to set or {@code null} to clear it.
* @since 2018/04/06
*/
@Api
public void setImage(Image __i)
{
throw Debugging.todo();
/*
// Do nothing for implementation specific commands
if (this._implspec)
return;
Image clone = (__i != null && __i.isMutable() ?
Image.createImage(__i) : __i);
LcdServiceCall.voidCall(LcdFunction.SET_IMAGE, this._handle,
(__i == null ? -1 : __i._handle),
(clone == null ? -1 : clone._handle));
this._image = __i;
*/
}
/**
* Sets the label to be displayed.
*
* @param __s The label to display.
* @throws NullPointerException On null arguments.
* @since 2018/03/29
*/
@Api
public void setLabel(String __s)
throws NullPointerException
{
if (__s == null)
throw new NullPointerException("NARG");
// Do nothing for implementation specific commands
if (this._implspec)
return;
this.__setLabels(__s, this._longLabel, this._image);
}
/**
* Sets the long label of the command.
*
* @param __s The long label to use, {@code null} clears it.
* @since 2018/03/29
*/
@Api
public void setLongLabel(String __s)
{
// Do nothing for implementation specific commands
if (this._implspec)
return;
this.__setLabels(this._shortLabel, __s, this._image);
}
/**
* Registers the command widget wrapper for this command.
*
* @param __wrapper The wrapper to register.
* @throws NullPointerException On null arguments.
* @since 2021/11/30
*/
final void __register(__CommandWidget__ __wrapper)
throws NullPointerException
{
if (__wrapper == null)
throw new NullPointerException("NARG");
// Inform any command widgets of the change
Collection<Reference<__CommandWidget__>> widgets = this._widgets;
for (Iterator<Reference<__CommandWidget__>> it = widgets.iterator();
it.hasNext();)
{
// Cleanup any old stale widget references
Reference<__CommandWidget__> ref = it.next();
__CommandWidget__ widget = ref.get();
if (widget == null)
it.remove();
// Is already in here, so do nothing
else if (widget == __wrapper)
return;
}
// Add it
widgets.add(new WeakReference<>(__wrapper));
}
/**
* Sets the labels for this command.
*
* @param __shortLabel The short label.
* @param __longLabel The long label.
* @param __image The image used.
* @since 2021/11/30
*/
private void __setLabels(String __shortLabel, String __longLabel,
Image __image)
{
// Store the text data
this._shortLabel = __shortLabel;
this._longLabel = __longLabel;
this._image = __image;
// Inform any command widgets of the change
Collection<Reference<__CommandWidget__>> widgets = this._widgets;
for (Iterator<Reference<__CommandWidget__>> it = widgets.iterator();
it.hasNext();)
{
// Cleanup any old stale widget references
Reference<__CommandWidget__> ref = it.next();
__CommandWidget__ widget = ref.get();
if (widget == null)
{
it.remove();
continue;
}
// Inform of the change
widget.__update();
}
}
}