/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * Copyright (C) 1999 New Zealand Digital Library Project * * 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 * (at your option) 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.cdm; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.undo.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.ws.Dispatch; import org.fife.ui.rsyntaxtextarea.*; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.gui.DesignPaneHeader; import org.greenstone.gatherer.gui.GLIButton; import org.greenstone.gatherer.gui.FormatPane; import org.greenstone.gatherer.metadata.MetadataElement; import org.greenstone.gatherer.metadata.MetadataSetManager; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.Utility; import org.greenstone.gatherer.util.XMLTools; import org.w3c.dom.*; import org.xml.sax.InputSource; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.io.ByteArrayInputStream; /** * This class maintains a list of format statements, and allows the addition and * removal of these statements. This is the greenstone 3 equivalent class of * FormatManager.java which is used by greenstone 2 */ public class Format4gs3Manager implements SharedByTwoFormatManager { // The default global format static final private String GLOBAL_FORMAT; static { // @formatter:off String GLOBAL_FORMAT_TEMP = "" + "" + "" + "" + "" + "" + "" + "Untitled" + "" + ""; GLOBAL_FORMAT = GLOBAL_FORMAT_TEMP; // @formatter:on } static final private String GLOBAL = "global"; //The default search format static final private String SEARCH_FORMAT; static { // @formatter:off String SEARCH_FORMAT_TEMP = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; SEARCH_FORMAT = SEARCH_FORMAT_TEMP; // @formatter:on } static final private String SEARCH = "search"; static final private String DISPLAY_DEFAULT_FORMAT; static { // @formatter:off String DISPLAY_DEFAULT_FORMAT_TEMP = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; // @formatter:on DISPLAY_DEFAULT_FORMAT = DISPLAY_DEFAULT_FORMAT_TEMP; } static final private String DISPLAY = "display"; //The default browse format static final private String CLASSIFIER_DEFAULT_FORMAT; static { // @formatter:off String CLASSIFIER_DEFAULT_FORMAT_TEMP = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
()
" + "
" + "" + "
" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
()
" + "
" + "" + "
" + "" + "" + "" + "" + ""; CLASSIFIER_DEFAULT_FORMAT = CLASSIFIER_DEFAULT_FORMAT_TEMP; // @formatter:on } static final private String CLASSIFIER_DEFAULT = "browse"; static final private String SEARCHTYPE_FORMAT = "plain,simpleform,advancedform"; static final private String SEARCHTYPE = "searchType"; static final private String[] FEATURE_NAME = { SEARCH, GLOBAL, DISPLAY, CLASSIFIER_DEFAULT, SEARCHTYPE }; static final private String[] FEATURE_FORMAT = { SEARCH_FORMAT, GLOBAL_FORMAT, DISPLAY_DEFAULT_FORMAT, CLASSIFIER_DEFAULT_FORMAT, SEARCHTYPE_FORMAT }; static private HashMap default_format_map = null; static private HashMap default_format_formated_map = null; /** The controls used to edit the format commands. */ private Control controls = null;// an interface /** A reference */ private DOMProxyListModel format_list_model = null; //private DOMProxyListModel feature_list_model = null; /** Constructor. */ public Format4gs3Manager() {//pass the internal structure Element root = CollectionDesignManager.collect_config.getDocumentElement(); format_list_model = new DOMProxyListModel(root, StaticStrings.FORMAT_STR, new Format4gs3()); initDefault(format_list_model, FEATURE_NAME, FEATURE_FORMAT); initFormatMap(FEATURE_NAME, FEATURE_FORMAT); } private void initFormatMap(String[] feature_name, String[] feature_format) { default_format_map = new HashMap(); default_format_formated_map = new HashMap(); for (int i = 0; i < feature_name.length; i++) { default_format_map.put(feature_name[i], feature_format[i]); default_format_formated_map.put(feature_name[i], Format4gs3.toFormatedFormat(feature_format[i])); } } public void initDefault(DOMProxyListModel model, String[] feature_name, String[] feature_format) { // Establish all of the format objects. for (int i = 0; i < model.getSize(); i++) { model.getElementAt(i);//get those objects cached } for (int i = 0; i < feature_name.length; i++) { if (getFormat(model, feature_name[i]) == null) { model.add(new Format4gs3(feature_name[i], feature_format[i])); } } } /** * Method to remove a format. * * @param format * The Format to remove. */ private void removeFormat(DOMProxyListModel model, Format4gs3 format) { model.remove(format); } private Format4gs3 getFormat(DOMProxyListModel model, String name) { for (int index = 0; index < model.getSize(); index++) { Format4gs3 format = (Format4gs3) model.getElementAt(index); if (format.getFeatureName().equals(name)) { return format; } } return null; } private void addFormat(Element parent, Format4gs3 format) { if (!format_list_model.contains(format)) { format_list_model.add(parent, format, null); } } public void destroy() { if (controls != null) { controls.destroy(); controls = null; } } /** * Method to retrieve this managers controls. * * @return the Control for this collection. */ public Control getControls() { if (controls == null) { controls = new FormatControl(); } //controls.gainFocus(); return controls; } /** * Called when the detail mode has changed which in turn may cause several * design elements to be available/hidden * * @param mode * the new mode as an int */ public void modeChanged(int mode) { } /** updates the format and feature model */ public synchronized void refresh() { for (int i = 0; i < format_list_model.getSize(); i++) { Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i); format.update(); format = null; } //call the gainFocus() and in turn the buildFeatureModel() method to get the feature combobox refreshed as well if (controls == null) { controls = new FormatControl(); } controls.gainFocus(); //format_list_model.refresh(); //this call is not necessary as it is included in gainFocus() } private ArrayList buildFeatureModel() { // Rebuild feature model. ArrayList feature_model = new ArrayList(); //This will display 'choose a feature' and is used when the format feature panel is first gained focus feature_model.add(new Entry("")); for (int i = 0; i < format_list_model.getSize(); i++) { Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i); String feature_name = format.getFeatureName(); if (!feature_name.startsWith(Classifier.CLASSIFIER_PREFIX)) { feature_model.add(new Entry(format.getFeatureName())); } } // Now the classifiers. Element root = CollectionDesignManager.collect_config.getDocumentElement(); NodeList classifier_list = root.getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT); for (int j = 0; j < classifier_list.getLength(); j++) { feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j))); } //Collections.sort (feature_model); return feature_model; } private String addSurroundingTags(String xml) { return "" + xml + ""; } private String removeSurrondingTags(String xml) { return xml.replace("\n", "").replace("", "").replace("", "").replace("",""); } public class FormatControl extends JPanel implements Control { private ArrayList feature_model; private boolean ignore_event = false; private boolean ready = false; // Are these controls available to be refreshed private JButton add_button; private JButton remove_button; private JButton default_button; private JButton undo_button; private JButton redo_button; private JComboBox feature_combobox; private JList format_list; private NumberedJTextArea editor_textarea; private JTextArea editor_msgarea; private JPanel validation_msg_panel; private JPanel selection_pane; private final Dimension FIELD_SIZE = new Dimension(200, 30); private final UndoManager undo = new UndoManager(); private boolean newtext = true; private Format4gs3 previousFormat = null; private Format4gs3 currentFormat = null; private boolean fresh = true; public FormatControl() { feature_model = buildFeatureModel(); // Create JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements"); format_list = new JList(format_list_model); selection_pane = new JPanel(); JPanel feature_pane = new JPanel(); JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature")); feature_combobox = new JComboBox(feature_model.toArray()); feature_combobox.setOpaque(!Utility.isMac()); feature_combobox.setPreferredSize(FIELD_SIZE); feature_combobox.setEditable(false); feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip")); JPanel center_pane = new JPanel(); JPanel editor_pane = new JPanel(); editor_textarea = new NumberedJTextArea(); /* Fields specific to RSyntaxQuery inherited class */ editor_textarea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML); editor_textarea.setBracketMatchingEnabled(true); editor_textarea.setAnimateBracketMatching(true); editor_textarea.setAntiAliasingEnabled(true); editor_textarea.setAutoIndentEnabled(true); editor_textarea.setPaintMarkOccurrencesBorder(false); /* Standard fields to JTextArea */ editor_textarea.setOpaque(false); editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false)); editor_textarea.setCaretPosition(0); editor_textarea.setLineWrap(true); editor_textarea.setRows(11); editor_textarea.setWrapStyleWord(false); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Add_Tooltip")); default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip")); JPanel button_pane = new JPanel(); add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip")); add_button.setEnabled(false); remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip")); remove_button.setEnabled(false); undo_button = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip")); undo_button.setEnabled(false); redo_button = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip")); redo_button.setEnabled(false); // Connect add_button.addActionListener(new AddListener()); remove_button.addActionListener(new RemoveListener()); default_button.addActionListener(new DefaultListener()); undo_button.addActionListener(new UndoListener()); redo_button.addActionListener(new RedoListener()); feature_combobox.addActionListener(new FeatureListener()); editor_textarea.getDocument().addDocumentListener(new EditorListener()); // Listen for undo and redo events editor_textarea.getDocument().addUndoableEditListener(new UndoableEditListener() { public void undoableEditHappened(UndoableEditEvent evt) { undo.addEdit(evt.getEdit()); } }); format_list.addListSelectionListener(new FormatListListener()); // Layout JPanel format_list_pane = new JPanel(); format_list_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); format_list_pane.setLayout(new BorderLayout()); format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER); feature_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); feature_pane.setLayout(new BorderLayout(5, 0)); feature_pane.add(feature_label, BorderLayout.WEST); feature_pane.add(feature_combobox, BorderLayout.CENTER); JPanel rupanel = new JPanel(); rupanel.setLayout(new GridLayout(1, 2)); rupanel.add(undo_button); rupanel.add(redo_button); editor_pane.setLayout(new BorderLayout()); editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER); validation_msg_panel = new JPanel(); JLabel validation_label = new JLabel(Dictionary.get("CDM.FormatManager.MessageBox")); editor_msgarea = new JTextArea(); editor_msgarea.setCaretPosition(0); editor_msgarea.setLineWrap(true); editor_msgarea.setRows(3); editor_msgarea.setWrapStyleWord(false); editor_msgarea.setEditable(false); editor_msgarea.setToolTipText(Dictionary.get("CDM.FormatManager.MessageBox_Tooltip")); validation_msg_panel.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); validation_msg_panel.setLayout(new BorderLayout(5, 0)); validation_msg_panel.add(validation_label, BorderLayout.WEST); validation_msg_panel.add(new JScrollPane(editor_msgarea), BorderLayout.CENTER); selection_pane.setLayout(new BorderLayout()); selection_pane.add(validation_msg_panel, BorderLayout.NORTH); selection_pane.add(rupanel, BorderLayout.SOUTH); selection_pane.add(editor_pane, BorderLayout.CENTER); button_pane.setLayout(new GridLayout(1, 3)); button_pane.add(add_button); button_pane.add(remove_button); button_pane.add(default_button); center_pane.setLayout(new BorderLayout()); center_pane.add(feature_pane, BorderLayout.NORTH); center_pane.add(selection_pane, BorderLayout.CENTER); center_pane.add(button_pane, BorderLayout.SOUTH); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.add(format_list_pane, JSplitPane.TOP); splitPane.add(center_pane, JSplitPane.BOTTOM); splitPane.setDividerLocation(150); setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); setLayout(new BorderLayout()); add(header_pane, BorderLayout.NORTH); add(splitPane, BorderLayout.CENTER); ready = true; } public void destroy() { } /** * Overriden to ensure that the instructions pane is scrolled to the * top. */ public void gainFocus() { if (ready) { format_list_model.refresh(); // Update the feature model, trying to maintain the same selected object Object selected_feature = feature_combobox.getSelectedItem(); feature_combobox.setSelectedItem(selected_feature); feature_model = buildFeatureModel(); feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray())); } } public void loseFocus() { //validate the templates. If not wellformed, pop up an alert; otherwise, do nothing. String msg = XMLTools.parse(editor_textarea.getText()); if (msg.startsWith(XMLTools.NOTWELLFORMED)) { JOptionPane.showMessageDialog(null, msg, XMLTools.NOTWELLFORMED, JOptionPane.ERROR_MESSAGE); } format_list_model.refresh(); } public Format4gs3 getCurrentFormat() { return (Format4gs3) format_list.getSelectedValue(); } /** * Listens for clicks on the add button, and if the relevant details are * provided adds a new format. Note that formats are responsible for * codecing the values into something that can be a) stored in a DOM and * b) written to file */ private class AddListener implements ActionListener { public void actionPerformed(ActionEvent event) { ignore_event = true; // Prevent format_list excetera propagating events String format_str = editor_textarea.getText(); Entry entry = (Entry) feature_combobox.getSelectedItem(); String feature_name = entry.getClassifier().getPositionString(); Format4gs3 format = new Format4gs3(feature_name, format_str); Element e = format.getClassifyElement(); addFormat(e, format); existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX)); // set the appropriate enable/disable on the interface // Update list selection (make the new added format highlighted on the format list panel) format_list.setSelectedValue(format, true); format = null; ignore_event = false; } } private class EditorListener implements DocumentListener { public void changedUpdate(DocumentEvent e) { update(); } public void insertUpdate(DocumentEvent e) { update(); updateUndo("insert"); } public void removeUpdate(DocumentEvent e) { update(); updateUndo("remove"); } private void updateUndo(String from) { if (!newtext) { undo_button.setEnabled(true); } if (editor_textarea.getText().length() != 0 && newtext) { newtext = false; } } public void update() { if (!format_list.isSelectionEmpty()) { Format4gs3 format = (Format4gs3) format_list.getSelectedValue(); String format_str = editor_textarea.getText(); String msg = XMLTools.parse(format_str); editor_msgarea.setText(msg); if (msg.startsWith(XMLTools.WELLFORMED)) { format.setPureFormat(format_str); format.update(); format_list_model.refresh(format); editor_msgarea.setBackground(Color.white); FormatPane.setPreviewButton(true); } else { editor_msgarea.setBackground(Color.red); FormatPane.setPreviewButton(false); } } else { add_button.setEnabled(false); } } } private class FeatureListener implements ActionListener { public void actionPerformed(ActionEvent event) { undo_button.setEnabled(false); redo_button.setEnabled(false); default_button.setEnabled(true); newtext = true; if (ignore_event == true) { undo.discardAllEdits(); return; } ignore_event = true; // Add is only enabled if there isn't already a format for the choosen feature and part. //Create a dummy format and test if itsa already in the model Entry entry = (Entry) feature_combobox.getSelectedItem(); String feature_name = entry.getFeatureName(); Format4gs3 format = getFormat(format_list_model, feature_name); if (format != null) { ///ystem.err.println("There is an existing format!"); format_list.setSelectedValue(format, true); Element formatElem = null; try { InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8"))); formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement(); } catch (Exception ex) { ex.printStackTrace(); } if (formatElem != null) { StringBuffer sb = new StringBuffer(); XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0); editor_textarea.setText(removeSurrondingTags(sb.toString())); } else { editor_textarea.setText(format.getPureFormat()); } editor_textarea.setCaretPosition(0); existingFormat(feature_name.startsWith(Classifier.CLASSIFIER_PREFIX)); } // Otherwise there is no existing format, then this feature must be a classifier (CL1, 2, ...) // we display the ClassifierDefault for this format else { //Fist reset the format list panel format_list.clearSelection(); if (feature_name.equals("")) { editor_textarea.setText(""); } else { //Only for debugging purposes if (entry.getClassifier() == null) { DebugStream.println("It should be a classifier or choose a feature. What is it? " + entry.toString()); } editor_textarea.setText(Format4gs3.toFormatedFormat(CLASSIFIER_DEFAULT_FORMAT)); editor_textarea.setCaretPosition(0); newFormat(); } } ignore_event = false; undo.discardAllEdits(); } } private class FormatListListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { undo_button.setEnabled(false); redo_button.setEnabled(false); default_button.setEnabled(true); newtext = true; if (!ignore_event && !event.getValueIsAdjusting()) { if (!format_list.isSelectionEmpty()) { ignore_event = true; Format4gs3 format = (Format4gs3) format_list.getSelectedValue(); String feature_name = format.getFeatureName(); Entry entry = null; if (feature_name.startsWith(Classifier.CLASSIFIER_PREFIX)) { entry = new Entry(format.getClassifier()); } else { entry = new Entry(feature_name); } feature_combobox.setSelectedItem(entry); existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX)); Element formatElem = null; try { InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8"))); formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement(); } catch (Exception ex) { ex.printStackTrace(); } if (formatElem != null) { StringBuffer sb = new StringBuffer(); XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0); editor_textarea.setText(removeSurrondingTags(sb.toString())); } else { editor_textarea.setText(format.getPureFormat()); } editor_textarea.setCaretPosition(0); ignore_event = false; } } undo.discardAllEdits(); } } private class RemoveListener implements ActionListener { public void actionPerformed(ActionEvent event) { if (!format_list.isSelectionEmpty()) { // Remove the current format Format4gs3 format = (Format4gs3) format_list.getSelectedValue(); removeFormat(format_list_model, format); // Change buttons add_button.setEnabled(true); feature_combobox.setSelectedItem(new Entry("")); newFormat(); } } } private class DefaultListener implements ActionListener { public void actionPerformed(ActionEvent event) { newtext = false; if (!ignore_event) { Entry entry = (Entry) feature_combobox.getSelectedItem(); String feature_name = entry.getFeatureName(); Format4gs3 format = getFormat(format_list_model, feature_name); if (format != null) { if (format.isClassifier() == true) { editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT)); editor_textarea.setCaretPosition(0); remove_button.setEnabled(true); } else { editor_textarea.setText((String) default_format_formated_map.get(format.getFeatureName())); editor_textarea.setCaretPosition(0); remove_button.setEnabled(false); } } else { editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT)); editor_textarea.setCaretPosition(0); remove_button.setEnabled(false); add_button.setEnabled(true); } } } } private class UndoListener implements ActionListener { public void actionPerformed(ActionEvent event) { try { if (undo.canUndo()) { int pos = editor_textarea.getCaretPosition(); redo_button.setEnabled(true); undo.undo(); if (pos > 0) editor_textarea.setCaretPosition(pos - 1); else editor_textarea.setCaretPosition(pos); } if (!undo.canUndo()) { undo_button.setEnabled(false); } else { undo_button.setEnabled(true); } } catch (Exception e) { } } } private class RedoListener implements ActionListener { public void actionPerformed(ActionEvent evt) { try { if (undo.canRedo()) { int pos = editor_textarea.getCaretPosition(); undo.redo(); editor_textarea.setCaretPosition(pos); } if (!undo.canRedo()) { redo_button.setEnabled(false); } else { redo_button.setEnabled(true); } } catch (Exception e) { } } } private void newFormat() { editor_textarea.setEditable(false); editor_textarea.setBackground(Color.lightGray); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip")); undo_button.setEnabled(false); redo_button.setEnabled(false); add_button.setEnabled(true); remove_button.setEnabled(false); default_button.setEnabled(false); FormatPane.setPreviewButton(true); } private void existingFormat(boolean enableRemoveButton) { editor_textarea.setEditable(true); editor_textarea.setBackground(Color.white); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip")); add_button.setEnabled(false); remove_button.setEnabled(enableRemoveButton); default_button.setEnabled(true); FormatPane.setPreviewButton(true); } /** * A textarea with the line number next to each line of the text */ public class NumberedJTextArea extends RSyntaxTextArea /* JTextArea */ { public void paintComponent(Graphics g) { Insets insets = getInsets(); Rectangle rectangle = g.getClipBounds(); g.setColor(Color.white); g.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); super.paintComponent(g); if (rectangle.x < insets.left) { FontMetrics font_metrics = g.getFontMetrics(); int font_height = font_metrics.getHeight(); int y = font_metrics.getAscent() + insets.top; int line_number_start_point = ((rectangle.y + insets.top) / font_height) + 1; if (y < rectangle.y) { y = line_number_start_point * font_height - (font_height - font_metrics.getAscent()); } int y_axis_end_point = y + rectangle.height + font_height; int x_axis_start_point = insets.left; x_axis_start_point -= getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " "); if (!this.getText().trim().equals("")) { g.setColor(Color.DARK_GRAY); } else { g.setColor(Color.white); } int length = ("" + Math.max(getRows(), getLineCount() + 1)).length(); while (y < y_axis_end_point) { g.drawString(line_number_start_point + " ", x_axis_start_point, y); y += font_height; line_number_start_point++; } } } public Insets getInsets() { Insets insets = super.getInsets(new Insets(0, 0, 0, 0)); insets.left += getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " "); return insets; } } } /** * This object provides a wrapping around an entry in Format4gs3, which is * tranparent. */ // This class is used for display in the feature combobox private class Entry implements Comparable { private Classifier classifier = null; private String feature_name = null; public Entry(Object object) { if (object instanceof Classifier) { classifier = (Classifier) object; feature_name = classifier.getPositionString(); } else if (object instanceof String) { feature_name = (String) object; } else { feature_name = ""; } } public Entry(String text) { this.feature_name = text; } public int compareTo(Object object) { if (object == null) { return 1; } if (toString() == null) { return -1; } else { String object_str = object.toString(); if (object_str == null) { return 1; } return toString().compareTo(object_str); } } public boolean equals(Object object) { if (compareTo(object) == 0) { return true; } return false; } public Classifier getClassifier() { return classifier; } public String toString() { if (classifier != null) { // Return the classifier name - with its CL index shown, and all its metadata options as well return classifier.getPositionString() + StaticStrings.SPACE_CHARACTER + classifier.toString(); } if (feature_name.equals("")) { return "" + "Choose a feature" + ""; } return feature_name; } public String getFeatureName() { return feature_name; } } }