Introducing the main window, yet more tweaks to localization support
This commit is contained in:
parent
7c7a52c113
commit
73c8245eff
BIN
Main.class
BIN
Main.class
Binary file not shown.
BIN
app/App.class
BIN
app/App.class
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 220 B |
|
@ -6,6 +6,7 @@ locale {
|
||||||
|
|
||||||
# Main window
|
# Main window
|
||||||
app {
|
app {
|
||||||
|
|
||||||
title {
|
title {
|
||||||
default PVB Emulator
|
default PVB Emulator
|
||||||
mixed {ctrl.number} {ctrl.filename} - {app.title.default}
|
mixed {ctrl.number} {ctrl.filename} - {app.title.default}
|
||||||
|
@ -16,6 +17,7 @@ app {
|
||||||
file {
|
file {
|
||||||
(menu) File
|
(menu) File
|
||||||
load_rom Load ROM...
|
load_rom Load ROM...
|
||||||
|
new_window New window
|
||||||
exit Exit
|
exit Exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,3 +32,11 @@ core {
|
||||||
windows-x86 Windows (32-bit)
|
windows-x86 Windows (32-bit)
|
||||||
windows-x86_64 Windows (64-bit)
|
windows-x86_64 Windows (64-bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# File dialog
|
||||||
|
dialog {
|
||||||
|
load Load
|
||||||
|
load_rom Load ROM
|
||||||
|
load_rom_error Unable to load the selected ROM file.
|
||||||
|
load_rom_notvb The selected file does not appear to be a Virtual Boy ROM.
|
||||||
|
}
|
||||||
|
|
2
makefile
2
makefile
|
@ -84,7 +84,7 @@ pack:
|
||||||
$(eval jarname = "pvbemu_`date +%Y%m%d`.jar")
|
$(eval jarname = "pvbemu_`date +%Y%m%d`.jar")
|
||||||
@echo " Bundling into $(jarname)"
|
@echo " Bundling into $(jarname)"
|
||||||
@jar -cfe $(jarname) Main *.class \
|
@jar -cfe $(jarname) Main *.class \
|
||||||
app locale native src util vue makefile license.txt
|
app images locale native src util vue makefile license.txt
|
||||||
|
|
||||||
# Delete only Java .class files
|
# Delete only Java .class files
|
||||||
.PHONY: clean_desktop
|
.PHONY: clean_desktop
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class App {
|
||||||
// Instance fields
|
// Instance fields
|
||||||
private Localizer.Locale[] locales; // Language translations
|
private Localizer.Locale[] locales; // Language translations
|
||||||
private Localizer localizer; // UI localization manager
|
private Localizer localizer; // UI localization manager
|
||||||
|
private ArrayList<Window> windows; // Application windows
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,41 +25,55 @@ public class App {
|
||||||
|
|
||||||
// Instance fields
|
// Instance fields
|
||||||
localizer = new Localizer();
|
localizer = new Localizer();
|
||||||
|
windows = new ArrayList<Window>();
|
||||||
|
|
||||||
// Additional processing
|
// Additional processing
|
||||||
initLocales();
|
initLocales();
|
||||||
|
addWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Public Methods //
|
// Package Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Associate a control with the localizer
|
// Add a new program window
|
||||||
public boolean addControl(Object control, Object key) {
|
void addWindow() {
|
||||||
return localizer.add(control, key);
|
windows.add(new Window(this));
|
||||||
|
windowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the currently active locale
|
// Retrieve the currently active locale
|
||||||
public Localizer.Locale getLocale() {
|
Localizer.Locale getLocale() {
|
||||||
return localizer.getLocale();
|
return localizer.getLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve the localization manager
|
||||||
|
Localizer getLocalizer() {
|
||||||
|
return localizer;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve a list of registered locales
|
// Retrieve a list of registered locales
|
||||||
public Localizer.Locale[] listLocales() {
|
Localizer.Locale[] listLocales() {
|
||||||
var ret = new Localizer.Locale[locales.length];
|
var ret = new Localizer.Locale[locales.length];
|
||||||
System.arraycopy(locales, 0, ret, 0, locales.length);
|
System.arraycopy(locales, 0, ret, 0, locales.length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a control from the localizer
|
// Determine the number of a window in the collection
|
||||||
public boolean removeControl(Object control) {
|
int numberOf(Window window) {
|
||||||
return localizer.remove(control);
|
return windows.indexOf(window) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a program window
|
||||||
|
void removeWindow(Window window) {
|
||||||
|
windows.remove(window);
|
||||||
|
windowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify a new locale
|
// Specify a new locale
|
||||||
public void setLocale(Localizer.Locale locale) {
|
void setLocale(Localizer.Locale locale) {
|
||||||
localizer.setLocale(locale);
|
localizer.setLocale(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,4 +125,11 @@ public class App {
|
||||||
localizer.setLocale(locale != null ? locale : this.locales[0]);
|
localizer.setLocale(locale != null ? locale : this.locales[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A window has been added to or removed from the program state
|
||||||
|
private void windowsChanged() {
|
||||||
|
int count = windows.size();
|
||||||
|
for (int x = 0; x < count; x++)
|
||||||
|
windows.get(x).windowsChanged(x + 1, count == 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
package app;
|
||||||
|
|
||||||
|
// Java imports
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.*;
|
||||||
|
import java.io.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.filechooser.*;
|
||||||
|
|
||||||
|
// Project imports
|
||||||
|
import util.*;
|
||||||
|
|
||||||
|
// Main application window
|
||||||
|
class Window extends JFrame {
|
||||||
|
|
||||||
|
// Instance fields
|
||||||
|
private App app; // Containing application
|
||||||
|
private int number; // Window number within application
|
||||||
|
private boolean only; // This is the only application window
|
||||||
|
private File romFile; // Currently loaded ROM file
|
||||||
|
|
||||||
|
// UI components
|
||||||
|
private File pwd; // Most recent working directory
|
||||||
|
private JPanel video; // Video output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constants //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Application icon
|
||||||
|
private static final BufferedImage APPICON;
|
||||||
|
|
||||||
|
// Static initializer
|
||||||
|
static {
|
||||||
|
APPICON = Util.imageRead("images/app_icon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
Window(App app) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Configure instance fields
|
||||||
|
this.app = app;
|
||||||
|
|
||||||
|
// Configure video pane
|
||||||
|
video = new JPanel() {
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
onPaintVideo((Graphics2D) g, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
video.setPreferredSize(new Dimension(384, 224));
|
||||||
|
|
||||||
|
// Configure window
|
||||||
|
addWindowListener(Util.onClose(e->onClose()));
|
||||||
|
setContentPane(video);
|
||||||
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
|
setIconImage(APPICON);
|
||||||
|
setJMenuBar(initMenus());
|
||||||
|
app.getLocalizer().add(this, "app.title.default");
|
||||||
|
|
||||||
|
// Display window
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Menu Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Produce the window's menu bar
|
||||||
|
private JMenuBar initMenus() {
|
||||||
|
var bar = new JMenuBar();
|
||||||
|
var loc = app.getLocalizer();
|
||||||
|
bar.setBorder(null);
|
||||||
|
bar.add(initMenuFile(loc));
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the File menu
|
||||||
|
private JMenu initMenuFile(Localizer loc) {
|
||||||
|
var mnuFile = new JMenu();
|
||||||
|
loc.add(mnuFile, "app.file.(menu)");
|
||||||
|
|
||||||
|
var mnuFileLoadRom = new JMenuItem();
|
||||||
|
loc.add(mnuFileLoadRom, "app.file.load_rom");
|
||||||
|
mnuFileLoadRom.addActionListener(e->onLoadROM());
|
||||||
|
mnuFile.add(mnuFileLoadRom);
|
||||||
|
|
||||||
|
mnuFile.addSeparator();
|
||||||
|
|
||||||
|
var mnuFileNewWindow = new JMenuItem();
|
||||||
|
loc.add(mnuFileNewWindow, "app.file.new_window");
|
||||||
|
mnuFileNewWindow.addActionListener(e->onNewWindow());
|
||||||
|
mnuFile.add(mnuFileNewWindow);
|
||||||
|
|
||||||
|
var mnuFileExit = new JMenuItem();
|
||||||
|
loc.add(mnuFileExit, "app.file.exit");
|
||||||
|
mnuFileExit.addActionListener(e->onClose());
|
||||||
|
mnuFile.add(mnuFileExit);
|
||||||
|
|
||||||
|
return mnuFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Package Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// A window has been added to or removed from the program state
|
||||||
|
void windowsChanged(int number, boolean only) {
|
||||||
|
this.number = number;
|
||||||
|
this.only = only;
|
||||||
|
app.getLocalizer().put(this, "ctrl.number", "" + number);
|
||||||
|
updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Window close, File -> Exit
|
||||||
|
private void onClose() {
|
||||||
|
app.removeWindow(this);
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// File -> Load ROM
|
||||||
|
private void onLoadROM() {
|
||||||
|
var loc = app.getLocalizer();
|
||||||
|
|
||||||
|
// Prompt the user to select a file
|
||||||
|
var dlgFile = new JFileChooser(pwd);
|
||||||
|
dlgFile.addChoosableFileFilter(new FileNameExtensionFilter(
|
||||||
|
"Virtual Boy ROMs (*.vb)", "vb"));
|
||||||
|
dlgFile.addChoosableFileFilter(new FileNameExtensionFilter(
|
||||||
|
"ISX modules (*.isx)", "isx"));
|
||||||
|
dlgFile.setAcceptAllFileFilterUsed(true);
|
||||||
|
dlgFile.setDialogTitle(loc.get("dialog.load_rom"));
|
||||||
|
int option = dlgFile.showDialog(this, loc.get("dialog.load"));
|
||||||
|
|
||||||
|
// The user did not select a file
|
||||||
|
var file = dlgFile.getSelectedFile();
|
||||||
|
if (option != JFileChooser.APPROVE_OPTION || file == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Update the current directory
|
||||||
|
pwd = file.getParentFile();
|
||||||
|
|
||||||
|
// Attempt to load the ROM file
|
||||||
|
var data = Util.fileRead(file);
|
||||||
|
if (data == null) {
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
loc.get("dialog.load_rom_error"),
|
||||||
|
loc.get("dialog.load_rom"),
|
||||||
|
JOptionPane.ERROR_MESSAGE
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the emulation state
|
||||||
|
romFile = file;
|
||||||
|
loc.put(this, "ctrl.filename", file.getName());
|
||||||
|
updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// File -> New window
|
||||||
|
private void onNewWindow() {
|
||||||
|
app.addWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Video paint
|
||||||
|
private void onPaintVideo(Graphics2D g, int width, int height) {
|
||||||
|
int scale = Math.max(1, Math.min(width / 384, height / 224));
|
||||||
|
|
||||||
|
g.translate(
|
||||||
|
Math.max(0, (width - scale * 384) / 2),
|
||||||
|
Math.max(0, (height - scale * 224) / 2)
|
||||||
|
);
|
||||||
|
g.scale(scale, scale);
|
||||||
|
|
||||||
|
g.setColor(Color.black);
|
||||||
|
g.fillRect(0, 0, 384, 224);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Update the window title
|
||||||
|
private void updateTitle() {
|
||||||
|
app.getLocalizer().add(this,
|
||||||
|
only ? romFile != null ?
|
||||||
|
"app.title.rom" :
|
||||||
|
"app.title.default"
|
||||||
|
: romFile != null ?
|
||||||
|
"app.title.mixed" :
|
||||||
|
"app.title.number"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,9 +10,8 @@ import javax.swing.text.*;
|
||||||
public class Localizer {
|
public class Localizer {
|
||||||
|
|
||||||
// Instance fields
|
// Instance fields
|
||||||
private HashMap<Object, Object> controls; // Control mapping
|
private HashMap<Object, Control> controls; // Control mapping
|
||||||
private Locale locale; // Current message store
|
private Locale locale; // Current message store
|
||||||
private HashMap<Object, HashMap<String, String>> tags; // Control messages
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +28,18 @@ public class Localizer {
|
||||||
// Classes //
|
// Classes //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Control settings
|
||||||
|
private static class Control {
|
||||||
|
String key; // Single-string dictionary key
|
||||||
|
String[] keys; // Multiple-string dictionary key
|
||||||
|
String tipKey; // Tooltip dictionary key
|
||||||
|
HashMap<String, String> tags; // Message overrides
|
||||||
|
Control(String tipKey) {
|
||||||
|
tags = new HashMap<String, String>();
|
||||||
|
this.tipKey = tipKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Locale container
|
// Locale container
|
||||||
public static class Locale implements Comparable<Locale> {
|
public static class Locale implements Comparable<Locale> {
|
||||||
|
|
||||||
|
@ -265,8 +276,7 @@ public class Localizer {
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
public Localizer() {
|
public Localizer() {
|
||||||
controls = new HashMap<Object, Object>();
|
controls = new HashMap<Object, Control>();
|
||||||
tags = new HashMap<Object, HashMap<String, String>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsing constructor
|
// Parsing constructor
|
||||||
|
@ -283,6 +293,14 @@ public class Localizer {
|
||||||
|
|
||||||
// Add a control to the collection
|
// Add a control to the collection
|
||||||
public boolean add(Object control, Object key) {
|
public boolean add(Object control, Object key) {
|
||||||
|
return add(control, key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a control with a tooltip to the collection
|
||||||
|
public boolean add(Object control, Object key, String tipKey) {
|
||||||
|
var ctrl = controls.get(control);
|
||||||
|
if (ctrl == null)
|
||||||
|
ctrl = new Control(tipKey);
|
||||||
|
|
||||||
// Error checking
|
// Error checking
|
||||||
if (control == null || key == null)
|
if (control == null || key == null)
|
||||||
|
@ -290,6 +308,8 @@ public class Localizer {
|
||||||
|
|
||||||
// Control takes a single string
|
// Control takes a single string
|
||||||
if (key instanceof String) {
|
if (key instanceof String) {
|
||||||
|
|
||||||
|
// Type validation
|
||||||
if (!(
|
if (!(
|
||||||
control instanceof AbstractButton ||
|
control instanceof AbstractButton ||
|
||||||
control instanceof JFrame ||
|
control instanceof JFrame ||
|
||||||
|
@ -297,22 +317,31 @@ public class Localizer {
|
||||||
control instanceof JPanel || // TitledBorder
|
control instanceof JPanel || // TitledBorder
|
||||||
control instanceof JTextComponent
|
control instanceof JTextComponent
|
||||||
)) return false;
|
)) return false;
|
||||||
|
|
||||||
|
// Configure key
|
||||||
|
ctrl.key = (String) key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Control takes an array of strings
|
// Control takes an array of strings
|
||||||
else if (key instanceof String[]) {
|
else if (key instanceof String[]) {
|
||||||
|
|
||||||
|
// Type validation
|
||||||
if (!(
|
if (!(
|
||||||
JCOMBOBOX.getClass().isAssignableFrom(control.getClass())
|
JCOMBOBOX.getClass().isAssignableFrom(control.getClass())
|
||||||
)) return false;
|
)) return false;
|
||||||
|
|
||||||
|
// Configure keys
|
||||||
|
String[] keys = (String[]) key;
|
||||||
|
ctrl.keys = new String[keys.length];
|
||||||
|
System.arraycopy(keys, 0, ctrl.keys, 0, keys.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalid control type
|
// Invalid control type
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
// Add the control to the collection
|
// Add the control to the collection
|
||||||
controls.put(control, key);
|
controls.put(control, ctrl);
|
||||||
tags .put(control, new HashMap<String, String>());
|
update(control);
|
||||||
update();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +350,11 @@ public class Localizer {
|
||||||
controls.clear();
|
controls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Evaluate the message for a given key
|
||||||
|
public String get(String key) {
|
||||||
|
return key == null ? null : evaluate(null, key);
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the currently loaded locale
|
// Retrieve the currently loaded locale
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return locale;
|
return locale;
|
||||||
|
@ -328,21 +362,26 @@ public class Localizer {
|
||||||
|
|
||||||
// Configure a control tag
|
// Configure a control tag
|
||||||
public String put(Object control, String key, String value) {
|
public String put(Object control, String key, String value) {
|
||||||
if (controls.get(control) == null || key == null)
|
var ctrl = controls.get(control);
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if (ctrl == null || key == null)
|
||||||
return null;
|
return null;
|
||||||
var tags = this.tags.get(control);
|
|
||||||
|
// Update the control's tags
|
||||||
key = key.toLowerCase();
|
key = key.toLowerCase();
|
||||||
String ret = value == null ?
|
String ret = value == null ?
|
||||||
tags.remove(key) :
|
ctrl.tags.remove(key) :
|
||||||
tags.put(key, value)
|
ctrl.tags.put(key, value)
|
||||||
;
|
;
|
||||||
update();
|
|
||||||
|
// Refresh the text on the control
|
||||||
|
update(control);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a control from the collection
|
// Remove a control from the collection
|
||||||
public boolean remove(Object control) {
|
public boolean remove(Object control) {
|
||||||
tags.remove(control);
|
|
||||||
return controls.remove(control) != null;
|
return controls.remove(control) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +397,7 @@ public class Localizer {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Process substitutions and escapes on a message for a given key
|
// Process substitutions and escapes on a message for a given key
|
||||||
private String evaluate(Object control, String key) {
|
private String evaluate(Control control, String key) {
|
||||||
|
|
||||||
// No locale is loaded
|
// No locale is loaded
|
||||||
if (locale == null)
|
if (locale == null)
|
||||||
|
@ -395,7 +434,7 @@ public class Localizer {
|
||||||
// Determine the substitution
|
// Determine the substitution
|
||||||
key = new String(chars, start, x - start);
|
key = new String(chars, start, x - start);
|
||||||
String lkey = key.toLowerCase();
|
String lkey = key.toLowerCase();
|
||||||
String value = tags.get(control).get(lkey);
|
String value = control == null ? null : control.tags.get(lkey);
|
||||||
if (value == null)
|
if (value == null)
|
||||||
value = locale.messages.get(lkey);
|
value = locale.messages.get(lkey);
|
||||||
if (value == null)
|
if (value == null)
|
||||||
|
@ -430,68 +469,66 @@ public class Localizer {
|
||||||
|
|
||||||
// Update the text for all controls
|
// Update the text for all controls
|
||||||
private void update() {
|
private void update() {
|
||||||
|
for (var control : controls.keySet())
|
||||||
|
update(control);
|
||||||
|
}
|
||||||
|
|
||||||
// Process all controls
|
// Update the text for a control
|
||||||
for (var control : controls.keySet()) {
|
private void update(Object control) {
|
||||||
Object key = controls.get(control);
|
var ctrl = controls.get(control);
|
||||||
String[] values = null;
|
String[] keys = ctrl.key==null ? ctrl.keys : new String[]{ctrl.key};
|
||||||
|
String[] values = new String[keys.length];
|
||||||
|
|
||||||
// One string
|
// Evaluate all messages
|
||||||
if (key instanceof String)
|
for (int x = 0; x < keys.length; x++)
|
||||||
values = new String[] { evaluate(control, (String) key) };
|
values[x] = evaluate(ctrl, keys[x]);
|
||||||
|
|
||||||
// Multiple strings
|
// Update the control's text
|
||||||
else {
|
if (control instanceof AbstractButton)
|
||||||
String[] keys = (String[]) key;
|
((AbstractButton) control).setText (values[0]);
|
||||||
values = new String[keys.length];
|
if (control instanceof JFrame)
|
||||||
for (int x = 0; x < keys.length; x++)
|
((JFrame ) control).setTitle(values[0]);
|
||||||
values[x] = evaluate(control, keys[x]);
|
if (control instanceof JInternalFrame)
|
||||||
}
|
((JInternalFrame) control).setTitle(values[0]);
|
||||||
|
if (control instanceof JTextComponent)
|
||||||
// Update the control's text
|
((JTextComponent) control).setText (values[0]);
|
||||||
if (control instanceof AbstractButton)
|
|
||||||
((AbstractButton) control).setText (values[0]);
|
|
||||||
if (control instanceof JFrame)
|
|
||||||
((JFrame ) control).setTitle(values[0]);
|
|
||||||
if (control instanceof JInternalFrame)
|
|
||||||
((JInternalFrame) control).setTitle(values[0]);
|
|
||||||
if (control instanceof JTextComponent)
|
|
||||||
((JTextComponent) control).setText (values[0]);
|
|
||||||
|
|
||||||
// JPanel must be wrapped in a TitledBorder
|
|
||||||
if (control instanceof JPanel) {
|
|
||||||
var border = ((JPanel) control).getBorder();
|
|
||||||
if (border instanceof TitledBorder)
|
|
||||||
((TitledBorder) border).setTitle(values[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the contents of a JComboBox without firing events
|
|
||||||
if (JCOMBOBOX.getClass().isAssignableFrom(control.getClass())) {
|
|
||||||
|
|
||||||
// The type is explicitly verified above
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
var box = (JComboBox<String>) control;
|
|
||||||
|
|
||||||
// Configure working variables
|
|
||||||
var action = box.getActionListeners();
|
|
||||||
int index = box.getSelectedIndex();
|
|
||||||
var item = box.getItemListeners();
|
|
||||||
|
|
||||||
// Remove event listeners
|
|
||||||
for (var lst : action) box.removeActionListener(lst);
|
|
||||||
for (var lst : item ) box.removeItemListener (lst);
|
|
||||||
|
|
||||||
// Update contents
|
|
||||||
box.setModel(new DefaultComboBoxModel<String>(values));
|
|
||||||
box.setSelectedIndex(index);
|
|
||||||
|
|
||||||
// Restore event listeners
|
|
||||||
for (var lst : action) box.addActionListener(lst);
|
|
||||||
for (var lst : item ) box.addItemListener (lst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// JPanel must be wrapped in a TitledBorder
|
||||||
|
if (control instanceof JPanel) {
|
||||||
|
var border = ((JPanel) control).getBorder();
|
||||||
|
if (border instanceof TitledBorder)
|
||||||
|
((TitledBorder) border).setTitle(values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace the contents of a JComboBox without firing events
|
||||||
|
if (JCOMBOBOX.getClass().isAssignableFrom(control.getClass())) {
|
||||||
|
|
||||||
|
// The type is explicitly verified above
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var box = (JComboBox<String>) control;
|
||||||
|
|
||||||
|
// Configure working variables
|
||||||
|
var action = box.getActionListeners();
|
||||||
|
int index = box.getSelectedIndex();
|
||||||
|
var item = box.getItemListeners();
|
||||||
|
|
||||||
|
// Remove event listeners
|
||||||
|
for (var lst : action) box.removeActionListener(lst);
|
||||||
|
for (var lst : item ) box.removeItemListener (lst);
|
||||||
|
|
||||||
|
// Update contents
|
||||||
|
box.setModel(new DefaultComboBoxModel<String>(values));
|
||||||
|
box.setSelectedIndex(index);
|
||||||
|
|
||||||
|
// Restore event listeners
|
||||||
|
for (var lst : action) box.addActionListener(lst);
|
||||||
|
for (var lst : item ) box.addItemListener (lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the control's tooltip text
|
||||||
|
if (control instanceof JComponent)
|
||||||
|
((JComponent) control).setToolTipText(
|
||||||
|
ctrl.tipKey == null ? null : evaluate(ctrl, ctrl.tipKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,18 @@ public final class Util {
|
||||||
return new Color(bits, true);
|
return new Color(bits, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read a file from disk
|
||||||
|
public static byte[] fileRead(File file) {
|
||||||
|
FileInputStream stream = null;
|
||||||
|
byte[] data = null;
|
||||||
|
try {
|
||||||
|
stream = new FileInputStream(file);
|
||||||
|
data = stream.readAllBytes();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
try { stream.close(); } catch (Exception e) { }
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
// Read a file, first from disk, then from .jar
|
// Read a file, first from disk, then from .jar
|
||||||
public static byte[] fileRead(String filename) {
|
public static byte[] fileRead(String filename) {
|
||||||
InputStream stream = null;
|
InputStream stream = null;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
util/Util.class
BIN
util/Util.class
Binary file not shown.
Loading…
Reference in New Issue