001: // Copyright (c) 2000, 2005 BlueJ Group, Deakin University
002: //
003: // This software is made available under the terms of the "MIT License"
004: // A copy of this license is included with this source distribution
005: // in "license.txt" and is also available at:
006: // http://www.opensource.org/licenses/mit-license.html
007: // Any queries should be directed to Michael Kolling mik@bluej.org
008:
009: package bluej.editor.moe;
010:
011: import java.awt.*;
012: import java.awt.event.*;
013:
014: import javax.swing.*;
015: import javax.swing.text.*;
016:
017: import bluej.*;
018: import bluej.utility.EscapeDialog;
019:
020: /**
021: * Dialog for user to input a line number to traverse source file in editor
022: *
023: * @author Bruce Quig
024: */
025: public class GoToLineDialog extends EscapeDialog implements
026: ActionListener {
027: static final String goToLineTitle = Config
028: .getString("editor.gotoline.title");
029: static final String goToLineLabel = Config
030: .getString("editor.gotoline.label");
031: static final String notNumericMessage = Config
032: .getString("editor.gotoline.notNumericMessage");
033: static final String notInRangeMessage = Config
034: .getString("editor.gotoline.notInRangeMessage");
035: static final int INVALID_NUMBER = -1;
036:
037: // -------- INSTANCE VARIABLES --------
038: private JButton okButton;
039: private JButton cancelButton;
040: private JTextField lineNumberField;
041: private JLabel instructionLabel;
042: private JLabel messageLabel;
043: private int lineNumber = INVALID_NUMBER;
044: private int sizeOfClass;
045:
046: /**
047: * Creates a new GoToLineDialog object.
048: */
049: public GoToLineDialog(Frame owner) {
050: super (owner, goToLineTitle, true);
051: makeDialog();
052: }
053:
054: /**
055: * Make the dialod visible.
056: * @param range the number of lines of source code in source file
057: */
058: public void showDialog(int range) {
059: //getRootPane().setDefaultButton(okButton);
060: sizeOfClass = range;
061: instructionLabel.setText(goToLineLabel + " ( 1 - " + range
062: + " )");
063: lineNumberField.requestFocus();
064: setVisible(true);
065: }
066:
067: // === Actionlistener interface ===
068:
069: /**
070: * A button was pressed. Find out which one and do the appropriate thing.
071: */
072: public void actionPerformed(ActionEvent evt) {
073: Object src = evt.getSource();
074:
075: if (src == okButton) {
076: doOK();
077: } else if (src == cancelButton) {
078: doCancel();
079: }
080: }
081:
082: /**
083: * Setup the dialog
084: */
085: private void makeDialog() {
086: addWindowListener(new WindowAdapter() {
087: public void windowClosing(WindowEvent E) {
088: doCancel();
089: }
090: });
091:
092: JPanel bodyPanel = new JPanel();
093: bodyPanel.setLayout(new BoxLayout(bodyPanel, BoxLayout.Y_AXIS));
094: bodyPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 20,
095: 20));
096:
097: instructionLabel = new JLabel(goToLineLabel);
098: bodyPanel.add(instructionLabel);
099: bodyPanel.add(Box.createVerticalStrut(6));
100:
101: lineNumberField = new JTextField();
102: bodyPanel.add(lineNumberField);
103: bodyPanel.add(Box.createVerticalStrut(6));
104:
105: IntegerDocument integerDocument1 = new IntegerDocument();
106: lineNumberField.setDocument(integerDocument1);
107:
108: messageLabel = new JLabel(" ");
109: bodyPanel.add(messageLabel);
110: bodyPanel.add(Box.createVerticalStrut(6));
111:
112: // add buttons
113: JPanel buttonPanel = new JPanel(
114: new FlowLayout(FlowLayout.RIGHT));
115: buttonPanel.setAlignmentX(LEFT_ALIGNMENT);
116:
117: okButton = BlueJTheme.getOkButton();
118: okButton.addActionListener(this );
119:
120: cancelButton = BlueJTheme.getCancelButton();
121: cancelButton.addActionListener(this );
122:
123: buttonPanel.add(okButton);
124: buttonPanel.add(cancelButton);
125: getRootPane().setDefaultButton(okButton);
126:
127: bodyPanel.add(buttonPanel);
128: getContentPane().add(bodyPanel, BorderLayout.CENTER);
129: pack();
130:
131: }
132:
133: /**
134: * When ok button is selected
135: */
136: private void doOK() {
137: lineNumber = validateInput();
138: clear();
139: setVisible(false);
140: }
141:
142: /**
143: * When cancel button is selected
144: */
145: private void doCancel() {
146: lineNumber = INVALID_NUMBER;
147: setVisible(false);
148: }
149:
150: /**
151: * Clear the line number text field
152: */
153: private void clear() {
154: lineNumberField.setText("");
155: }
156:
157: /**
158: * Returns the lineNumber.
159: * @return the line number entered, returns -1 if input is invalid
160: */
161: public int getLineNumber() {
162: return lineNumber;
163: }
164:
165: /**
166: * Convert input field contents to an int
167: * @return int the String input value as an int
168: * representing line number
169: */
170: private int validateInput() {
171: int validatedNumber = -1;
172: try {
173: validatedNumber = Integer.parseInt(lineNumberField
174: .getText());
175: } catch (NumberFormatException nfe) {
176: //shouldn't happen, verified at data model level
177: }
178: return validatedNumber;
179: }
180:
181: /**
182: * Inner class that provides the formatted (Integer only) data model
183: * for the line number text field
184: */
185: class IntegerDocument extends PlainDocument {
186: /**
187: * Inserts into Document model. Checks for format and for range
188: */
189: public void insertString(int offset, String string,
190: AttributeSet attributes) throws BadLocationException {
191: if (string == null) {
192: return;
193: } else {
194: String newValue;
195: int length = getLength();
196: if (length == 0) {
197: newValue = string;
198: } else {
199: String currentContent = getText(0, length);
200: StringBuffer currentBuffer = new StringBuffer(
201: currentContent);
202: currentBuffer.insert(offset, string);
203: newValue = currentBuffer.toString();
204: }
205: try {
206: int parsedNumber = checkInputIsInteger(newValue);
207: if (checkInputRange(parsedNumber)) {
208: super .insertString(offset, string, attributes);
209: messageLabel.setText(" ");
210: }
211: } catch (NumberFormatException exception) {
212: Toolkit.getDefaultToolkit().beep();
213: messageLabel.setText(notNumericMessage);
214: }
215: }
216: }
217:
218: /**
219: * Check that the String is an integer
220: */
221: private int checkInputIsInteger(String proposedValue)
222: throws NumberFormatException {
223: int newValue = 0;
224: if (proposedValue.length() > 0) {
225: newValue = Integer.parseInt(proposedValue);
226: }
227: return newValue;
228: }
229:
230: /**
231: * Check that the int parameter is within range, meaning that it is
232: * greater than 0 and not greater than the number of lines in the source file
233: */
234: private boolean checkInputRange(int parsedNumber) {
235: return (parsedNumber > 0 && parsedNumber <= sizeOfClass);
236: }
237: }
238: } // end class GoToLineDialog
|