// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/tools/symbology/milStd2525/SymbolChooser.java,v $ // $RCSfile: SymbolChooser.java,v $ // $Revision: 1.16 $ // $Date: 2006/11/14 22:44:08 $ // $Author: kratkiew $ // // ********************************************************************** package com.bbn.openmap.tools.symbology.milStd2525; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.HeadlessException; import java.awt.Insets; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import com.bbn.openmap.event.ListenerSupport; import com.bbn.openmap.gui.DimensionQueryPanel; import com.bbn.openmap.image.AcmeGifFormatter; import com.bbn.openmap.image.BufferedImageHelper; import com.bbn.openmap.image.ImageFormatter; import com.bbn.openmap.io.FormatException; import com.bbn.openmap.omGraphics.DrawingAttributes; import com.bbn.openmap.util.ArgParser; import com.bbn.openmap.util.Debug; import com.bbn.openmap.util.FileUtils; import com.bbn.openmap.util.PaletteHelper; /** * The SymbolChooser is a GUI symbol builder. It can be used in stand-alone mode * to create image files, or be integrated into a java application to create * ImageIcons. * <P> * To bring up this chooser, run this class as a standalone application, or call * showDialog(..) */ public class SymbolChooser extends JPanel implements ActionListener { public final static String CREATE_IMAGE_CMD = "CREATE_IMAGE_CMD"; public final static String NAMEFIELD_CMD = "NAMEFIELD_CMD"; public final static String EMPTY_FEATURE_LIST = null; public final static int DEFAULT_ICON_DIMENSION = 100; public final static String EMPTY_CODE = "---------------"; protected static ImageIcon DEFAULT_SYMBOL_IMAGE; protected DrawingAttributes drawingAttributes = new DrawingAttributes(); protected ImageIcon symbolImage; protected DefaultMutableTreeNode currentSymbol = null; protected SymbolTreeHolder currentSymbolTreeHolder; protected SymbolReferenceLibrary library; protected List trees; protected DimensionQueryPanel dqp; protected JButton clearFeaturesButton; protected JButton createImageFileButton; protected JTextField nameField; protected JLabel symbolImageLabel; protected JScrollPane treeView; protected JPanel optionPanel; protected Dimension iconDimension; protected boolean allowCreateImage = true; public SymbolChooser(SymbolReferenceLibrary srl) { library = srl; try { trees = createNodes(srl); } catch (FormatException fe) { Debug.output("SymbolChooser(): Caught FormatException reading data: " + fe.getMessage()); } init(srl, trees); } /** * Update the GUI with the contents of the provided SymbolTreeHolder, * reflecting a new set of symbols. * * @param sth */ public void setSelectedTreeHolder(SymbolTreeHolder sth) { treeView.setViewportView(sth.getTree()); optionPanel.removeAll(); optionPanel.add(sth.getOptionPanel()); sth.handleNodeSelection((DefaultMutableTreeNode) sth.tree.getLastSelectedPathComponent()); revalidate(); } /** * Convenience function to get a standard blank image for those SymbolParts * that are not found by the SymbolImageMaker. * * @return DEFAULT_SYMBOL_IMAGE */ public static ImageIcon getNotFoundImageIcon() { if (DEFAULT_SYMBOL_IMAGE == null) { BufferedImage bi = new BufferedImage(DEFAULT_ICON_DIMENSION, DEFAULT_ICON_DIMENSION, BufferedImage.TYPE_INT_RGB); Graphics g = bi.getGraphics(); g.setColor(Color.LIGHT_GRAY); g.fillRect(0, 0, DEFAULT_ICON_DIMENSION, DEFAULT_ICON_DIMENSION); DEFAULT_SYMBOL_IMAGE = new ImageIcon(bi); } return DEFAULT_SYMBOL_IMAGE; } /** * Create the GUI based on the contents of the SymbolReferenceLibrary and * the SymbolPartTrees created from the options. * * @param srl * @param trees */ protected void init(SymbolReferenceLibrary srl, List trees) { // /////////////////// // Create the tree window by creating the scroll pane and add // the tree to it. GridBagLayout outergridbag = new GridBagLayout(); GridBagConstraints outerc = new GridBagConstraints(); JPanel setChoicePanel = new JPanel(); JLabel setChoiceLabel = new JLabel("Symbol Set:"); JComboBox setChoices = new JComboBox(trees.toArray()); setChoices.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JComboBox jcb = (JComboBox) e.getSource(); setSelectedTreeHolder((SymbolTreeHolder) jcb.getSelectedItem()); } }); currentSymbolTreeHolder = (SymbolTreeHolder) setChoices.getSelectedItem(); setChoicePanel.add(setChoiceLabel); setChoicePanel.add(setChoices); treeView = new JScrollPane(currentSymbolTreeHolder.getTree()); setLayout(outergridbag); outerc.fill = GridBagConstraints.BOTH; outerc.gridwidth = GridBagConstraints.REMAINDER; outerc.weighty = 0.0; outerc.insets = new Insets(5, 10, 5, 10); outergridbag.setConstraints(setChoicePanel, outerc); add(setChoicePanel); outerc.weightx = 1.0; outerc.weighty = 1.0; outerc.gridwidth = GridBagConstraints.RELATIVE; outergridbag.setConstraints(treeView, outerc); add(treeView); // Add the symbol preview area to the right of the tree JPanel symbolPanel = PaletteHelper.createVerticalPanel(" Current Symbol "); setImageIcon(getNotFoundImageIcon()); symbolPanel.add(symbolImageLabel); outerc.weightx = 0.0; outerc.gridwidth = GridBagConstraints.REMAINDER; outergridbag.setConstraints(symbolPanel, outerc); dqp = new DimensionQueryPanel(getDesiredIconDimension()); outergridbag.setConstraints(dqp, outerc); symbolPanel.add(dqp); add(symbolPanel); // /////////////////// optionPanel = PaletteHelper.createVerticalPanel(" Symbol Attributes "); optionPanel.add(((SymbolTreeHolder) setChoices.getSelectedItem()).getOptionPanel()); outergridbag.setConstraints(optionPanel, outerc); add(optionPanel); // /////////////////// // gridbag2 is for the name panel and the recent symbols. GridBagLayout gridbag2 = new GridBagLayout(); GridBagConstraints c2 = new GridBagConstraints(); JPanel namePanel = new JPanel(); namePanel.setLayout(gridbag2); c2.weightx = 0; c2.anchor = GridBagConstraints.WEST; JLabel nameLabel = new JLabel("Symbol Code: "); gridbag2.setConstraints(nameLabel, c2); namePanel.add(nameLabel); c2.fill = GridBagConstraints.HORIZONTAL; c2.weightx = 1.0; if (nameField == null) { nameField = new JTextField(EMPTY_CODE); } nameField.addActionListener(this); nameField.setActionCommand(NAMEFIELD_CMD); gridbag2.setConstraints(nameField, c2); namePanel.add(nameField); createImageFileButton = new JButton("Create Image File"); createImageFileButton.addActionListener(this); createImageFileButton.setActionCommand(CREATE_IMAGE_CMD); createImageFileButton.setEnabled(false); createImageFileButton.setVisible(allowCreateImage); c2.weightx = 0.0; gridbag2.setConstraints(createImageFileButton, c2); namePanel.add(createImageFileButton); outerc.weighty = 0.0; outerc.gridwidth = GridBagConstraints.REMAINDER; outergridbag.setConstraints(namePanel, outerc); add(namePanel); // /////////////////// // Just call this to make sure that the stuff in the name // field matches the selected JTree setSelectedTreeHolder(currentSymbolTreeHolder); } public void actionPerformed(ActionEvent ae) { String command = ae.getActionCommand(); if (command == CREATE_IMAGE_CMD && library != null && nameField != null) { try { setDesiredIconDimension(dqp.getDimension()); } catch (NumberFormatException e) { JOptionPane.showMessageDialog(this, "Width and height must be integers.", "Warning", JOptionPane.WARNING_MESSAGE); return; } Dimension d = getDesiredIconDimension(); ImageIcon ii = library.getIcon(getCode(), d); if (ii == null) { createImageFileButton.setEnabled(false); return; } try { BufferedImage bi = BufferedImageHelper.getBufferedImage(ii.getImage(), 0, 0, (int) d.getWidth(), (int) d.getHeight(), BufferedImage.TYPE_INT_ARGB); ImageFormatter formatter = new AcmeGifFormatter(); byte[] imageBytes = formatter.formatImage(bi); String newFileName = FileUtils.getFilePathToSaveFromUser("Create File To Save"); if (newFileName != null) { FileOutputStream fos = new FileOutputStream(newFileName); fos.write(imageBytes); fos.flush(); fos.close(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } if (command == NAMEFIELD_CMD) { handleManualNameFieldUpdate(getCode()); } } /** * Update the GUI to react to code typed into the string window. * * @param text */ protected void handleManualNameFieldUpdate(String text) { if (text == null) return; if (text.length() > 15) { text = text.substring(0, 15); } text = text.toUpperCase().replace('*', '-'); for (Iterator it = trees.iterator(); it.hasNext();) { SymbolTreeHolder sth = (SymbolTreeHolder) it.next(); if (sth != null) { DefaultMutableTreeNode node = sth.getNodeForCode(text); if (node != null) { if (Debug.debugging("symbology")) { Debug.output("SymbolChooser: Found node for " + text); } sth.getTree() .setSelectionPath(new TreePath(node.getPath())); sth.updateOptionsForCode(text); setSelectedTreeHolder(sth); } } } } /** * Initialization method to create the SymbolTreeHolders from the * SymbolReferenceLibrary. * * @param srl * @return List of nodes of the symbol part tree. * @throws FormatException */ protected List createNodes(SymbolReferenceLibrary srl) throws FormatException { List treeList = new LinkedList(); List subs = srl.getHead().getSubs(); int count = 1; if (subs != null) { for (Iterator it = subs.iterator(); it.hasNext();) { SymbolPart schemeSymbolPart = (SymbolPart) it.next(); CodeOptions options = ((CodeScheme) srl.positionTree.getFromChoices(count++)).getCodeOptions(null); treeList.add(new SymbolTreeHolder(schemeSymbolPart, options)); } } return treeList; } /** * Get the current symbol code listed in the GUI. * * @return code for current symbol. */ public String getCode() { if (nameField != null) return nameField.getText(); return EMPTY_CODE; } /** * Set the symbol code in the GUI. */ public void setCode(String code) { if (nameField == null) { // If we do this here, the default jtree presented // will be able to put it's default symbol code in the // text field widget. Has to be done before that // default JTree is made. nameField = new JTextField(code); } else { nameField.setText(code); } } /** * Get the icon displayed in the GUI. * * @return ImageIcon being displayed. */ public ImageIcon getImageIcon() { return symbolImage; } /** * Set the current icon in the display. * * @param ii */ public void setImageIcon(ImageIcon ii) { symbolImage = ii; if (symbolImageLabel == null) { symbolImageLabel = new JLabel(symbolImage); } else { symbolImageLabel.setIcon(symbolImage); } } /** * Set the dimension o the icon to be created. * * @param d */ public void setDesiredIconDimension(Dimension d) { iconDimension = d; dqp.setDimension(getDesiredIconDimension()); } /** * @return the dimension of the icon to be created. */ public Dimension getDesiredIconDimension() { if (iconDimension == null) { iconDimension = new Dimension(DEFAULT_ICON_DIMENSION, DEFAULT_ICON_DIMENSION); } return iconDimension; } /** * @return Returns the allowCreateImage. */ public boolean isAllowCreateImage() { return allowCreateImage; } /** * @param allowCreateImage The allowCreateImage to set. */ public void setAllowCreateImage(boolean allowCreateImage) { this.allowCreateImage = allowCreateImage; if (createImageFileButton != null) { createImageFileButton.setVisible(allowCreateImage); } } public static ImageIcon showDialog(Component component, String title, SymbolReferenceLibrary srl, String defaultSymbolCode) throws HeadlessException { final SymbolChooser pane = new SymbolChooser(srl); SymbolTracker ok = new SymbolTracker(pane); JDialog dialog = createDialog(component, title, true, pane, ok, null); dialog.addWindowListener(new SymbolChooserDialog.Closer()); dialog.addComponentListener(new SymbolChooserDialog.DisposeOnClose()); pane.setCode(defaultSymbolCode); pane.handleManualNameFieldUpdate(defaultSymbolCode); dialog.setVisible(true); // blocks until user brings dialog down... return ok.getImageIcon(); } /** * Creates JDialog window displaying a SymbolChooser. */ public static JDialog createDialog(Component c, String title, boolean modal, SymbolChooser chooserPane, ActionListener okListener, ActionListener cancelListener) throws HeadlessException { return new SymbolChooserDialog(c, title, modal, chooserPane, okListener, cancelListener); } public static void main(String[] args) { Debug.init(); ArgParser ap = new ArgParser("SymbolChooser"); ap.add("type", "Type of symbol image set being used (PNG, GIF or SVG, PNG is default)", 1); ap.add("path", "Path to root directory of symbol image set if not in classpath", 1); ap.add("default", "15 character code for default icon", 1); ap.add("verbose", "Print messages"); if (!ap.parse(args)) { ap.printUsage(); System.exit(0); } String arg[]; arg = ap.getArgValues("type"); String symbolImageMakerClass = "com.bbn.openmap.tools.symbology.milStd2525.PNGSymbolImageMaker"; if (arg != null) { if (arg[0].equalsIgnoreCase("SVG")) { symbolImageMakerClass = "com.bbn.openmap.tools.symbology.milStd2525.SVGSymbolImageMaker"; } else if (arg[0].equalsIgnoreCase("GIF")) { symbolImageMakerClass = "com.bbn.openmap.tools.symbology.milStd2525.GIFSymbolImageMaker"; } } String defaultSymbolCode = "SFPPV-----*****"; arg = ap.getArgValues("default"); if (arg != null) { defaultSymbolCode = arg[0]; } arg = ap.getArgValues("verbose"); if (arg != null) { Debug.put("symbology"); } SymbolReferenceLibrary srl = new SymbolReferenceLibrary(); if (srl.setSymbolImageMaker(symbolImageMakerClass) != null) { arg = ap.getArgValues("path"); if (arg != null) { srl.getSymbolImageMaker().setDataPath(arg[0]); } SymbolChooser.showDialog(null, "MIL-STD-2525B Symbol Chooser", srl, defaultSymbolCode); } else { Debug.output("Couldn't create SymbolImageMaker"); } System.exit(0); } public class SymbolTreeHolder extends ListenerSupport implements TreeSelectionListener { // Optionally play with line styles. Possible values are // "Angled", "Horizontal", and "None" (the default). protected boolean playWithTreeLineStyle = false; protected String treeLineStyle = "Angled"; protected JTree tree; protected JPanel optionPanel; protected CodeOptions options; protected Character[] optionChars = new Character[15]; protected Hashtable optionMenuHashtable; public SymbolTreeHolder(SymbolPart schemeSymbolPart, CodeOptions opts) { super(schemeSymbolPart); DefaultMutableTreeNode top = new DefaultMutableTreeNode(schemeSymbolPart); addNodes(top, schemeSymbolPart); tree = new JTree(top); tree.getSelectionModel() .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.setVisibleRowCount(10); tree.addTreeSelectionListener(this); tree.setSelectionPath(new TreePath(top)); if (playWithTreeLineStyle) { tree.putClientProperty("JTree.lineStyle", treeLineStyle); } options = opts; optionPanel = getOptionPanel(); } public JTree getTree() { return tree; } protected void addNodes(DefaultMutableTreeNode node, SymbolPart sp) { DefaultMutableTreeNode newNode = null; List subs = sp.getSubs(); if (subs != null) { for (Iterator it = subs.iterator(); it.hasNext();) { sp = (SymbolPart) it.next(); newNode = new DefaultMutableTreeNode(sp); node.add(newNode); addNodes(newNode, sp); } } } public DefaultMutableTreeNode getNodeForCode(String code) { DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel() .getRoot(); SymbolPart sp = (SymbolPart) root.getUserObject(); if (Debug.debugging("symbology.detail")) { Debug.output("Tree root object has " + sp.getClass().getName() + " user object with code |" + sp.getCode() + "| at code position " + sp.getCodePosition().startIndex); } if (sp.codeMatches(code)) { return getNodeForCodeStartingAt(root, code); } else { return null; } } protected DefaultMutableTreeNode getNodeForCodeStartingAt( DefaultMutableTreeNode node, String code) { Enumeration enumeration = node.children(); while (enumeration.hasMoreElements()) { DefaultMutableTreeNode kid = (DefaultMutableTreeNode) enumeration.nextElement(); SymbolPart ssp = (SymbolPart) kid.getUserObject(); try { if (code.charAt(ssp.getCodePosition().startIndex) == '-') return node; if (ssp.codeMatches(code)) { return getNodeForCodeStartingAt(kid, code); } } catch (StringIndexOutOfBoundsException sioobe) { } catch (NullPointerException npe) { } } return node; } /** * Given an text string, have the options available to the current * SymbolTreeHolder reflect those updates. * * @param text */ protected void updateOptionsForCode(String text) { for (Iterator it = options.getOptions().iterator(); it.hasNext();) { CodePosition cp = (CodePosition) it.next(); JComboBox jcb = (JComboBox) optionMenuHashtable.get(cp); if (jcb != null) { int numComps = jcb.getItemCount(); for (int i = 0; i < numComps; i++) { if (((CodePosition) jcb.getItemAt(i)).codeMatches(text)) { jcb.setSelectedIndex(i); break; } } } } } public void valueChanged(TreeSelectionEvent e) { handleNodeSelection((DefaultMutableTreeNode) tree.getLastSelectedPathComponent()); } public void updateInterfaceToLastSelectedNode() { handleNodeSelection((DefaultMutableTreeNode) tree.getLastSelectedPathComponent()); } public void handleNodeSelection(DefaultMutableTreeNode node) { if (node == null) { setCode(""); return; } Object nodeInfo = node.getUserObject(); if (nodeInfo instanceof SymbolPart) { SymbolPart symbolPart = (SymbolPart) nodeInfo; currentSymbol = node; setCode(updateStringWithCurrentOptionChars(symbolPart.getSymbolCode())); ImageIcon ii = library.getIcon(getCode(), new Dimension(DEFAULT_ICON_DIMENSION, DEFAULT_ICON_DIMENSION)); if (createImageFileButton != null) { createImageFileButton.setEnabled(ii != null); } if (ii == null) { ii = getNotFoundImageIcon(); } setImageIcon(ii); } else { setCode(""); setImageIcon(getNotFoundImageIcon()); createImageFileButton.setEnabled(false); } } public JPanel getOptionPanel() { if (optionPanel == null) { optionMenuHashtable = new Hashtable(); optionPanel = new JPanel(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); optionPanel.setLayout(gridbag); if (options != null) { int i = 0; for (Iterator it = options.getOptions().iterator(); it.hasNext();) { CodePosition cp = (CodePosition) it.next(); List lt = cp.getPositionChoices(); if (lt != null) { JLabel label = new JLabel(cp.getPrettyName() + ": "); c.gridx = 0; c.gridy = i++; c.weightx = 0; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; gridbag.setConstraints(label, c); optionPanel.add(label); JComboBox jcb = new JComboBox(lt.toArray()); jcb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { setPositionSetting((CodePosition) ((JComboBox) ae.getSource()).getSelectedItem()); updateInterfaceToLastSelectedNode(); } }); c.gridx = 1; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1f; gridbag.setConstraints(jcb, c); optionPanel.add(jcb); optionMenuHashtable.put(cp, jcb); } } } else { optionPanel.add(new JLabel("No options available for these symbols.")); } } return optionPanel; } public void setPositionSetting(CodePosition cp) { if (Debug.debugging("codeposition")) { Debug.output("Setting " + cp.getPrettyName() + " [" + cp.getID() + "] at " + cp.getStartIndex() + ", " + cp.getEndIndex()); } updateOptionChars(cp); setCode(updateStringWithCurrentOptionChars(getCode())); } public void updateOptionChars(CodePosition cp) { String cpString = cp.getID(); for (int i = 0; i < cpString.length(); i++) { char curChar = cpString.charAt(i); optionChars[cp.getStartIndex() + i] = new Character(curChar); } } public String updateStringWithCurrentOptionChars( String currentSymbolCode) { try { StringBuffer buf = new StringBuffer(currentSymbolCode); for (int i = 0; i < optionChars.length; i++) { Character c = optionChars[i]; if (c != null) { buf.setCharAt(i, c.charValue()); } } currentSymbolCode = buf.toString(); } catch (StringIndexOutOfBoundsException siobe) { } catch (NullPointerException npe) { } return currentSymbolCode; } public String toString() { return ((SymbolPart) getSource()).getCodePosition().getPrettyName(); } } } /* * Class which builds a symbol chooser dialog consisting of a SymbolChooser with * "Ok", "Cancel", and "Reset" buttons. This class is based on the contents of * the JColorChooser components. */ class SymbolChooserDialog extends JDialog { private String initialCode; private SymbolChooser chooserPane; public SymbolChooserDialog(Component c, String title, boolean modal, SymbolChooser chooserPane, ActionListener okListener, ActionListener cancelListener) throws HeadlessException { super(JOptionPane.getFrameForComponent(c), title, modal); this.chooserPane = chooserPane; String okString = UIManager.getString("ColorChooser.okText"); String cancelString = UIManager.getString("ColorChooser.cancelText"); String resetString = UIManager.getString("ColorChooser.resetText"); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(chooserPane, BorderLayout.CENTER); /* * Create Lower button panel */ JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); JButton okButton = new JButton(okString); getRootPane().setDefaultButton(okButton); okButton.setActionCommand("OK"); if (okListener != null) { okButton.addActionListener(okListener); } okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); } }); buttonPane.add(okButton); JButton cancelButton = new JButton(cancelString); cancelButton.setActionCommand("cancel"); if (cancelListener != null) { cancelButton.addActionListener(cancelListener); } cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); } }); buttonPane.add(cancelButton); JButton resetButton = new JButton(resetString); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { reset(); } }); buttonPane.add(resetButton); contentPane.add(buttonPane, BorderLayout.SOUTH); applyComponentOrientation(((c == null) ? getRootPane() : c).getComponentOrientation()); pack(); setLocationRelativeTo(c); } public void setVisible(boolean val) { if (val) { initialCode = chooserPane.getCode(); } super.setVisible(val); } public void reset() { chooserPane.setCode(initialCode); chooserPane.handleManualNameFieldUpdate(initialCode); } static class Closer extends WindowAdapter implements Serializable { public void windowClosing(WindowEvent e) { Window w = e.getWindow(); w.setVisible(false); } } static class DisposeOnClose extends ComponentAdapter implements Serializable { public void componentHidden(ComponentEvent e) { Window w = (Window) e.getComponent(); w.dispose(); } } } class SymbolTracker implements ActionListener, Serializable { SymbolChooser chooser; ImageIcon icon; public SymbolTracker(SymbolChooser c) { chooser = c; } public void actionPerformed(ActionEvent e) { // This is subject to too many timing problems, it's easier if we just get the icon // when asked in getImageIcon. // icon = chooser.library.getIcon(chooser.getCode(), // chooser.getDesiredIconDimension()); } public ImageIcon getImageIcon() { try { return chooser.library.getIcon(chooser.getCode(), chooser.getDesiredIconDimension()); } catch (NullPointerException npe) { Debug.error("SymbolChooser.SymbolTracker: something messed up with chooser:"); npe.printStackTrace(); } return null; } }