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

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

Minor changes and corrections.

File size: 7.2 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(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.