source: main/trunk/gli/src/org/greenstone/gatherer/gui/NumberedJTextArea.java@ 29031

Last change on this file since 29031 was 29031, checked in by ak19, 10 years ago

Moved out the NumberedJTextArea into its own class. It now manages the associated Undo and RedoButtons itself, so that the undo/redobutton code and their listeners are also moved out of FormatConversionDialog. Tested that it all still works, including bugfix to previous commit by overrding undo/redoLastAction() in NumberedJTextArea.java. 2. Also, cleaned up import statements, minor change to comments in the StreamGobbler classes, added the license text at the top of all these new classes.

File size: 7.3 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Copyright (C) 1999 New Zealand Digital Library Project
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *########################################################################
24 */
25
26package org.greenstone.gatherer.gui;
27
28import org.greenstone.gatherer.Configuration;
29import org.greenstone.gatherer.Dictionary;
30
31import org.fife.ui.rsyntaxtextarea.*;
32
33import java.awt.*;
34import java.awt.event.*;
35import java.util.*;
36import javax.swing.*;
37import javax.swing.event.*;
38import javax.swing.undo.*;
39
40/**
41 * A textarea with the line number next to each line of the text.
42 * It provides undo and redo buttons that are already hooked up to listeners
43 * You can add these buttons to a JComponent and they will behave just like the
44 * existing RSyntaxArea's Ctrl-Z and Ctrl-Y shortcuts and undo/redo popup menus.
45 */
46public class NumberedJTextArea extends RSyntaxTextArea /* JTextArea */
47 implements UndoableEditListener, ActionListener
48{
49
50 String id = null;
51
52 public final GLIButton undoButton;
53 public final GLIButton redoButton;
54
55 public NumberedJTextArea(String tooltip) {
56 this("", tooltip);
57 }
58
59 public NumberedJTextArea (String id, String tooltip) {
60 super();
61
62 this.id = id;
63
64 // maybe use this textarea's id field to customise the undo/redo button tooltips?
65 undoButton = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip"));
66 undoButton.setEnabled(false);
67
68 redoButton = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip"));
69 redoButton.setEnabled(false);
70
71 undoButton.addActionListener(this);
72 redoButton.addActionListener(this);
73
74 // next, initialise this RSyntaxTextArea:
75
76 // Adding the UndoableEditListener has to come after instantiation of the undo and
77 // redo buttons, since the listener expects these buttons to already exist
78 this.getDocument().addUndoableEditListener(this);
79
80 /* Fields specific to RSyntaxQuery inherited class */
81 setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
82 setBracketMatchingEnabled(true);
83 setAnimateBracketMatching(true);
84 setAntiAliasingEnabled(true);
85 setAutoIndentEnabled(true);
86 setPaintMarkOccurrencesBorder(false);
87
88 /* Standard fields to JTextArea */
89 setOpaque(false);
90 setBackground(Configuration.getColor("coloring.editable_background", false));
91 setCaretPosition(0);
92 setLineWrap(true);
93 setRows(11);
94 setWrapStyleWord(false);
95 setToolTipText(Dictionary.get("FormatConversionDialog.GS2_Text_Tooltip"));
96 }
97
98 public void paintComponent(Graphics g)
99 {
100 Insets insets = getInsets();
101 Rectangle rectangle = g.getClipBounds();
102 g.setColor(Color.white);
103 g.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
104
105 super.paintComponent(g);
106
107 if (rectangle.x < insets.left)
108 {
109 FontMetrics font_metrics = g.getFontMetrics();
110 int font_height = font_metrics.getHeight();
111 int y = font_metrics.getAscent() + insets.top;
112 int line_number_start_point = ((rectangle.y + insets.top) / font_height) + 1;
113 if (y < rectangle.y)
114 {
115 y = line_number_start_point * font_height - (font_height - font_metrics.getAscent());
116 }
117 int y_axis_end_point = y + rectangle.height + font_height;
118 int x_axis_start_point = insets.left;
119 x_axis_start_point -= getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " ");
120 if (!this.getText().trim().equals(""))
121 {
122 g.setColor(Color.DARK_GRAY);
123 }
124 else
125 {
126 g.setColor(Color.white);
127 }
128 int length = ("" + Math.max(getRows(), getLineCount() + 1)).length();
129 while (y < y_axis_end_point)
130 {
131 g.drawString(line_number_start_point + " ", x_axis_start_point, y);
132 y += font_height;
133 line_number_start_point++;
134 }
135 }
136 }
137
138
139 public Insets getInsets()
140 {
141 Insets insets = super.getInsets(new Insets(0, 0, 0, 0));
142 insets.left += getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " ");
143 return insets;
144 }
145
146
147 // Overriding, to ensure that even if ctrl-z was pressed to undo something,
148 // the undo and redo buttons are in sync with that.
149 public void undoLastAction() {
150 super.undoLastAction();
151 redoButton.setEnabled(true);
152
153 if (!this.canUndo()) {
154 undoButton.setEnabled(false);
155 } else {
156 undoButton.setEnabled(true);
157 }
158 }
159
160 // Overriding
161 public void redoLastAction() {
162 super.redoLastAction();
163 undoButton.setEnabled(true);
164
165 if (!this.canRedo()) {
166 redoButton.setEnabled(false);
167 } else {
168 redoButton.setEnabled(true);
169 }
170 }
171
172 // Overriding
173 public void discardAllEdits() {
174 // Buttons have to be disabled before discardAllEdits(). If done in reverse order, buttons get re-enabled
175 undoButton.setEnabled(false);
176 redoButton.setEnabled(false);
177 super.discardAllEdits();
178 }
179
180 // The RSyntaxTextarea class already provides undo and redo functionality hooked up to their
181 // usual keyboard shortcuts and to rightclick popup menus. The actionListener below merely
182 // reuses this behaviour and attaches it to the undoButton and redoButton.
183 public void actionPerformed(ActionEvent event)
184 {
185 // actionPerformed() not defined in any of the superclasses RTextArea, RTextAreaBase, JTextArea
186 //super.actionPerformed(event); // compile error
187
188 if(event.getSource() == undoButton) {
189
190 try {
191 // calls canUndo() and undoLastAction() defined by RTextArea
192 // internally calls its undoManager's canUndo() and undo() to handle compoundEdits
193 if (this.canUndo()) {
194 this.undoLastAction();
195 }
196
197 if (!this.canUndo()) {
198 undoButton.setEnabled(false);
199 } else {
200 undoButton.setEnabled(true);
201 }
202
203 } catch (Exception e) {
204 System.err.println("Exception trying to undo: " + e.getMessage());
205 e.printStackTrace();
206 }
207 }
208 else if (event.getSource() == redoButton) {
209 try {
210 // calls canRedo() and redoLastAction() defined by RTextArea
211 // internally calls its undoManager's canRedo() and redo() to handle compoundEdits
212
213 if (this.canRedo()) {
214 this.redoLastAction();
215 }
216
217 if (!this.canRedo()) {
218 redoButton.setEnabled(false);
219 } else {
220 redoButton.setEnabled(true);
221 }
222
223 } catch (Exception e) {
224 System.err.println("Exception trying to redo: " + e.getMessage());
225 e.printStackTrace();
226 }
227 }
228 }
229
230
231 // defined in interface UndoableEditListener
232 public void undoableEditHappened(UndoableEditEvent evt)
233 {
234 undoButton.setEnabled(true);
235 redoButton.setEnabled(false);
236 }
237}
Note: See TracBrowser for help on using the repository browser.