/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.midp;
import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
import malik.emulator.application.*;
import malik.emulator.fileformats.text.mapped.*;
import malik.emulator.io.cloud.*;
import malik.emulator.io.j2me.*;
import malik.emulator.media.text.*;
import malik.emulator.util.*;
public class SystemGUI extends Object
implements CommandListener, ItemCommandListener,
ItemStateListener, VirtualSystemGUI, ThreadTerminationListener
{
public static final Command APPLY_SETTINGS_COMMAND;
public static final Command BACK_TO_SETTINGS_COMMAND;
private static final int NAME = 0;
private static final int ICON = 1;
private static final int CLASS = 2;
private static final int SETTABLE_KEY_CODES = 7;
private static final int NATIVE_SYSTEM_SETTINGS = 3;
private static final int[] KEYS;
private static final int[] DEVICE_KEYS;
private static final KeyCodeSet[] KEY_CODE_SETS;
private static final String YES = "Да";
private static final String NO = "Нет";
static
{
APPLY_SETTINGS_COMMAND = new Command("Применить", Command.SCREEN, Integer.MAX_VALUE);
BACK_TO_SETTINGS_COMMAND = new Command("Назад", Command.BACK, Integer.MIN_VALUE);
KEYS = new int[] {
0, AppProxy.KEY_ESCAPE, AppProxy.KEY_F1, AppProxy.KEY_F2, AppProxy.KEY_F3,
AppProxy.KEY_F4, AppProxy.KEY_F5, AppProxy.KEY_F6, AppProxy.KEY_F7,
AppProxy.KEY_F8, AppProxy.KEY_F9, AppProxy.KEY_F10, AppProxy.KEY_F11,
AppProxy.KEY_F12, AppProxy.KEY_F13, AppProxy.KEY_F14, AppProxy.KEY_F15,
AppProxy.KEY_F16, AppProxy.KEY_F17, AppProxy.KEY_F18, AppProxy.KEY_F19,
AppProxy.KEY_F20, AppProxy.KEY_F21, AppProxy.KEY_F22, AppProxy.KEY_F23,
AppProxy.KEY_F24, AppProxy.KEY_ENTER, AppProxy.KEY_SPACE, AppProxy.KEY_INSERT,
AppProxy.KEY_DELETE, AppProxy.KEY_HOME, AppProxy.KEY_END, AppProxy.KEY_PAGE_UP,
AppProxy.KEY_PAGE_DOWN, AppProxy.KEY_UP, AppProxy.KEY_DOWN, AppProxy.KEY_LEFT,
AppProxy.KEY_RIGHT, AppProxy.KEY_NUM_PLUS, AppProxy.KEY_NUM_MINUS,
AppProxy.KEY_NUM_STAR, AppProxy.KEY_NUM_DIVIDE, AppProxy.KEY_NUM_DECIMAL,
AppProxy.KEY_NUM_0, AppProxy.KEY_NUM_1, AppProxy.KEY_NUM_2, AppProxy.KEY_NUM_3,
AppProxy.KEY_NUM_4, AppProxy.KEY_NUM_5, AppProxy.KEY_NUM_6, AppProxy.KEY_NUM_7,
AppProxy.KEY_NUM_8, AppProxy.KEY_NUM_9
};
DEVICE_KEYS = new int[] {
MIDletProxy.DEVICE_KEY_UP, MIDletProxy.DEVICE_KEY_DOWN,
MIDletProxy.DEVICE_KEY_LEFT, MIDletProxy.DEVICE_KEY_RIGHT,
MIDletProxy.DEVICE_KEY_SELECT, MIDletProxy.DEVICE_KEY_SOFT1,
MIDletProxy.DEVICE_KEY_SOFT2, MIDletProxy.DEVICE_KEY_CONSOLE,
MIDletProxy.DEVICE_KEY_EXITAPP,
MIDletProxy.DEVICE_KEY_1, MIDletProxy.DEVICE_KEY_2, MIDletProxy.DEVICE_KEY_3,
MIDletProxy.DEVICE_KEY_4, MIDletProxy.DEVICE_KEY_5, MIDletProxy.DEVICE_KEY_6,
MIDletProxy.DEVICE_KEY_7, MIDletProxy.DEVICE_KEY_8, MIDletProxy.DEVICE_KEY_9,
MIDletProxy.DEVICE_KEY_STAR, MIDletProxy.DEVICE_KEY_0, MIDletProxy.DEVICE_KEY_POUND
};
KEY_CODE_SETS = new KeyCodeSet[] {
new KeyCodeSet("Свои настройки", 0, 0, 0, 0, 0, 0, 0),
new KeyCodeSet("Nokia (по умолчанию)", -1, -2, -3, -4, -5, -6, -7),
new KeyCodeSet("Motorola", -1, -6, -2, -5, -20, -21, -22),
new KeyCodeSet("Siemens", -59, -60, -61, -62, -26, -1, -4)
};
}
public static Image loadImage(String fileName)
{
Image result;
FileInputStream stream;
try
{
(stream = new FileInputStream(fileName)).checkOpenError();
try
{
result = Image.createImage(stream);
}
finally
{
stream.close();
}
}
catch(IOException e)
{
e.printRealStackTrace();
result = null;
}
return result;
}
public static Image loadMIDletIcon(AttributableMappedTextDecoder descriptor)
{
String iconRes;
if((iconRes = descriptor.get("MIDlet-Icon")) == null)
{
return null;
}
if(iconRes.length() > 0 && iconRes.charAt(0) == '/')
{
iconRes = iconRes.substring(1);
}
return loadImage("/res/".concat(iconRes));
}
private static int toFontSize(int systemGUISize)
{
return systemGUISize == 2 ? 2 : systemGUISize ^ 0x01;
}
private static int indexOfKey(int key)
{
int i;
int[] keys;
for(i = (keys = KEYS).length; i-- > 1; )
{
if(keys[i] == key)
{
return i;
}
}
return 0;
}
private static int indexOfFont(RasterFont font)
{
int i;
for(i = RasterFont.getRasterFontsCount(); i-- > 0; )
{
if(RasterFont.getRasterFontAtIndex(i) == font)
{
return i;
}
}
return -1;
}
private static String[] fillMIDletList(Choice dst, AttributableMappedTextDecoder descriptor)
{
int i;
int len;
String[] attr;
String[] result;
String iconRes;
String className;
String midletName;
len = 0;
result = new String[1];
dst.deleteAll();
for(i = 0; (attr = descriptor.getAttributes("MIDlet-" + (i + 1))) != null &&
attr.length >= 3; i++)
{
if((iconRes = attr[ICON]) == null)
{
continue;
}
if(iconRes.length() > 0 && iconRes.charAt(0) == '/')
{
iconRes = iconRes.substring(1);
}
if((className = attr[CLASS]) == null || (midletName = attr[NAME]) == null)
{
continue;
}
if(len == result.length)
{
Array.copy(result, 0, result = new String[(len << 1) + 1], 0, len);
}
result[len++] = className;
dst.append(midletName, loadImage("/res/".concat(iconRes)));
}
if(len != result.length)
{
Array.copy(result, 0, result = new String[len], 0, len);
}
return result;
}
private boolean midletStarted;
private String[] midletClassNames;
private Displayable[] screensOfSettings;
private String midletName;
private Command commandLaunch;
private Command commandExit;
private Command commandSettings;
private Command commandAboutApplication;
private Command commandAboutImplementation;
private Command commandProperties;
private Command commandDeleteAll;
private Command commandDelete;
private Command commandUpdate;
private Command commandBack;
private Command commandYes;
private Command commandNo;
private Ticker tickerLaunch;
private Ticker tickerSettings;
private Gauge itemFrequency;
private ChoiceGroup itemModelSelect;
private ChoiceGroup itemSystemSettings;
private StringItem itemRecordName;
private StringItem itemRecordSize;
private StringItem itemRecordNumRecords;
private StringItem itemRecordLastModified;
private StringItem itemRecordVersion;
private ButtonSet itemKeypad;
private StringItem itemKeyDescription;
private StringItem itemKeyEquivalent;
private StringItem itemLibraryList;
private List screenMIDlets;
private List screenSettings;
private Form screenSettingControl;
private Form screenSettingKeyCodes;
private Form screenSettingFonts;
private Form screenSettingFrequency;
private Form screenSettingSystem;
private List screenSettingRecords;
private Form screenSettingKeypad;
private Form screenRecordProperties;
private Alert screenRecordDelete;
private Alert screenRecordDeleteAll;
private Alert screenRecordDeletionError;
private Form screenAboutApplication;
private Form screenAboutImplementation;
private Form screenError;
private Alert screenExit;
private ConsoleScreen screenConsole;
public SystemGUI()
{
int i;
List scr;
String midletName;
String parameterKey;
String parameterValue;
ConsoleScreen console;
AttributableMappedTextDecoder descriptor = MIDletProxy.getInstance().getMIDletDescriptor();
Run.getInstance().setThreadProxy(this);
this.midletClassNames = fillMIDletList(scr = getScreenMIDlets(), descriptor);
this.midletName = midletName = descriptor.get("MIDlet-Name");
this.screenConsole = console = new SystemConsole("Консоль Java 2 ME", this);
scr.setTitle(midletName);
getScreenExit();
console.addConsoleCommand(new ImageCommand());
console.addConsoleCommand(new SoundCommand());
for(i = 1; true; i++)
{
parameterKey = "malik.emulator.microedition.console.command.".concat(
Integer.toString(i));
if((parameterValue = System.getSystemProperty(parameterKey)) == null)
{
break;
}
try
{
console.addConsoleCommand((ConsoleCommand) Class.forName(parameterValue).
newInstance());
}
catch(Exception e)
{
e.printRealStackTrace();
}
}
}
public void commandAction(Command command, Displayable screen)
{
int sel;
List list;
Display display;
MIDletProxy proxy;
display = (proxy = MIDletProxy.getInstance()).getEmulatorScreen();
if(command == APPLY_SETTINGS_COMMAND)
{
applySettingsFromScreen((list = getScreenSettings()).getSelectedIndex());
display.setCurrent(list);
return;
}
if(command == BACK_TO_SETTINGS_COMMAND)
{
display.setCurrent(getScreenSettings());
return;
}
if(screen == (list = screenMIDlets))
{
if(command == commandLaunch)
{
launchSelectedMIDlet(list);
return;
}
if(command == commandSettings)
{
display.setCurrent(getScreenSettings());
return;
}
if(command == commandAboutApplication)
{
display.setCurrent(getScreenAboutApplication());
return;
}
if(command == commandAboutImplementation)
{
display.setCurrent(getScreenAboutImplementation());
return;
}
if(command == commandExit)
{
Run.getInstance().terminate();
}
return;
}
if(screen == (list = screenSettings))
{
if(command == List.SELECT_COMMAND)
{
if((sel = list.getSelectedIndex()) == list.size() - 1)
{
Run.getInstance().showMessage("Сохранение настроек…");
proxy.saveMIDletProperties();
display.setCurrent(screenMIDlets);
return;
}
updateSettingsScreen(sel);
display.setCurrent(screensOfSettings[sel]);
return;
}
if(command == commandBack)
{
display.setCurrent(screenMIDlets);
}
return;
}
if(screen == (list = screenSettingRecords))
{
if(command == commandProperties)
{
showSelectedRecordProperties(list, display);
return;
}
if(command == commandDelete)
{
showSelectedRecordDeleteDialog(list, display);
return;
}
if(command == commandDeleteAll)
{
display.setCurrent(getScreenRecordDeleteAll());
return;
}
if(command == commandUpdate)
{
updateRecordList();
}
return;
}
if(screen == screenRecordProperties && command == commandBack)
{
display.setCurrent(screenSettingRecords);
return;
}
if(screen == screenRecordDelete)
{
if(command == commandYes)
{
deleteSelectedRecord(display);
return;
}
if(command == commandNo)
{
display.setCurrent(screenSettingRecords);
}
return;
}
if(screen == screenRecordDeleteAll)
{
if(command == commandYes)
{
deleteAllRecords(display);
return;
}
if(command == commandNo)
{
display.setCurrent(screenSettingRecords);
}
return;
}
if(screen == screenRecordDeletionError && command == Alert.DISMISS_COMMAND)
{
updateRecordList();
display.setCurrent(screenSettingRecords);
return;
}
if((screen == screenAboutApplication || screen == screenAboutImplementation) &&
command == commandBack)
{
display.setCurrent(screenMIDlets);
return;
}
if(screen == screenConsole && command == ConsoleScreen.BACK_COMMAND)
{
display.hideSystemScreen();
return;
}
if(screen == screenExit)
{
if(command != null && YES.equals(command.getLabel()))
{
stopMIDlet();
return;
}
display.hideSystemScreen();
return;
}
if(screen == screenError && command == commandExit)
{
Run.getInstance().terminate();
}
}
public void commandAction(Command command, Item item)
{
int i;
Displayable[] screens;
Displayable scr;
FormSettings form;
if(command != List.SELECT_COMMAND)
{
return;
}
for(i = (screens = screensOfSettings).length; i-- > 0; )
{
if(!((scr = screens[i]) instanceof FormSettings))
{
continue;
}
form = (FormSettings) scr;
if(item == form.getApplyButton())
{
commandAction(APPLY_SETTINGS_COMMAND, form);
break;
}
if(item == form.getBackButton())
{
commandAction(BACK_TO_SETTINGS_COMMAND, form);
break;
}
}
}
public void itemStateChanged(Item item)
{
int i;
int code;
int[] codes;
MIDletProxy proxy;
ButtonSet keypad;
Choice list;
Form form;
if(item == (list = itemModelSelect))
{
form = screenSettingKeyCodes;
i = (codes = KEY_CODE_SETS[list.getSelectedIndex()].getKeyCodesAsArray()).length;
while(i-- > 0)
{
if((code = codes[i]) != 0)
{
((Input) form.get(i + 1)).setString(Integer.toString(code));
}
}
return;
}
if(item == (keypad = itemKeypad))
{
proxy = MIDletProxy.getInstance();
switch(code = keypad.getPressedButtonID())
{
case MIDletProxy.DEVICE_KEY_UP:
case MIDletProxy.DEVICE_KEY_DOWN:
case MIDletProxy.DEVICE_KEY_LEFT:
case MIDletProxy.DEVICE_KEY_RIGHT:
case MIDletProxy.DEVICE_KEY_SELECT:
case MIDletProxy.DEVICE_KEY_SOFT1:
case MIDletProxy.DEVICE_KEY_SOFT2:
case MIDletProxy.DEVICE_KEY_1:
case MIDletProxy.DEVICE_KEY_2:
case MIDletProxy.DEVICE_KEY_3:
case MIDletProxy.DEVICE_KEY_4:
case MIDletProxy.DEVICE_KEY_5:
case MIDletProxy.DEVICE_KEY_6:
case MIDletProxy.DEVICE_KEY_7:
case MIDletProxy.DEVICE_KEY_8:
case MIDletProxy.DEVICE_KEY_9:
case MIDletProxy.DEVICE_KEY_STAR:
case MIDletProxy.DEVICE_KEY_0:
itemKeyDescription.setText(proxy.getKeyName(proxy.getKeyCodeFor(code)) +
"\nКод клавиши: " + Integer.toString(proxy.getKeyCodeFor(code)) +
"\nНазначение: посылает в приложение соответствующий код клавиши.");
break;
case MIDletProxy.DEVICE_KEY_POUND:
itemKeyDescription.setText(proxy.getKeyName(proxy.getKeyCodeFor(code)) +
"\nКод клавиши: " + Integer.toString(proxy.getKeyCodeFor(code)) +
"\nНазначение: посылает в приложение соответствующий код клавиши." +
"\nПримечание: эта клавиша позволяет полностью просмотреть выделенный " +
"элемент списка. Если на экране отображается стандартный список " +
"каких-нибудь элементов и среди них есть такие, которые заканчиваются " +
"на многоточие (…), выделите такой элемент и нажмите эту клавишу. Пока " +
"вы её удерживаете, на экране отображается полный текст выделенного " +
"элемента, без многоточия.");
break;
case MIDletProxy.DEVICE_KEY_CONSOLE:
itemKeyDescription.setText("Вызов консоли" +
"\nНазначение: вызов системной консоли " +
"(доступно только во время работы приложения).");
break;
case MIDletProxy.DEVICE_KEY_EXITAPP:
itemKeyDescription.setText("Выход из приложения" +
"\nНазначение: вызов диалога выхода из приложения " +
"(доступно только во время работы приложения).");
break;
default:
return;
}
itemKeyEquivalent.setText(MIDletProxy.getSystemKeyName(proxy.getKeyUsedAs(code)));
}
}
public void showStartScreen(Display display)
{
display.setCurrent(screenMIDlets);
}
public void showConsole(Display display)
{
if(display.isClientInForeground())
{
display.setCurrent(screenConsole);
}
}
public void showExitScreen(Display display)
{
if(display.isClientInForeground())
{
display.setCurrent(screenExit);
}
}
public void onMIDletStarted()
{
}
public void onMIDletDestroyed()
{
Run.getInstance().terminate();
}
public void onAppTerminate()
{
}
public void threadTerminated(Thread terminatedThread, Throwable exitThrowable)
{
if(exitThrowable == null)
{
return;
}
exitThrowable.printRealStackTrace();
MIDletProxy.getInstance().getEmulatorScreen().setCurrent(getScreenError(exitThrowable));
RecordStore.closeAllRecordStores();
}
public void onAboutImplementationScreenShow()
{
}
public void onSettingsScreenShow()
{
}
public void onSettingsUpdate(Displayable screen)
{
}
public void onSettingsApply(Displayable screen)
{
}
public void onSystemSettingsScreenShow()
{
}
public void onSystemSettingsUpdate()
{
}
public void onSystemSettingsApply()
{
}
public void startMIDlet(Class midletClass)
{
MIDletProxy.getInstance().getEmulatorScreen().setCurrent(
new LaunchScreen(this, midletClass));
}
public void stopMIDlet()
{
MIDletProxy.getInstance().stopMIDlet();
}
public void addConsoleCommand(ConsoleCommand command)
{
screenConsole.addConsoleCommand(command);
}
public void addThirdPartyLibraryInformation(String libraryNameAndJSR)
{
StringItem list;
if((list = itemLibraryList) == null)
{
throw new IllegalStateException("SystemGUI.addThirdPartyLibraryInformation: " +
"экран сведений о реализации ещё не создан.");
}
if(libraryNameAndJSR == null)
{
throw new NullPointerException("SystemGUI.addThirdPartyLibraryInformation: " +
"параметр libraryNameAndJSR равен нулевой ссылке.");
}
list.setText(list.getText() + "\n" + libraryNameAndJSR);
}
public void addSettingScreen(String label, Image icon, Displayable screen)
{
int len;
Displayable[] screens;
Choice settings;
if((screens = screensOfSettings) == null || (settings = screenSettings) == null)
{
throw new IllegalStateException("SystemGUI.addSettingScreen: " +
"экран настроек ещё не создан.");
}
if(label == null)
{
throw new NullPointerException("SystemGUI.addSettingScreen: " +
"параметр label равен нулевой ссылке.");
}
if(screen == null)
{
throw new NullPointerException("SystemGUI.addSettingScreen: " +
"параметр screen равен нулевой ссылке.");
}
if((len = settings.size() - 1) == screens.length)
{
Array.copyReferences(screens, 0,
screens = screensOfSettings = new Displayable[(len << 1) + 1], 0, len);
}
screens[len] = screen;
settings.insert(len, label, icon);
}
public int addSystemSetting(String label, String description, Image icon)
{
Choice list;
String text;
if((list = itemSystemSettings) == null)
{
throw new IllegalStateException("SystemGUI.addSystemSetting: " +
"экран настроек системы ещё не создан.");
}
if(label == null)
{
throw new NullPointerException("SystemGUI.addSystemSetting: " +
"параметр label равен нулевой ссылке.");
}
text = description == null ? label : label + "\n\n" + description;
return list.append(text, icon) - NATIVE_SYSTEM_SETTINGS;
}
public final void setSystemSetting(int index, boolean value)
{
Choice list;
if((list = itemSystemSettings) == null)
{
throw new IllegalStateException("SystemGUI.setSystemSetting: " +
"экран настроек системы ещё не создан.");
}
if((index += NATIVE_SYSTEM_SETTINGS) < NATIVE_SYSTEM_SETTINGS || index >= list.size())
{
throw new IndexOutOfBoundsException("SystemGUI.setSystemSetting: " +
"параметр index выходит из диапазона.");
}
list.setSelectedIndex(index, value);
}
public final boolean getSystemSetting(int index)
{
Choice list;
if((list = itemSystemSettings) == null)
{
throw new IllegalStateException("SystemGUI.getSystemSetting: " +
"экран настроек системы ещё не создан.");
}
if((index += NATIVE_SYSTEM_SETTINGS) < NATIVE_SYSTEM_SETTINGS || index >= list.size())
{
throw new IndexOutOfBoundsException("SystemGUI.getSystemSetting: " +
"параметр index выходит из диапазона.");
}
return list.isSelected(index);
}
public final String getMIDletName()
{
return midletName;
}
protected void prepareForStartMIDlet()
{
midletClassNames = null;
screensOfSettings = null;
midletName = null;
commandLaunch = null;
commandExit = null;
commandSettings = null;
commandAboutApplication = null;
commandAboutImplementation = null;
commandProperties = null;
commandDeleteAll = null;
commandDelete = null;
commandUpdate = null;
commandBack = null;
commandYes = null;
commandNo = null;
tickerLaunch = null;
tickerSettings = null;
itemFrequency = null;
itemModelSelect = null;
itemSystemSettings = null;
itemRecordName = null;
itemRecordSize = null;
itemRecordNumRecords = null;
itemRecordLastModified = null;
itemRecordVersion = null;
itemKeypad = null;
itemKeyDescription = null;
itemKeyEquivalent = null;
itemLibraryList = null;
screenMIDlets = null;
screenSettings = null;
screenSettingControl = null;
screenSettingKeyCodes = null;
screenSettingFonts = null;
screenSettingFrequency = null;
screenSettingSystem = null;
screenSettingRecords = null;
screenSettingKeypad = null;
screenRecordProperties = null;
screenRecordDelete = null;
screenRecordDeleteAll = null;
screenRecordDeletionError = null;
screenAboutApplication = null;
screenAboutImplementation = null;
}
private void launchSelectedMIDlet(Choice midletList)
{
if(midletStarted)
{
return;
}
midletStarted = true;
try
{
startMIDlet(Class.forName(midletClassNames[midletList.getSelectedIndex()]));
}
catch(Throwable cause)
{
cause.printRealStackTrace();
MIDletProxy.getInstance().getEmulatorScreen().setCurrent(getScreenError(cause));
}
}
private void showSelectedRecordProperties(Choice recordList, Display display)
{
Calendar lastModified = Calendar.getInstance();
Displayable screen = getScreenRecordProperties();
RecordStore record;
try
{
record = RecordStore.openRecordStore(
recordList.getString(recordList.getSelectedIndex()), false);
try
{
lastModified.setTime(new Date(record.getLastModified()));
itemRecordName.setText(record.getName());
itemRecordSize.setText(Integer.toString(record.getSize()).concat(" байт"));
itemRecordNumRecords.setText(Integer.toString(record.getNumRecords()));
itemRecordLastModified.setText(lastModified.toString());
itemRecordVersion.setText(Integer.toString(record.getVersion()));
}
finally
{
record.closeRecordStore();
}
}
catch(RecordStoreException e)
{
e.printRealStackTrace();
itemRecordName.setText("(Ошибка возникла при считывании свойств записи.)");
itemRecordSize.setText(null);
itemRecordNumRecords.setText(null);
itemRecordLastModified.setText(null);
itemRecordVersion.setText(null);
}
display.setCurrent(screen);
}
private void showSelectedRecordDeleteDialog(Choice recordList, Display display)
{
Displayable screen = getScreenRecordDelete();
screenRecordDelete.setString(
"Осторожно: удаление одной записи может привести к ошибкам в работе приложения. " +
"Удаляйте записи только если уверены, что всё делаете правильно. Удалить запись " +
recordList.getString(recordList.getSelectedIndex()) + "?");
display.setCurrent(screen);
}
private void deleteSelectedRecord(Display display)
{
List list;
try
{
RecordStore.deleteRecordStore(
(list = screenSettingRecords).getString(list.getSelectedIndex()));
updateRecordList();
display.setCurrent(list);
}
catch(RecordStoreException e)
{
e.printRealStackTrace();
display.setCurrent(getScreenRecordDeletionError());
}
}
private void deleteAllRecords(Display display)
{
int i;
String[] list;
try
{
for(i = (list = RecordStore.listRecordStores()) == null ? 0 : list.length; i-- > 0; )
{
RecordStore.deleteRecordStore(list[i]);
}
updateRecordList();
display.setCurrent(screenSettingRecords);
}
catch(RecordStoreException e)
{
e.printRealStackTrace();
display.setCurrent(getScreenRecordDeletionError());
}
}
private void createSettingsScreens()
{
this.screensOfSettings = new Displayable[] {
getScreenSettingControl(),
getScreenSettingKeyCodes(),
getScreenSettingFonts(),
getScreenSettingFrequency(),
getScreenSettingSystem(),
getScreenSettingRecords(),
getScreenSettingKeypad()
};
}
private void applySettingsFromScreen(int screenIndex)
{
MIDletProxy proxy = MIDletProxy.getInstance();
switch(screenIndex)
{
default:
onSettingsApply(screensOfSettings[screenIndex]);
/* fall through */
case 5:
case 6:
return;
case 0:
{
int i;
int key;
int[] keys = KEYS;
int[] deviceKeys = DEVICE_KEYS;
Form form = screenSettingControl;
for(i = deviceKeys.length; i-- > 0; )
{
if((key = keys[((Choice) form.get(i)).getSelectedIndex()]) == 0)
{
continue;
}
proxy.setKeyUsedAs(deviceKeys[i], key);
}
}
return;
case 1:
{
int i;
int keyCode;
int[] deviceKeys = DEVICE_KEYS;
Form form = screenSettingKeyCodes;
String representation;
for(i = SETTABLE_KEY_CODES; i-- > 0; )
{
if((representation = ((Input) form.get(i + 1)).getString()) == null ||
representation.length() <= 0 ||
(keyCode = Integer.parseInt(representation)) == 0)
{
continue;
}
proxy.setKeyCodeFor(deviceKeys[i], keyCode);
}
}
return;
case 2:
{
int i;
Form form;
for(i = (form = screenSettingFonts).size(); i-- > 0; )
{
proxy.setFont(toFontSize(i >> 2), i & 0x03, RasterFont.getRasterFontAtIndex(
((Choice) form.get(i)).getSelectedIndex()));
}
}
return;
case 3:
proxy.setMaximumFrequency(Math.max(itemFrequency.getValue(), 1));
return;
case 4:
{
Choice list = itemSystemSettings;
proxy.setEnableStackTrace(list.isSelected(0));
proxy.setKeyRepeatedEvent(list.isSelected(1));
proxy.setSerializeRepaint(list.isSelected(2));
onSystemSettingsApply();
}
return;
}
}
private void updateSettingsScreen(int screenIndex)
{
MIDletProxy proxy = MIDletProxy.getInstance();
switch(screenIndex)
{
default:
onSettingsUpdate(screensOfSettings[screenIndex]);
/* fall through */
case 6:
return;
case 0:
{
int i;
int[] deviceKeys = DEVICE_KEYS;
Form form = screenSettingControl;
for(i = deviceKeys.length; i-- > 0; )
{
((Choice) form.get(i)).setSelectedIndex(
indexOfKey(proxy.getKeyUsedAs(deviceKeys[i])), true);
}
}
return;
case 1:
{
int i;
int[] deviceKeys = DEVICE_KEYS;
Form form = screenSettingKeyCodes;
itemModelSelect.setSelectedIndex(0, true);
for(i = SETTABLE_KEY_CODES; i-- > 0; )
{
((Input) form.get(i + 1)).setString(
Integer.toString(proxy.getKeyCodeFor(deviceKeys[i])));
}
}
return;
case 2:
{
int i;
Form form;
for(i = (form = screenSettingFonts).size(); i-- > 0; )
{
((Choice) form.get(i)).setSelectedIndex(
indexOfFont(proxy.getFont(toFontSize(i >> 2), i & 0x03)), true);
}
}
return;
case 3:
itemFrequency.setValue(proxy.getMaximumFrequency());
case 4:
{
Choice list = itemSystemSettings;
list.setSelectedIndex(0, proxy.isEnableStackTrace());
list.setSelectedIndex(1, proxy.isKeyRepeatedEvent());
list.setSelectedIndex(2, proxy.isSerializeRepaint());
onSystemSettingsUpdate();
}
return;
case 5:
updateRecordList();
return;
}
}
private void updateRecordList()
{
int i;
int len;
int sel;
String[] records;
String rec;
Command cmd1;
Command cmd2;
List list = screenSettingRecords;
len = (records = RecordStore.listRecordStores()) == null ? 0 : records.length;
sel = list.getSelectedIndex();
list.deleteAll();
list.removeCommand(cmd1 = getCommandDelete());
list.removeCommand(cmd2 = getCommandDeleteAll());
for(i = 0; i < len; i++)
{
list.append((rec = records[i]) == null ? "" : rec, null);
if(i == 0)
{
list.addCommand(cmd1);
list.addCommand(cmd2);
}
}
if(sel >= 0 && --len >= 0)
{
list.setSelectedIndex(Math.min(sel, len), true);
}
}
private Command getCommandLaunch()
{
Command result;
if((result = commandLaunch) == null)
{
result = commandLaunch = new Command("Запустить",
Command.OK, 0);
}
return result;
}
private Command getCommandExit()
{
Command result;
if((result = commandExit) == null)
{
result = commandExit = new Command("Выход",
Command.EXIT, 0);
}
return result;
}
private Command getCommandSettings()
{
Command result;
if((result = commandSettings) == null)
{
result = commandSettings = new Command("Настройки",
Command.SCREEN, 0);
}
return result;
}
private Command getCommandAboutApplication()
{
Command result;
if((result = commandAboutApplication) == null)
{
result = commandAboutApplication = new Command("О приложении",
Command.SCREEN, 0);
}
return result;
}
private Command getCommandAboutImplementation()
{
Command result;
if((result = commandAboutImplementation) == null)
{
result = commandAboutImplementation = new Command("Об этой реализации J2ME",
Command.SCREEN, 0);
}
return result;
}
private Command getCommandBack()
{
Command result;
if((result = commandBack) == null)
{
result = commandBack = new Command("Назад",
Command.BACK, 0);
}
return result;
}
private Command getCommandYes()
{
Command result;
if((result = commandYes) == null)
{
result = commandYes = new Command(YES,
Command.OK, 0);
}
return result;
}
private Command getCommandNo()
{
Command result;
if((result = commandNo) == null)
{
result = commandNo = new Command(NO,
Command.BACK, 0);
}
return result;
}
private Command getCommandProperties()
{
Command result;
if((result = commandProperties) == null)
{
result = commandProperties = new Command("Свойства",
Command.OK, 0);
}
return result;
}
private Command getCommandDeleteAll()
{
Command result;
if((result = commandDeleteAll) == null)
{
result = commandDeleteAll = new Command("Удалить все",
Command.SCREEN, 0);
}
return result;
}
private Command getCommandDelete()
{
Command result;
if((result = commandDelete) == null)
{
result = commandDelete = new Command("Удалить",
Command.SCREEN, 0);
}
return result;
}
private Command getCommandUpdate()
{
Command result;
if((result = commandUpdate) == null)
{
result = commandUpdate = new Command("Обновить",
Command.SCREEN, 0);
}
return result;
}
private Ticker getTickerLaunch()
{
Ticker result;
if((result = tickerLaunch) == null)
{
result = tickerLaunch = new Ticker(
"Выберите приложение и нажмите кнопку «Запустить». Если приложение запущено " +
"впервые (после установки), нажмите кнопку «Меню» и выберите пункт " +
"«Настройки».");
}
return result;
}
private Ticker getTickerSettings()
{
Ticker result;
if((result = tickerSettings) == null)
{
result = tickerSettings = new Ticker(
"Это настройки приложения. ВАЖНО: не забудьте сохранить настройки. " +
"Настройки шрифтов применяются только после перезапуска программы.");
}
return result;
}
private List getScreenMIDlets()
{
Command[] commands;
List result;
if((result = screenMIDlets) == null)
{
commands = new Command[] {
getCommandExit(), getCommandSettings(),
getCommandAboutApplication(), getCommandAboutImplementation()
};
result = screenMIDlets = new List(false,
null, getTickerLaunch(), commands, getCommandLaunch(), this,
Choice.IMPLICIT, new String[0], null, "(приложений нет)");
}
return result;
}
private List getScreenSettings()
{
String[] elements;
Command[] commands;
List result;
if((result = screenSettings) == null)
{
Run.getInstance().showMessage("Загрузка настроек…");
elements = new String[] {
"Управление", "Коды клавиш", "Шрифты", "Частота обновления экрана",
"Система", "Записи", "Показать клавиатуру", "Сохранить настройки"
};
commands = new Command[] {
getCommandBack()
};
result = screenSettings = new List(false,
"Настройки", getTickerSettings(), commands, List.SELECT_COMMAND, this,
Choice.IMPLICIT, elements, null);
createSettingsScreens();
onSettingsScreenShow();
}
return result;
}
private Displayable getScreenSettingControl()
{
int i;
int w;
int len;
int key;
int[] k;
Item[] items;
String[] elements;
Command[] commands;
MIDletProxy proxy;
String keyName;
Form result;
if((result = screenSettingControl) == null)
{
(elements = new String[i = (k = KEYS).length])[0] = "Свои настройки";
for(; i-- > 1; elements[i] = MIDletProxy.getSystemKeyName(k[i]));
items = new Item[len = (k = DEVICE_KEYS).length];
proxy = MIDletProxy.getInstance();
for(i = len; i-- > 0; )
{
switch(key = k[i])
{
case MIDletProxy.DEVICE_KEY_CONSOLE:
keyName = "Вызов консоли";
break;
case MIDletProxy.DEVICE_KEY_EXITAPP:
keyName = "Выход из приложения";
break;
default:
keyName = proxy.getKeyName(proxy.getKeyCodeFor(key));
break;
}
items[i] = new ChoiceGroup(Item.LAYOUT_NEWLINE_BEFORE, keyName, null, null,
Choice.POPUP, elements, null);
}
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, APPLY_SETTINGS_COMMAND
};
result = screenSettingControl = new FormSettings("Управление", null, commands, this,
"Здесь можно задать соответствие между клавишами виртуального устройства и " +
"клавишами компьютера.\nВАЖНО: следите, чтобы в разных полях были разные " +
"названия клавиш компьютера, так как программа этого не проверяет.\n" +
"Расшифровка непонятных названий клавиш компьютера:\n SPACE – пробел\n" +
" UP – \u2191\n DOWN – \u2193\n LEFT – \u2190\n RIGHT – \u2192\n" +
" NUM_PLUS – Num +\n NUM_MINUS – Num -\n NUM_STAR – Num *\n" +
" NUM_DIVIDE – Num /\n NUM_DECIMAL – Num .\nОпция «Свои настройки» не " +
"изменяет соответствующую клавишу при нажатии кнопки «Применить», оставляя " +
"ту клавишу, которая была задана раннее. Эта опция была специально создана " +
"на случай, когда файл настроек /midlet.properties редактировался вручную.",
items, this, null);
w = result.getWidth();
for(i = len; i-- > 0; items[i].setPreferredSize(w, -1));
}
return result;
}
private Displayable getScreenSettingKeyCodes()
{
int i;
int w;
int len;
int[] deviceKeys;
Item[] items;
String[] elements;
Command[] commands;
KeyCodeSet[] sets;
MIDletProxy proxy;
Form result;
if((result = screenSettingKeyCodes) == null)
{
deviceKeys = DEVICE_KEYS;
elements = new String[len = (sets = KEY_CODE_SETS).length];
for(i = len; i-- > 0; elements[i] = sets[i].getName());
items = new Item[len = SETTABLE_KEY_CODES + 1];
proxy = MIDletProxy.getInstance();
items[0] = itemModelSelect = new ChoiceGroup(
Item.LAYOUT_NEWLINE_BEFORE, "Предустановки", null, null, Choice.POPUP,
elements, null);
for(i = SETTABLE_KEY_CODES; i-- > 0; )
{
items[i + 1] = new TextField(Item.LAYOUT_NEWLINE_BEFORE, -1,
proxy.getKeyName(proxy.getKeyCodeFor(deviceKeys[i])), null, null, null,
"", 12, Input.NUMERIC);
}
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, APPLY_SETTINGS_COMMAND
};
result = screenSettingKeyCodes = new FormSettings("Коды клавиш", null, commands, this,
"Здесь можно задать коды тех клавиш, которые не были предусмотрены " +
"спецификацией MIDP, в результате чего коды этих клавиш стали зависимыми от " +
"конкретных моделей устройств. Особенно это касается тех приложений, " +
"которые работают только на устройствах определённых моделей. Вы можете " +
"задать особые числовые коды для клавиш или выбрать предустановленные коды " +
"клавиш для некоторых моделей устройств.",
items, this, this);
w = result.getWidth();
for(i = len; i-- > 0; items[i].setPreferredSize(w, -1));
}
return result;
}
private Displayable getScreenSettingFonts()
{
int i;
int j;
int w;
int len;
int rcnt;
Item[] items;
String[] fontTypes;
String[] elements;
Command[] commands;
ChoiceGroup list;
Form result;
if((result = screenSettingFonts) == null)
{
fontTypes = new String[] {
"Мелкий нормальный", "Мелкий жирный",
"Мелкий курсив", "Мелкий жирный курсив",
"Средний нормальный", "Средний жирный",
"Средний курсив", "Средний жирный курсив",
"Крупный нормальный", "Крупный жирный",
"Крупный курсив", "Крупный жирный курсив"
};
elements = new String[rcnt = RasterFont.getRasterFontsCount()];
for(i = rcnt; i-- > 0; )
{
elements[i] = RasterFont.getRasterFontAtIndex(i).getName();
}
items = new Item[len = fontTypes.length];
for(i = len; i-- > 0; )
{
items[i] = list = new ChoiceGroup(Item.LAYOUT_NEWLINE_BEFORE, fontTypes[i],
null, null, Choice.POPUP, elements, null);
for(j = rcnt; j-- > 0; )
{
list.setFont(j, Font.getRasterFont(j));
}
}
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, APPLY_SETTINGS_COMMAND
};
result = screenSettingFonts = new FormSettings("Шрифты", null, commands, this,
"Здесь можно задать шрифты, которые приложение будет использовать для " +
"вывода текста.\nНастройки шрифтов вступят в силу только после перезапуска " +
"программы.",
items, this, null);
w = result.getWidth();
for(i = len; i-- > 0; items[i].setPreferredSize(w, -1));
}
return result;
}
private Displayable getScreenSettingFrequency()
{
Item[] items;
Command[] commands;
Form result;
if((result = screenSettingFrequency) == null)
{
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, APPLY_SETTINGS_COMMAND
};
items = new Item[] {
itemFrequency = new Gauge(Item.LAYOUT_DEFAULT, -1, -1, "Максимум кадров в секунду",
null, null, this, true, 100, 25)
};
result = new FormSettings("Частота обновления экрана", null, commands, this,
"Здесь можно задать максимальную частоту обновления экрана (максимум кадров в секунду). " +
"Рекомендуемое значение – 25 кадров в секунду. Большие значения (> 50) могут привести к " +
"«подвисанию» некоторых программ.",
items, this, this);
}
return result;
}
private Displayable getScreenSettingSystem()
{
Item[] items;
String[] elements;
Command[] commands;
Form result;
if((result = screenSettingSystem) == null)
{
elements = new String[] {
"Трассировка стека в исключениях\n\n" +
"Отключите эту опцию, если приложение работает с ошибками и " +
"генерирует много исключений, увеличивая размер файла /err.txt. " +
"В противном случае эту опцию рекомендуется включить (для " +
"отслеживания ошибок в программе).",
"Вызов метода Canvas.keyRepeated(int)\n\n" +
"Изменение состояния этого флага может привести к изменению " +
"поведения приложения в тот момент, когда вы удерживаете нажатой " +
"какую-нибудь клавишу. Установите или снимите этот флаг в " +
"соответствии с вашими предпочтениями.",
"Вызов метода Canvas.paint(Graphics) в порядке общей очереди событий\n\n" +
"Подавляющее большинство приложений требуют установки этого флага. " +
"Если, по вашему мнению, приложение не рисует некоторые кадры " +
"анимации, попробуйте снять этот флаг. Если поведение приложения " +
"при этом не изменится или приложение будет работать с ошибками, " +
"снова установите этот флаг."
};
items = new Item[] {
itemSystemSettings = new ChoiceGroup(Item.LAYOUT_DEFAULT, "Поведение системы",
null, null, Choice.MULTIPLE, elements, null)
};
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, APPLY_SETTINGS_COMMAND
};
result = screenSettingSystem = new FormSettings("Система", null, commands, this,
"Здесь можно изменить поведение системы, устанавливая или снимая флаги. " +
"Выделите опцию, затем нажмите и удерживайте клавишу #, чтобы увидеть " +
"полное описание выбранной опции.",
items, this, null);
items[0].setPreferredSize(result.getWidth(), -1);
onSystemSettingsScreenShow();
}
return result;
}
private Displayable getScreenSettingRecords()
{
Command[] commands;
List result;
if((result = screenSettingRecords) == null)
{
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND, getCommandUpdate()
};
result = screenSettingRecords = new List(false,
"Записи", null, commands, getCommandProperties(), this,
Choice.IMPLICIT, new String[0], null, "(записей нет)");
}
return result;
}
private Displayable getScreenSettingKeypad()
{
int devkey;
int left;
int top;
int width;
int height;
Item[] items;
Command[] commands;
FileInputStream stream;
DataInputStream data;
ButtonSet keypad;
Form result;
if((result = screenSettingKeypad) == null)
{
items = new Item[] {
itemKeypad = keypad = new ButtonSet(Item.LAYOUT_CENTER |
Item.LAYOUT_NEWLINE_AFTER, null, loadImage("/ui/keypad.png")),
itemKeyDescription = new StringItem(Item.LAYOUT_DEFAULT |
Item.LAYOUT_NEWLINE_AFTER, -1, -1, "Описание", null, null, null,
"Укажите клавишу на этой виртуальной клавиатуре, чтобы увидеть её " +
"описание здесь.", null, Item.PLAIN),
itemKeyEquivalent = new StringItem(Item.LAYOUT_DEFAULT, -1, -1,
"Эквивалентная клавиша", null, null, null,
"(клавиша не выбрана)", null, Item.PLAIN)
};
try
{
(stream = new FileInputStream("/ui/keypad.dat")).checkOpenError();
try
{
for(data = new DataInputStream(stream); data.available() >= 5; )
{
devkey = data.readUnsignedByte();
left = data.readUnsignedByte();
top = data.readUnsignedByte();
width = data.readUnsignedByte();
height = data.readUnsignedByte();
keypad.addButton(devkey, left, top, width, height);
}
}
finally
{
stream.close();
}
}
catch(IOException e)
{
e.printRealStackTrace();
}
commands = new Command[] {
BACK_TO_SETTINGS_COMMAND
};
result = screenSettingKeypad = new Form("Внешний вид клавиатуры", null, commands, this, items, this);
}
return result;
}
private Displayable getScreenRecordProperties()
{
Item[] items;
Command[] commands;
Form result;
if((result = screenRecordProperties) == null)
{
items = new Item[] {
itemRecordName = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Название", null, null, null, null, null, Item.PLAIN),
itemRecordSize = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Размер", null, null, null, null, null, Item.PLAIN),
itemRecordNumRecords = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Количество подзаписей", null, null, null, null, null, Item.PLAIN),
itemRecordLastModified = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Последнее изменение", null, null, null, null, null, Item.PLAIN),
itemRecordVersion = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Количество изменений", null, null, null, null, null, Item.PLAIN),
};
commands = new Command[] {
getCommandBack()
};
result = screenRecordProperties = new Form("Свойства записи", null, commands, this, items, null);
}
return result;
}
private Displayable getScreenRecordDelete()
{
Command[] commands;
Alert result;
if((result = screenRecordDelete) == null)
{
commands = new Command[] {
getCommandNo()
};
result = screenRecordDelete = new Alert("Удалить", null, commands, getCommandYes(), this,
null, null, AlertType.WARNING, null);
}
return result;
}
private Displayable getScreenRecordDeleteAll()
{
Command[] commands;
Alert result;
if((result = screenRecordDeleteAll) == null)
{
commands = new Command[] {
getCommandNo()
};
result = screenRecordDeleteAll = new Alert("Удалить все", null, commands, getCommandYes(), this,
"Удаление всех записей приведёт приложение к состоянию, в котором оно " +
"находилось сразу после установки. Удалить все записи?",
null, AlertType.CONFIRMATION, null);
}
return result;
}
private Displayable getScreenRecordDeletionError()
{
Alert result;
if((result = screenRecordDeletionError) == null)
{
result = screenRecordDeletionError = new Alert("Ошибка", null, null, Alert.DISMISS_COMMAND, this,
"Ошибка возникла при удалении записи.", null, AlertType.ERROR, null);
}
return result;
}
private Displayable getScreenAboutApplication()
{
int i;
int len;
Item[] items;
String[] list;
Command[] commands;
StringBuffer classNames;
AttributableMappedTextDecoder descriptor;
Form result;
if((result = screenAboutApplication) == null)
{
descriptor = MIDletProxy.getInstance().getMIDletDescriptor();
len = (list = midletClassNames).length - 1;
classNames = new StringBuffer();
for(i = 0; i <= len; i++)
{
classNames.append(list[i]);
if(i < len)
{
classNames.append('\n');
}
}
items = new Item[] {
new ImageItem(Item.LAYOUT_NEWLINE_AFTER, null, null, null, null,
loadMIDletIcon(descriptor), null, Item.PLAIN),
new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1, null, null, null, null,
midletName + "\nВерсия: " + descriptor.get("MIDlet-Version") +
"\nПоставщик: " + descriptor.get("MIDlet-Vendor") +
"\nПрофиль: " + descriptor.get("MicroEdition-Profile") +
"\nКонфигурация: " + descriptor.get("MicroEdition-Configuration"),
Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM),
Item.PLAIN),
new StringItem(Item.LAYOUT_DEFAULT, -1, -1, "Класс мидлета", null, null, null,
classNames.toString(),
Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL),
Item.PLAIN)
};
commands = new Command[] {
getCommandBack()
};
result = screenAboutApplication = new Form("О приложении", null, commands, this, items, null);
}
return result;
}
private Displayable getScreenAboutImplementation()
{
Item[] items;
Command[] commands;
Font font;
Form result;
if((result = screenAboutImplementation) == null)
{
font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
items = new Item[] {
new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1, null, null, null, null,
"Реализация спецификации Mobile Information Device Profile для " +
"Малик Эмулятора от Малик Разработчика" +
"\nВерсия: " + System.getProperty("software.version") +
"\nПрофиль: " + System.getProperty("microedition.profiles") +
"\nКонфигурация: " + System.getProperty("microedition.configuration"),
Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM),
Item.PLAIN),
itemLibraryList = new StringItem(Item.LAYOUT_NEWLINE_AFTER, -1, -1,
"Поддержка интерфейсов программирования приложений", null, null, null,
"MIDP 2.1 (JSR-120)\nMMAPI 1.2 (JSR-135)\nWMA 1.1 (JSR-118)",
font, Item.PLAIN),
new StringItem(Item.LAYOUT_DEFAULT, -1, -1, "Важные классы", null, null, null,
MIDletProxy.getInstance().getClass().getCanonicalName() + "\n" +
this.getClass().getCanonicalName(), font, Item.PLAIN),
new StringItem(Item.LAYOUT_DEFAULT, -1, -1, "Лицензии", null, null, null,
"GNU LGPL 3\nZLib", font, Item.PLAIN)
};
commands = new Command[] {
getCommandBack()
};
result = screenAboutImplementation = new Form("Об этой реализации J2ME", null, commands, this, items, null);
onAboutImplementationScreenShow();
}
return result;
}
private Displayable getScreenError(Throwable cause)
{
Item[] items;
Command[] commands;
String message;
String text;
String name;
Form result;
name = cause.getClass().getCanonicalName();
text = (message = cause.getRealMessage()) == null ? name : message + "\n\n– " + name;
if((result = screenError) == null)
{
items = new Item[] {
new StringItem(Item.LAYOUT_DEFAULT, -1, -1, null, null, null, null, text,
Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL),
Item.PLAIN)
};
commands = new Command[] {
getCommandExit()
};
result = screenError = new Form("Ошибка приложения", null, commands, this, items, null);
} else
{
((StringItem) result.get(0)).setText(text);
}
return result;
}
private Displayable getScreenExit()
{
Command[] commands;
Alert result;
if((result = screenExit) == null)
{
commands = new Command[] {
getCommandNo()
};
result = screenExit = new Alert("Выход из приложения", null, commands, getCommandYes(), this,
"Выйти из приложения " + midletName + "?\nВсе несохранённые данные будут потеряны.",
null, AlertType.WARNING, null);
}
return result;
}
}