From: mshio Date: Fri, 28 May 2010 13:57:17 +0000 (+0000) Subject: add a little program 'chartool' X-Git-Tag: v.20200415~169 X-Git-Url: http://git.sourceforge.jp/view?p=sawarabi-fonts%2Fsawarabi-fonts.git;a=commitdiff_plain;h=e1c495e896978b1494e3c2edcc3ff678950c5516 add a little program 'chartool' git-svn-id: svn+ssh://svn.osdn.net/svnroot/sawarabi-fonts/trunk@7 54a90f34-5e62-402c-8eae-46c47f0b2e07 --- diff --git a/chartool/build.xml b/chartool/build.xml new file mode 100644 index 00000000..e33dd415 --- /dev/null +++ b/chartool/build.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chartool/js/charpalette.js b/chartool/js/charpalette.js new file mode 100644 index 00000000..efb46259 --- /dev/null +++ b/chartool/js/charpalette.js @@ -0,0 +1,10 @@ +var fonts = [ +]; + +var script = [ + function(property, modifier) { + }, + function(property, modifier) { + }, +]; + diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/CharProperty.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/CharProperty.java new file mode 100644 index 00000000..3935e897 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/CharProperty.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +public class CharProperty { + final String character; + final String name; + final String code; + + public CharProperty(String character, String code) { + this(character, code, ""); + } + + public CharProperty(String character, String code, String name) { + this.character = character; + this.code = code; + this.name = name; + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/ConfigScript.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/ConfigScript.java new file mode 100644 index 00000000..2f2c9e81 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/ConfigScript.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.logging.Logger; + +import javax.swing.JFrame; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.EvaluatorException; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.ScriptableObject; + +public class ConfigScript { + private final static ConfigScript instance = new ConfigScript(); + private JsScriptableObject scriptable = null; + + private ConfigScript() { } + + public static ConfigScript getInstance() { + return instance; + } + + public void load() throws IOException { + load("js/charpalette.js"); + } + + public void load(String filename) throws IOException { + File f = new File(filename); + FileReader in = new FileReader(f); + Context cx = Context.enter(); + scriptable = new JsScriptableObject(); + cx.initStandardObjects(scriptable); + setupVariables(); + try { + cx.evaluateReader(scriptable, in, "", 0, null); + } finally { + Context.exit(); + } + } + + public boolean isLoaded() { + return scriptable != null; + } + + public String[] getFontNames() { + String[] ret = null; + if (scriptable.has("fonts", scriptable)) { + Object o = scriptable.get("fonts", scriptable); + try { + ret = (String[]) Context.jsToJava(o, String[].class); + } catch (EvaluatorException e) { + e.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(e.getMessage()); + } + } + return ret; + } + + private Function[] getScriptFunction() { + final String NAME = "script"; + Function[] ret = null; + if (scriptable.has(NAME, scriptable)) { + Object o = scriptable.get(NAME, scriptable); + try { + ret = (Function[]) Context.jsToJava(o, Function[].class); + } catch (EvaluatorException e) { + e.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(e.getMessage()); + } + } + return ret; + } + + public void execScript(int id, String property, int modifier) throws Exception { + Function[] fs = getScriptFunction(); + if (fs == null || fs.length <= id) { return ; } + + Context cx = Context.enter(); +// Class clazz = org.jdesktop.jdic.desktop.Desktop.class; +// cx.setApplicationClassLoader(clazz.getClassLoader()); + try { + fs[id].call(cx, scriptable, scriptable, new Object[] {property, modifier}); + } finally { + Context.exit(); + } + } + + private void setupVariables() { + final int RO = ScriptableObject.READONLY; + final int DE = ScriptableObject.DONTENUM; + String home = System.getProperty("user.home"); + ScriptableObject.defineProperty(scriptable, "HOME", home, RO); + + String[] fs = new String[] { "alert" }; + scriptable.defineFunctionProperties(fs, JsScriptableObject.class, DE); + } + + public void setFrame(JFrame frame) { + scriptable.setFrame(frame); + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/GlyphViewer.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/GlyphViewer.java new file mode 100644 index 00000000..a0907344 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/GlyphViewer.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.util.logging.Logger; + +import javax.swing.JMenu; +import javax.swing.JPopupMenu; +import javax.swing.JTextField; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import javax.swing.border.EtchedBorder; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.text.TextAction; + +public class GlyphViewer extends JTextField { + private static final long serialVersionUID = 5811308266106026080L; + + public GlyphViewer(GuiController controller) { + Font f = new Font(getFont().getFontName(), Font.PLAIN, 64); + setFont(f); + setHorizontalAlignment(JTextField.CENTER); + setEditable(false); + EmptyBorder m = new EmptyBorder(10, 10, 10, 10); + setBorder(new CompoundBorder(new EtchedBorder(), m)); + + controller.setGlyphViewer(this); + setPreferredSize(new Dimension(100, 100)); + + final JPopupMenu menu = new GlyphViewerMenu(); + addCaretListener(new CaretListener() { + public void caretUpdate(CaretEvent e) { + String s = getSelectedText(); + if (s != null && s.length() > 0) { + menu.show(GlyphViewer.this, 70, 70); + } + } + }); + } + + private void copyChar() { + Clipboard b = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection s = new StringSelection(getText()); + b.setContents(s, s); + } + + private void changeFont(String nm) { + Font f = getFont(); + int sz = f.getSize(); + int st = f.getStyle(); + setFont(new Font(nm, st, sz)); + } + + class GlyphViewerMenu extends JPopupMenu { + private static final long serialVersionUID = 847563481396381931L; + + GlyphViewerMenu() { + add(new TextAction("Copy") { + private static final long serialVersionUID = -4087404094754292233L; + public void actionPerformed(ActionEvent e) { copyChar(); } + }); + JMenu fontmenu = new JMenu("font"); + setFontMenu(fontmenu, "Dialog"); + try { + addCustomFontMenu(fontmenu); + } catch (IOException e) { + e.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(e.getMessage()); + } + add(fontmenu); + } + + private void addCustomFontMenu(JMenu menu) throws IOException { + ConfigScript s = ConfigScript.getInstance(); + if (! s.isLoaded()) { s.load(); } + String[] fnt = s.getFontNames(); + if (fnt != null) { + for (String nm: fnt) setFontMenu(menu, nm); + } else { + String msg = "configuration of fonts is not found."; + System.err.println(msg); + Logger.getLogger(Main.LOGNAME).warning(msg); + } + } + + private void setFontMenu(JMenu menu, final String nm) { + menu.add(new TextAction(nm) { + private static final long serialVersionUID = 7621704223879655193L; + public void actionPerformed(ActionEvent e) { changeFont(nm); } + }); + } + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/GuiController.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/GuiController.java new file mode 100644 index 00000000..66656839 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/GuiController.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.util.logging.Logger; + +public class GuiController { + private final Main main; + private GlyphViewer glyphViewer = null; + private SearchPanel searchPanel = null; + private PropertyPanel propertyPanel = null; + + public GuiController(Main main) { + this.main = main; + } + + public void setGlyphViewer(GlyphViewer g) { + this.glyphViewer = g; + } + + public void setPropertyPanel(PropertyPanel p) { + this.propertyPanel = p; + } + + public void setSearchPanel(SearchPanel s) { + this.searchPanel = s; + } + + private boolean isHexChar(char ch) { + return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F'); + } + + private boolean foundByCode(String searchText, int pos) { + char ch = searchText.charAt(pos); + int len = searchText.length(); + if (isHexChar(ch)) { + boolean four = false; + int p = pos; + for (;;) { + four = p - pos >= 3; + if (p - pos == 4) { + if (showGlyphByCode(searchText, pos, pos + 5) || + (four && showGlyphByCode(searchText, pos, pos + 4))) { + return true; + } + } else if (p + 1 < len && isHexChar(searchText.charAt(p + 1))) { + p++; + } else { + break; + } + } + int b = pos; + for (;;) { + four = p - b >= 3; + if (p - b == 4) { + if (showGlyphByCode(searchText, b, b + 5) || + (four && showGlyphByCode(searchText, b + 1, b + 5))) { + return true; + } + } else if (b - 1 >= 0 && isHexChar(searchText.charAt(b - 1))) { + b--; + } else { + if (four) { return showGlyphByCode(searchText, b, b + 4); } + break; + } + } + } + return false; + } + + public void onSearch(String searchText, int pos, String selected) { + if (searchText.length() == 0) { return; } + if (pos >= searchText.length()) { pos = 0; } + + if (! foundByCode(searchText, pos)) { + String s = searchText.substring(pos); + if (s.length() == 0) { s = searchText; } + try { + showGlyph(main.searchChar(s)); + boolean h = Character.isHighSurrogate(s.charAt(0)); + searchPanel.setCaretPosition(pos, h ? 2 : 1); + } catch (InvalidSearchStringException e) { + e.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(e.getMessage()); + } + } + } + + private boolean showGlyphByCode(String text, int pos0, int pos1) { + boolean ret = false; + int c = Integer.parseInt(text.substring(pos0, pos1), 16); + try { + CharProperty p = main.searchChar(c); + int len = p.character.length(); + if ((len >= 2 && Character.isHighSurrogate(p.character.charAt(0)) && + Character.isLowSurrogate(p.character.charAt(1))) || len <= 1) { + showGlyph(main.searchChar(c)); + searchPanel.setCaretPosition(pos0, pos1 - pos0); + ret = true; + } + } catch (InvalidSearchStringException e) { + e.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(e.getMessage()); + } + return ret; + } + + private void showGlyph(CharProperty cp) { + if (cp != null) { + glyphViewer.setText(cp.character); + propertyPanel.setCode(cp.code); + } + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/HistoryBuffer.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/HistoryBuffer.java new file mode 100644 index 00000000..24d99cce --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/HistoryBuffer.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.util.LinkedList; +import java.util.ListIterator; + +public class HistoryBuffer { + private final static int MAX_LENGTH = 100; + private final LinkedList buffer = new LinkedList(); + private ListIterator iterator = null; + private boolean prev = true; + + public void add(String buf) { + buffer.add(buf); + if (buffer.size() >= MAX_LENGTH) { buffer.removeFirst(); } + iterator = buffer.listIterator(buffer.size() - 1); + prev = true; + } + + public String getPrev() { + String ret = null; + if (! buffer.isEmpty() && iterator.hasPrevious()) { + ret = iterator.previous(); + if (! prev && iterator.hasPrevious()) { ret = iterator.previous(); } + prev = true; + } + return ret; + } + + public String getNext() { + String ret = null; + if (! buffer.isEmpty() && iterator.hasNext()) { + ret = iterator.next(); + if (prev && iterator.hasNext()) { ret = iterator.next(); } + prev = false; + } + return ret; + } + + public String getCurrent() { + return buffer.isEmpty() ? null : buffer.getLast(); + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/InvalidSearchStringException.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/InvalidSearchStringException.java new file mode 100644 index 00000000..d910eb90 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/InvalidSearchStringException.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +public class InvalidSearchStringException extends Exception { + private static final long serialVersionUID = -320568592282581589L; +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/JsScriptableObject.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/JsScriptableObject.java new file mode 100644 index 00000000..3af9990d --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/JsScriptableObject.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import org.mozilla.javascript.ScriptableObject; + +public class JsScriptableObject extends ScriptableObject { + private static final long serialVersionUID = 2857654503604299849L; + + private JFrame frame = null; + + @Override + public String getClassName() { + return "JsScriptableObject"; + } + + public void setFrame(JFrame frame) { + this.frame = frame; + } + + public void alert(String message) { + if (frame != null) { + JOptionPane.showMessageDialog(frame, message); + } + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/Main.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/Main.java new file mode 100644 index 00000000..e7bd20b0 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/Main.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.io.File; +import java.io.IOException; +import java.util.logging.FileHandler; +import java.util.logging.Logger; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class Main { + public static final String LOGNAME = "jp.sourceforge.sawarabifonts.chartool.log"; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Main m = new Main(); + m.setupLogger(); + m.showGUI(); + } + }); + } + + private void showGUI() { + JFrame f = new JFrame(); + setupConfigScript(f); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + f.add(new MainPanel(this)); + f.setSize(340, 120); + f.setVisible(true); + } + + private void setupLogger() { + Logger log = Logger.getLogger(LOGNAME); + try { + File f = new File("log"); + if (! f.exists()) { f.mkdir(); } + log.addHandler(new FileHandler("log/error", 200000, 10, false)); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void setupConfigScript(JFrame frame) { + ConfigScript s = ConfigScript.getInstance(); + if (! s.isLoaded()) { + try { + s.load(); + } catch (IOException e) { + e.printStackTrace(); + Logger.getLogger(LOGNAME).warning(e.getMessage()); + } + } + s.setFrame(frame); + } + + public CharProperty searchChar(String str) throws InvalidSearchStringException { + if (str == null || str.length() == 0) { return null; } + + String code = null; + String ch = null; + char c = str.charAt(0); + if (Character.isHighSurrogate(c)) { + if (str.length() >= 2) { + char c1 = str.charAt(1); + int t = ((int) c - 0xd800) * 0x400 + (int) c1 - 0xdc00 + 0x10000; + code = Integer.toHexString(t); + ch = new String(new char[] { c, c1 }); + } else { + code = fillZero(Integer.toHexString(c), 4); + ch = new String(new char[] { c }); + } + } else { + code = fillZero(Integer.toHexString(c), 4); + ch = new String(new char[] { c }); + } + return new CharProperty(ch, code); + } + + public CharProperty searchChar(int code) throws InvalidSearchStringException { + String h = Integer.toHexString(code); + String s = null; + String c = null; + if (h.length() >= 5) { + int x = code - 0x10000; + int c0 = x / 0x400 + 0xd800; + int c1 = x % 0x400 + 0xdc00; + s = new String(new char[] { (char) c0, (char) c1}); + c = h; + } else { + s = new String(new char[] { (char) code }); + c = fillZero(h, 4); + } + return new CharProperty(s, c); + } + + private String fillZero(String str, int length) { + String ret = str; + int l = str.length(); + if (l < length) { + StringBuilder sb = new StringBuilder(length); + for (int i = 0; length - l - i > 0; i++) { sb.append('0'); } + sb.append(str); + ret = sb.toString(); + } + return ret; + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/MainPanel.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/MainPanel.java new file mode 100644 index 00000000..b9eb1e84 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/MainPanel.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.awt.BorderLayout; + +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; + +class MainPanel extends JPanel { + private static final long serialVersionUID = 7520947148504510083L; + + public MainPanel(Main m) { + GuiController c = new GuiController(m); + final SearchPanel sp = new SearchPanel(c); + PropertyPanel pp = new PropertyPanel(c); + GlyphViewer gv = new GlyphViewer(c); + + EmptyBorder b = new EmptyBorder(10, 10, 10, 10); + this.setBorder(b); + this.setLayout(new BorderLayout()); + + JPanel p = new JPanel(); + EmptyBorder e = new EmptyBorder(0, 10, 0, 0); + p.setBorder(e); + p.setLayout(new BorderLayout()); + p.add(sp, BorderLayout.NORTH); + p.add(pp, BorderLayout.CENTER); + this.add(p, BorderLayout.CENTER); + + this.add(gv, BorderLayout.WEST); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { sp.setFocus(); } + }); + } +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/PropertyPanel.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/PropertyPanel.java new file mode 100644 index 00000000..bab4af0e --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/PropertyPanel.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.awt.FontMetrics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.logging.Logger; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class PropertyPanel extends JPanel { + private static final long serialVersionUID = -762290847824180418L; + + private final static int MARGIN_LEFT = 5; + private final static int MARGIN_TOP = 5; + private final int labelWidth; + private final JButton[] buttons; + private final JLabel[] properties; + + public PropertyPanel(GuiController controller) { + setLayout(null); + FontMetrics fm = getFontMetrics(getFont()); + String[] t = new String[] { "Code: ", "Name: " }; + buttons = new JButton[t.length]; + properties = new JLabel[t.length]; + labelWidth = setPropertyLabels(t, fm); + int maxWidth = setPropertyButtons(t, fm, labelWidth); + setPropertyLabels(t, fm, maxWidth); + addComponentListener(new ComponentAdapter() { + @Override public void componentResized(ComponentEvent e) { + onResized(); + } + }); + + controller.setPropertyPanel(this); + } + + public void setCode(String code) { + properties[0].setText(code); + } + + private void setPropertyLabels(String[] text, FontMetrics fm, int x) { + int y = MARGIN_TOP; + int h = fm.getHeight(); + for (int i = 0; i < text.length; i++) { + properties[i] = new JLabel(); + add(properties[i]); + properties[i].setLocation(x, y); + y += h; + } + } + + private int setPropertyLabels(String[] text, FontMetrics fm) { + int max = 0; + int y = MARGIN_TOP; + int h = fm.getHeight(); + for (String t : text) { + JLabel n = new JLabel(t); + n = new JLabel(t); + add(n); + n.setLocation(MARGIN_LEFT, y); + int w = fm.stringWidth(t); + n.setSize(w, h); + y += h; + if (max < w) max = w; + } + return max + MARGIN_LEFT; + } + + private int setPropertyButtons(String[] text, FontMetrics fm, int x) { + int w = fm.stringWidth("S"); + int h = fm.getHeight(); + int y = MARGIN_TOP; + + for (int i = 0; i < text.length; i++) { + JButton b = new JButton("S"); + b.setFocusable(false); + final int id = i; + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String t = properties[id].getText(); + ConfigScript s = ConfigScript.getInstance(); + try { + s.execScript(id, t, e.getModifiers()); + } catch (Exception ex) { + ex.printStackTrace(); + Logger.getLogger(Main.LOGNAME).warning(ex.getMessage()); + } + } + }); + add(b); + b.setLocation(x, y); + b.setSize(w + 10, h); + y += h; + buttons[i] = b; + } + return w; + } + + private void onResized() { + int y = MARGIN_TOP; + int h = getFontMetrics(getFont()).getHeight(); + int w = getWidth() - labelWidth - buttons[0].getWidth(); + for (int i = 0; i < properties.length; i++) { + properties[i].setLocation(labelWidth, y); + properties[i].setSize(w, h); + buttons[i].setLocation(labelWidth + w, y); + y += h; + } + } + +} diff --git a/chartool/src/jp/sourceforge/sawarabifonts/chartool/SearchPanel.java b/chartool/src/jp/sourceforge/sawarabifonts/chartool/SearchPanel.java new file mode 100644 index 00000000..97b51f91 --- /dev/null +++ b/chartool/src/jp/sourceforge/sawarabifonts/chartool/SearchPanel.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2010, mshio + * + * This program 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 any later version. + * + * This program 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 this program. If not, see . + * --- + * Require JDK 1.5 (or later) + */ +package jp.sourceforge.sawarabifonts.chartool; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.JButton; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.text.DefaultEditorKit; +import javax.swing.text.JTextComponent; +import javax.swing.text.Keymap; +import javax.swing.text.TextAction; + +public class SearchPanel extends JPanel { + private static final long serialVersionUID = 1971690273660748828L; + + private final JTextField searchField; + private final HistoryBuffer buffer = new HistoryBuffer(); + private final SearchFieldPopup popup; + + public SearchPanel(final GuiController controller) { + setLayout(new BorderLayout()); + + searchField = new JTextField(); + popup = new SearchFieldPopup(); + searchField.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON3) { + popup.show(searchField, e.getX(), e.getY()); + } + } + }); + setupKeymap(controller); + + add(searchField, BorderLayout.CENTER); + add(makeSearchButton(), BorderLayout.EAST); + + controller.setSearchPanel(this); + } + + private JButton makeSearchButton() { + JButton b = new JButton("Search"); + Keymap k = searchField.getKeymap(); + Action a = k.getAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); + b.addActionListener(a); + b.setFocusable(false); + + return b; + } + + public void setFocus() { + searchField.requestFocusInWindow(); + } + + public void setCaretPosition(int position, int length) { + if (searchField.getText().length() > position) { + searchField.setSelectionStart(position); + searchField.setSelectionEnd(position + length); + } else { + searchField.setSelectionStart(0); + searchField.setSelectionEnd(length); + } + } + + private void setupKeymap(final GuiController controller) { + Keymap map = JTextComponent.addKeymap("charpalette", searchField.getKeymap()); + searchField.setKeymap(map); + + setupSearchKeymap(controller); + setupHistoryUpKeymap(); + setupHistoryDownKeymap(); + } + + private void setupHistoryUpKeymap() { + Keymap map = searchField.getKeymap(); + KeyStroke key0 = KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_MASK); + KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); + Action a = new TextAction("history-up") { + private static final long serialVersionUID = 8417010810041845179L; + public void actionPerformed(ActionEvent e) { + String s = buffer.getPrev(); + if (s != null) { + searchField.setText(s); + searchField.setCaretPosition(0); + } + } + }; + map.addActionForKeyStroke(key0, a); + map.addActionForKeyStroke(key1, a); + } + + private void setupHistoryDownKeymap() { + Keymap map = searchField.getKeymap(); + KeyStroke key0 = KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK); + KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); + Action a = new TextAction("history-down") { + private static final long serialVersionUID = 2292000606648845301L; + public void actionPerformed(ActionEvent e) { + String s = buffer.getNext(); + if (s != null) { + searchField.setText(s); + searchField.setCaretPosition(0); + } + } + }; + map.addActionForKeyStroke(key0, a); + map.addActionForKeyStroke(key1, a); + } + + private void setupSearchKeymap(final GuiController controller) { + KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + Action a = new TextAction("search") { + private static final long serialVersionUID = 7670487950463928408L; + public void actionPerformed(ActionEvent e) { + String st = searchField.getSelectedText(); + int p = searchField.getCaretPosition(); + controller.onSearch(searchField.getText(), p, st); + String s = buffer.getCurrent(); + String t = searchField.getText(); + if (s == null || ! s.equals(t)) { + buffer.add(t); + } + } + }; + searchField.getKeymap().addActionForKeyStroke(key, a); + } + + + class SearchFieldPopup extends JPopupMenu { + private static final long serialVersionUID = 5225317856689478836L; + + final JMenuItem cut; + final JMenuItem copy; + final JMenuItem paste; + final JMenuItem clear; + + SearchFieldPopup() { + cut = makeMenuItem("Cut", DefaultEditorKit.cutAction); + copy = makeMenuItem("Copy", DefaultEditorKit.copyAction); + paste = makeMenuItem("Paste", DefaultEditorKit.pasteAction); + clear = new JMenuItem(new TextAction("Clear") { + private static final long serialVersionUID = 3995545953271258486L; + public void actionPerformed(ActionEvent e) { + searchField.setText(""); + } + }); + add(cut); + add(copy); + add(paste); + add(clear); + } + + private JMenuItem makeMenuItem(String name, String action) { + JMenuItem ret = null; + Action a = getActionFromTextField(action); + if (a != null) { + ret = new JMenuItem(); + ret.setAction(a); + ret.setText(name); + } + return ret; + } + + private Action getActionFromTextField(String name) { + ActionMap m = searchField.getActionMap(); + return m.get(name); + } + + private boolean isClipboardContentsString(Clipboard c) { + boolean ret = false; + try { + ret = c.isDataFlavorAvailable(DataFlavor.stringFlavor); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + return ret; + } + + private Clipboard getClipboard() { + Toolkit k = Toolkit.getDefaultToolkit(); + return k.getSystemClipboard(); + } + + @Override + public void show(Component invoker, int x, int y) { + boolean s = searchField.getSelectedText() != null; + cut.setEnabled(s); + copy.setEnabled(s); + paste.setEnabled(isClipboardContentsString(getClipboard())); + clear.setEnabled(searchField.getText().length() != 0); + super.show(invoker, x, y); + } + } + +}