/* * @(#)CDcreator.java * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 1999-2006 Jörg P. M. Haeger * * webCDwriter is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * webCDwriter is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with webCDwriter; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Jörg Haeger, 14.05.1999 */ import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; import netscape.security.PrivilegeManager; /** * The main class of webCDcreator. * * @version 20060425 * @author Jörg P. M. Haeger */ public class CDcreator extends JApplet implements java.awt.event.ActionListener { public static String debug = ""; public static String serverName = Config.serverName; public static int serverPortNo = Config.serverPortNo; public static String osName, osVersion, vmName, vmVersion; public static boolean vmUnknown = true; public static Socket socket; public static BufferedInputStream inStream; public static DataOutputStream outStream; public static CDcreator app = null, applet = null; static JFrame frame = null; private static JMenuBar menuBar = null; private static java.awt.Container contentPane = null; private static WindowListener windowListener = null; private static WindowListener[] windowListeners; public static java.awt.Component mainWin = null; static MainWin model = null, view = null; private static JButton startButton; static boolean appletDocked = true; static Point appletOrigin = new Point(0, 0); public static Locale locale; static ResourceBundle messages; public static int maxCopies = 1, maxMBTransferPerProject = 5000, maxSpeed = 4; public static boolean anonymousUse = false, askForProjectInfo = false, audioCDSupport = false, cdrdao = false, copySupport = false, DnD = false, exportOnly = false, importImageSupport = false, managedAccounts = false, MD5FileSupport = true, mp3Support = false, oggSupport = true, overburnSupport = false, saveImageAs = false, verifySupport = false, writeProtection = false, writerSelection = false; public static String supportedMedia = ""; public static WebStart webStart; public static String project = ""; public static String projectURL = ""; public static boolean oneClick = false; static boolean javaws142 = false; public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getActionCommand().equals("quitCmd")) { closeConnection(); if (mainWin != applet) mainWin.setVisible(false); mainWin = null; startButton.setEnabled(true); synchronized(this) { notifyAll(); } return; } if (isNetscapeVM()) try { PrivilegeManager.enablePrivilege( "UniversalPropertyRead"); PrivilegeManager.enablePrivilege( "UniversalFileRead"); } catch (Exception e2) { } // check the privileges try { File f = new SecFile("C:\\"); if (!f.exists()) f = new SecFile("/"); f.exists(); } catch (java.security.AccessControlException e1) { new JOptionPane( i18n("accessError"), JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION) .createDialog(this, i18n("titleAccessError")).show(); return; } catch (Exception e2) { new JOptionPane( "unknown Error", JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION) .createDialog(this, "Error").show(); return; } startButton.setEnabled(false); openMainWin(); } static void closeConnection() { try { if (socket != null) { new Quit().run(); socket.close(); socket = null; } } catch (java.io.IOException e) { System.out.println( "closeConnection(): java.io.IOException"); } } public static void closeMainWin() { if (mainWin == null) return; closeConnection(); if (mainWin != applet) mainWin.setVisible(false); mainWin = null; if (isApplet()) startButton.setEnabled(true); else System.exit(0); } public void destroy() { Version.debug("applet", "destroy() start"); if (isApplet() && appletDocked) SwingUtilities.invokeLater(new Runnable() { public void run() { frame = new JFrame(getTitle()); windowListener = new WindowAdapter() { public void windowClosed(WindowEvent e) { applet.closeMainWin(); } public void windowClosing(WindowEvent e) { e.getWindow().dispose(); } }; frame.addWindowListener(windowListener); JMenuBar menuBar = applet.getJMenuBar(); applet.setJMenuBar(null); java.awt.Container pane = applet.getContentPane(); applet.setContentPane(new java.awt.Container()); appletDocked = false; frame.setJMenuBar(menuBar); frame.setContentPane(pane); mainWin = frame; java.awt.Dimension dim = applet.getSize(); mainWin.setBounds(appletOrigin.x, appletOrigin.y, dim.width, dim.height); mainWin.setVisible(true); } }); synchronized(this) { while (mainWin != null) try { wait(); } catch (InterruptedException e) { } } Version.debug("applet", "destroy() end"); } /** * */ public static void exit() { closeConnection(); Config.set(Config.x, CDcreator.frame.getX()); Config.set(Config.y, CDcreator.frame.getY()); int width = CDcreator.frame.getWidth(); if (width < 800) width++; Config.set(Config.width, width); Config.set(Config.height, CDcreator.frame.getHeight()); Config.set(Config.MD5File, Options.MD5File); Config.set(Config.MEDIUM, "" + Mode.media.getSelectedItem()); Config.set(Config.VERIFY, Options.verify); if (isApplet()) applet.closeMainWin(); else System.exit(0); } /** * Load a help page of webCDcreator. */ public static JComponent getHelp(String key) { JComponent viewer = getHTML("help/" + key + ".html"); if (viewer == null) return new JLabel("no help available"); JScrollPane scroller = new JScrollPane(); scroller.getViewport().add(viewer); return scroller; } /** * Load a HTML page of webCDcreator. */ public static JEditorPane getHTML(String name) { int p = name.lastIndexOf("."); String suffix = ""; if (p >= 0) { suffix = name.substring(p); name = name.substring(0, p); } JEditorPane viewer; try { Version.debug("JEditorPane", "loading..."); URL url = CDcreator.getURL(name + "_" + CDcreator.locale.getLanguage() + suffix); viewer = new JEditorPane(url); Version.debug("JEditorPane", "loading... done"); } catch (java.io.IOException e) { URL url = CDcreator.getURL(name + suffix); try { viewer = new JEditorPane(url); } catch (java.io.IOException e2) { return null; } } viewer.setEditable(false); return viewer; } static String getTitle() { String version = Version.version; int level = 1; int i; for (i = 0; i < version.length(); i++) { char ch = version.charAt(i); if (ch == '.') { level++; if (level > 3) break; } else if (ch < '0' || ch > '9') break; } if (level == 1) version = ""; else version = " " + version.substring(0, i); return Version.product + version; } public static URL getURL(String fileName) { URL url; if (app != null) { url = app.getClass().getResource(fileName); if (url == null) try { url = new URL( "http", serverName, serverPortNo, "/webCDcreator/" + fileName); } catch (Exception e) {} } else if (isApplet()) { url = applet.getClass().getResource(fileName); if (url == null) // required by Netscape 4.7x try { url = new URL( applet.getCodeBase(), fileName); } catch (java.net.MalformedURLException e) {} } else url = null; Version.debug("getURL()", fileName + " -> " + url); return url; } static public String i18n(String key) { String msg; try { String str = key; if (key.equals("optionSimulate")) str = "laserOff"; msg = messages.getString(str); } catch (MissingResourceException e) { if (key.indexOf("_to_big") > 0) key = "error_session_too_big"; try { msg = messages.getString(key); } catch (MissingResourceException e2) { msg = key; } } if (msg.startsWith("-> ")) try { msg = messages.getString(msg.substring(3)); } catch (MissingResourceException e) { msg = key; } if (msg.indexOf("") >= 0 || msg.indexOf("
") >= 0) msg = "" + msg + ""; if (msg.indexOf("650") >= 0 && msg.indexOf("/650") < 0) msg = replaceAll(msg, "650", String.valueOf(Mode.mediumSize)); String plusMinus = "+"; if (supports("DVD-R")) if (supports("DVD+R")) plusMinus = "\u00B1"; else plusMinus = "-"; String[][] replacements = { { "@CD-RW@", "@CD@@-@RW" }, { "@CD-R@", "@CD@@-@R" }, { "@CD@", Mode.isMediumDVD()? "DVD": "CD" }, { "@-@", Mode.isMediumDVD()? plusMinus: "-" }, { "@DVD-@", "DVD" + plusMinus } }; for (int i = 0; i < replacements.length; i++) msg = replaceAll(msg, replacements[i][0], replacements[i][1]); if (msg.indexOf("@") < 0) return msg; msg = replaceAll(msg, "@PORT@", "" + serverPortNo); msg = replaceAll(msg, "@MAXTRANSFER@", "" + maxMBTransferPerProject); msg = replaceAll(msg, "@SERVER@", serverName); return msg; } public void init() { if (getParameter("debug") != null) debug = getParameter("debug"); Version.debug("applet", "init()"); // if (applet != null) // return; showProductInfo(); Version.debug("applet", "bounds = " + getBounds()); applet = this; readProperties(); serverName = getCodeBase().getHost(); initMessages(getParameter("language"), getParameter("country")); if (getParameter("server") != null) serverName = getParameter("server"); if (getParameter("port") != null) serverPortNo = new Integer(getParameter("port")) .intValue(); appletDocked = getBounds().width > 400; if (appletDocked) openMainWin(); else { startButton = new JButton(i18n("startCmd")); startButton.addActionListener(this); startButton.setToolTipText(i18n("TTstart")); getContentPane().add(startButton); } } private static void initMessages(String language, String country) { String str = Config.get(Config.language); if (str != null && str.length() > 0) language = str; str = Config.get(Config.country); if (str != null && str.length() > 0) country = str; if (language == null || language.length() == 0) language = Locale.getDefault().getLanguage(); if (country == null) country = ""; setLocale2(new Locale(language, country)); System.out.println( "language = <" + language + ">" + " country = <" + country + ">" + " locale = <" + new Locale(language, country) + ">" + " default = <" + Locale.getDefault() + ">"); } public static boolean isApplet() { return applet != null; } public static boolean isNetscapeVM() { return vmName.equals("unknown"); // vmUnknown; } public static void main(String args[]) { showProductInfo(); app = new CDcreator(); app.readProperties(); String country = null, language = null; // Java Web Start init try { Class.forName("javax.jnlp.ServiceManager"); webStart = new WebStart(); System.out.println("codeBase = " + webStart.getCodeBase()); serverName = webStart.getCodeBase().getHost(); String version = System.getProperty("javawebstart.version", ""); System.out.println("javawebstart.version=" + version); javaws142 = version.startsWith("javaws-1.4.2"); } catch (Exception e) {} boolean error = false; for (int i = 0; i < args.length; i++) if (args[i].startsWith("server=")) serverName = args[i].substring(7); else if (args[i].startsWith("port=")) serverPortNo = new Integer( args[i].substring(5)).intValue(); else if (args[i].startsWith("country=")) country = args[i].substring(8); else if (args[i].startsWith("debug=")) debug = args[i].substring(6); else if (args[i].startsWith("language=")) language = args[i].substring(9); else if (args[i].startsWith("project=")) { project = args[i].substring(8); oneClick = true; } else if (args[i].toUpperCase().startsWith("URL=")) { projectURL = args[i].substring(4); oneClick = true; } else if (args[i].startsWith("oneClick=")) oneClick = args[i].endsWith("on"); else // error = true; JOptionPane.showInputDialog(args[i]); initMessages(language, country); if (error) { System.out.println(Version.product + " " + Version.version); // System.out.println("Author: " + Version.author); System.out.println("Arguments and their defaults:"); System.out.println("country=" + locale.getCountry()); System.out.println("language=" + locale.getLanguage()); System.out.println("port=" + Config.serverPortNo); System.out.println("server=" + Config.serverName); System.exit(0); } app.openMainWin(); } public void openMainWin() { String LnF = ""; try { LnF = UIManager.getSystemLookAndFeelClassName(); Version.debug("LnF", LnF); if (LnF.indexOf(".plaf.windows.") > 0) UIManager.setLookAndFeel(LnF); } catch (Exception e) { } if (!isNetscapeVM()) Config.mirror(); if (!Config.configFile.exists() && !isNetscapeVM()) { try { OutputStream out = new FileOutputStream(Config.configFile); out.close(); } catch (IOException e) {} if (Config.configFile.exists()) showFirstTimeDialog(); } Options.MD5File = Config.getBool(Config.MD5File); Options.verify = Config.getBool(Config.VERIFY); if (javaws142 && LnF.indexOf(".plaf.windows.") > 0 && Config.getBool(Config.JAVAWS142)) showJavaWS142Dialog(); if (isApplet() && appletDocked) { if (isNetscapeVM()) try { PrivilegeManager.enablePrivilege( "UniversalPropertyRead"); PrivilegeManager.enablePrivilege( "UniversalFileRead"); } catch (Exception e2) { } mainWin = applet; model = view = new MainWin(); } else { frame = new JFrame(getTitle()); windowListener = new WindowAdapter() { public void windowClosed(WindowEvent e) { exit(); } public void windowClosing(WindowEvent e) { e.getWindow().dispose(); } }; frame.addWindowListener(windowListener); frame.setIconImage(MainWin.getIcon("logo.png").getImage()); mainWin = frame; model = view = new MainWin(); Rectangle screenRect; try { frame.getClass().getMethod( "getGraphicsConfiguration", null); screenRect = frame.getGraphicsConfiguration() .getBounds(); } catch (NoSuchMethodException e) { screenRect = new Rectangle(0, 0, 1024, 768); } int x = Config.getInt(Config.x); int y = Config.getInt(Config.y); int width = Config.getInt(Config.width); int height = Config.getInt(Config.height); if (width < 300) width = 300; if (height < 200) height = 200; if (width > screenRect.width) width = screenRect.width; if (height > screenRect.height) height = screenRect.height; if (x < 0 || x > screenRect.width - 100) x = screenRect.x + (screenRect.width - width) / 2; if (y < 0 || y > screenRect.height - 100) y = screenRect.y + (screenRect.height - height) / 2; frame.setBounds(x, y, width, height); frame.setVisible(true); } State.reset(); State.userID = System.getProperty("user.name") .replace(' ', '_'); Options.reset(); // SwingUtilities.invokeLater(new Runnable() { new Thread() { public void run() { replaceMainContentPane(); try { new Connect(serverName, serverPortNo).exec(frame); SwingUtilities.invokeLater(new Runnable() { public void run() { try { if (overburnSupport) Mode.addMedium(Mode.CDR90); if (supports("DVD-R")) Mode.addMedium("DVD-R"); if (supports("DVD-RW")) Mode.addMedium("DVD-RW"); if (supports("DVD+R")) Mode.addMedium("DVD+R"); if (supports("DVD+R DL")) Mode.addMedium("DVD+R DL"); if (supports("DVD+RW")) Mode.addMedium("DVD+RW"); if (supports("DVD-RAM")) Mode.addMedium("DVD-RAM"); Mode.setMedium(Config.get(Config.MEDIUM)); view.createMenuBar(); if (!anonymousUse) { if (!LoginDialog.show()) throw new CommandError(); } view.addServerExports(); if (project.length() > 0) { model.loadProject(new StringReader(project)); } else if (projectURL.length() > 0) { model.loadProject(projectURL); } else { if (Config.getBool(Config.onStartup)) model.typeSelection(false); } } catch (CommandError cmdErr) { closeMainWin(); } } }); } catch (CommandError cmdErr) { closeMainWin(); } finally { restoreMainContentPane(); } } }.start(); } private void readProperties() { osName = System.getProperty("os.name").replace(' ', '_'); osVersion = System.getProperty("os.version") .replace(' ', '_'); try { vmName = System.getProperty("java.vm.name"); vmVersion = System.getProperty("java.vm.version"); } catch (Exception e1) { try { // PrivilegeManager.enablePrivilege( // "UniversalPropertyRead"); vmName = System.getProperty("java.vm.name"); vmVersion = System.getProperty( "java.vm.version"); } catch (Exception e2) { vmName = "unknown"; vmVersion = "unknown"; } } if (vmName == null || vmName.equals("")) vmName = "unknown"; else { vmName = vmName.replace(' ', '_'); vmUnknown = false; } if (vmVersion == null || vmVersion.equals("")) vmVersion = "unknown"; else vmVersion = vmVersion.replace(' ', '_'); } static class MyBundle extends PropertyResourceBundle { MyBundle(InputStream in, ResourceBundle parent) throws IOException { super(in); setParent(parent); } public static ResourceBundle getBundle2( String baseName, Locale locale) { ResourceBundle bundle = null; try { InputStream in = getURL(baseName + ".properties").openStream(); bundle = new PropertyResourceBundle(in); } catch (Exception e) { System.out.println(e); } if (locale.getLanguage().length() == 0) return bundle; try { InputStream in = getURL(baseName + "_" + locale.getLanguage() + ".properties").openStream(); bundle = new MyBundle(in, bundle); } catch (Exception e) { System.out.println(e); } if (locale.getCountry().length() == 0) return bundle; try { InputStream in = getURL(baseName + "_" + locale.getLanguage() + "_" + locale.getCountry() + ".properties").openStream(); bundle = new MyBundle(in, bundle); } catch (Exception e) { System.out.println(e); } return bundle; } } static String replaceAll( String str, String regex, String replacement) { if (str.indexOf(regex) < 0) return str; String str2 = ""; int p0 = 0; while (true) { int p = str.indexOf(regex, p0); if (p < 0) { str2 += str.substring(p0); break; } str2 += str.substring(p0, p) + replacement; p0 = p + regex.length(); } return str2; } static void replaceMainContentPane() { Runnable runnable = new Runnable() { public void run() { JComponent c = new JPanel(); c.setLayout(new java.awt.BorderLayout()); c.setOpaque(true); synchronized(Version.product) { replaceMainContentPane2(c); } } }; if (SwingUtilities.isEventDispatchThread()) runnable.run(); else SwingUtilities.invokeLater(runnable); } private static void replaceMainContentPane2(JComponent pane) { if (contentPane != null) return; if (frame != null) { if (menuBar == null) menuBar = frame.getJMenuBar(); if (contentPane == null) contentPane = frame.getContentPane(); frame.setJMenuBar(null); frame.setContentPane(pane); // frame.removeWindowListener(windowListener); windowListeners = frame.getWindowListeners(); Version.debug("windowListener", "" + windowListeners.length); for (int i = 0; i < windowListeners.length; i++) frame.removeWindowListener(windowListeners[i]); frame.validate(); frame.repaint(); } else if (applet != null) { if (menuBar == null) menuBar = applet.getJMenuBar(); if (contentPane == null) contentPane = applet.getContentPane(); applet.setJMenuBar(null); applet.setContentPane(pane); applet.validate(); applet.repaint(); } } static void restoreMainContentPane() { SwingUtilities.invokeLater(new Runnable() { public void run() { synchronized(Version.product) { restoreMainContentPane2(); } } }); } private static void restoreMainContentPane2() { if (contentPane == null) return; if (frame != null) { frame.setJMenuBar(menuBar); frame.setContentPane(contentPane); // frame.addWindowListener(windowListener); WindowListener[] wls = frame.getWindowListeners(); Version.debug("windowListener", "" + wls.length); for (int i = 0; i < wls.length; i++) frame.removeWindowListener(wls[i]); for (int i = 0; i < windowListeners.length; i++) frame.addWindowListener(windowListeners[i]); frame.validate(); frame.repaint(); } else if (applet != null) { applet.setJMenuBar(menuBar); applet.setContentPane(contentPane); applet.validate(); applet.repaint(); } contentPane = null; } static void setLocale2(Locale locale) { CDcreator.locale = locale; Config.set(Config.language, locale.getLanguage()); Config.set(Config.country, locale.getCountry()); if (isNetscapeVM()) { messages = MyBundle.getBundle2("i18n/Messages", locale); return; } ClassLoader loader = new ClassLoader() { /* public Class findClass(String name) throws ClassNotFoundException { System.out.println("findClass: " + name); try { InputStream in = getURL(name) .openStream(); byte[] bs = new byte[64 * 1024]; int n = in.read(bs); return defineClass(name, bs, 0, n); } catch (Exception e) { System.out.println(e); throw new ClassNotFoundException(); } } */ public URL findResource(String name) { Version.debug("ClassLoader", "findResource: " + name); URL url = super.findResource(name); if (url != null) return url; return getURL(name); } public URL getResource(String name) { Version.debug("ClassLoader", "getResource: " + name); URL url = super.getResource(name); if (url != null) return url; return getURL(name); } public Class loadClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(); } }; // URL[] urls = { getURL("/") }; // ClassLoader loader = new URLClassLoader(urls); messages = ResourceBundle.getBundle( "i18n/Messages", locale, loader); } static void setTitle(int progress) { if (frame != null) if (progress < 0) frame.setTitle(getTitle()); else frame.setTitle(progress + "% - " + getTitle()); } public static void showDocument(String name) { URL url = null; if (applet != null) { try { url = new URL( applet.getCodeBase(), name); } catch (java.net.MalformedURLException e) {} } else if (webStart != null) { try { url = new URL( webStart.getCodeBase(), name); } catch (java.net.MalformedURLException e) {} } else url = getURL(name); showDocument(url); } public static void showDocument(URL url) { if (applet != null) applet.getAppletContext() .showDocument(url, "_blank"); else if (webStart != null) webStart.showDocument(url); else new HelpWin(url).show(); } /** * */ protected void showFirstTimeDialog() { try { if (EventQueue.isDispatchThread()) showFirstTimeDialog2(); else EventQueue.invokeAndWait(new Runnable() { public void run() { showFirstTimeDialog2(); } }); } catch (Exception e) { } } private void showFirstTimeDialog2() { JPanel vbox = new JPanel(); vbox.setLayout(new BoxLayout(vbox, BoxLayout.Y_AXIS)); JComponent c = new JLabel(i18n("FirstTimeDialog.label")); c.setAlignmentX(JLabel.LEFT_ALIGNMENT); vbox.add(c); vbox.add(Box.createVerticalStrut(20)); final JComboBox languageBox = new JComboBox(MainWin.locales); languageBox.addActionListener( new java.awt.event.ActionListener() { public void actionPerformed( java.awt.event.ActionEvent e) { int i = languageBox.getSelectedIndex(); setLocale2(MainWin.locales[i].locale); } }); for (int i = 0; i < MainWin.locales.length; i++) if (MainWin.locales[i].locale.getLanguage() .equals(locale.getLanguage())) languageBox.setSelectedIndex(i); languageBox.setAlignmentX(JLabel.LEFT_ALIGNMENT); vbox.add(languageBox); vbox.add(Box.createVerticalStrut(20)); JOptionPane pane = new JOptionPane(vbox, JOptionPane.QUESTION_MESSAGE); JDialog dialog = pane.createDialog( null, i18n("FirstTimeDialog.title")); // dialog.setModal(false); dialog.setVisible(true); } /** * */ public void showJavaWS142Dialog() { JPanel vbox = new JPanel(); vbox.setLayout(new BoxLayout(vbox, BoxLayout.Y_AXIS)); vbox.add(new JLabel("Delaying the start of webCDcreator" + " to avoid a problem with Java Web Start 1.4.2")); JProgressBar bar = new JProgressBar(0, 8); vbox.add(bar); vbox.add(Box.createVerticalStrut(10)); final JCheckBox box = new JCheckBox( i18n("NewProjectDialog.onStartup"), true); box.addActionListener( new java.awt.event.ActionListener() { public void actionPerformed( java.awt.event.ActionEvent e) { Config.set(Config.JAVAWS142, box.isSelected()); } }); vbox.add(box); JOptionPane pane = new JOptionPane(vbox, JOptionPane.INFORMATION_MESSAGE); // win.getContentPane().add(pane); // win.pack(); JDialog win = pane.createDialog(null, ""); win.setModal(false); win.setVisible(true); for (int i = 0; i < 8; i++) { bar.setValue(i); try { Thread.sleep(1000); } catch (Exception e) { } } win.setVisible(false); } public static void showProductInfo() { System.out.println( Version.product + " " + Version.version + " " + Version.copyright); } public static void showServerDocument(String name) { try { URL url = new URL("http", serverName, serverPortNo, name); showDocument(url); } catch (java.net.MalformedURLException urlExp) { } } public void stop() { Version.debug("applet", "stop()"); } public void start() { Version.debug("applet", "start()"); } public static boolean supports(String name) { return supportedMedia.indexOf(name + ",") >= 0; } public static boolean useUnicodeFont() { return locale.getLanguage().equals("ko") || locale.getLanguage().equals("zh"); } }