001: /*
002: * Beryl - A web platform based on XML, XSLT and Java
003: * This file is part of the Beryl XML GUI
004: *
005: * Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011:
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
020: */
021:
022: package org.beryl.gui.swing;
023:
024: import java.awt.AWTEvent;
025: import java.awt.Color;
026: import java.awt.Font;
027: import java.awt.FontMetrics;
028: import java.awt.Graphics;
029: import java.awt.Image;
030: import java.awt.Insets;
031: import java.awt.event.AdjustmentEvent;
032: import java.awt.event.AdjustmentListener;
033: import java.awt.event.MouseAdapter;
034: import java.awt.event.MouseEvent;
035: import java.awt.event.MouseWheelEvent;
036: import java.awt.event.MouseWheelListener;
037:
038: import javax.swing.JPanel;
039: import javax.swing.JScrollBar;
040: import javax.swing.border.EmptyBorder;
041:
042: /**
043: * JConsole - Very simplistic console widget supporting attributes
044: * @version 1.0
045: * @author Wenzel Jakob
046: */
047:
048: public class JConsole extends JPanel {
049: private JScrollBar scrollBar = null;
050: private ConsoleBuffer buffer = null;
051: private Image bufferImage = null;
052: private FontMetrics fontMetrics = null;
053: private boolean drawCursor = false;
054: private int cursorRow = 0;
055: private int cursorColumn = 0;
056: private Color cursorColor = null;
057:
058: Font plainFont = null;
059: Font boldFont = null;
060: int columnWidth = -1;
061: int rowHeight = -1;
062: int descent = -1;
063: int offset = 0;
064: int width = -1;
065: int height = -1;
066: boolean dirty = false;
067:
068: protected class ScrollBarListener implements AdjustmentListener {
069: public void adjustmentValueChanged(AdjustmentEvent event) {
070: offset = event.getValue();
071: dirty = true;
072: refresh();
073: }
074: };
075:
076: protected class WheelListener implements MouseWheelListener {
077: public void mouseWheelMoved(MouseWheelEvent event) {
078: int notches = event.getWheelRotation();
079: scrollBar.setValue(scrollBar.getValue() + notches * 5);
080: }
081: };
082:
083: protected class ConsoleMouseListener extends MouseAdapter {
084: public void mouseClicked(MouseEvent e) {
085: requestFocus();
086: }
087: };
088:
089: /**
090: * Create the console widget
091: */
092: public JConsole() {
093: /* Add a scrollbar */
094: scrollBar = new JScrollBar();
095: scrollBar.addAdjustmentListener(new ScrollBarListener());
096: addMouseWheelListener(new WheelListener());
097: add(scrollBar);
098:
099: /* Construct the buffer */
100: buffer = new ConsoleBuffer(this );
101:
102: /* Setup a fixed size font */
103: setFont(new Font("Monospaced", Font.PLAIN, 12));
104:
105: /* Disable double buffering */
106: setDoubleBuffered(false);
107:
108: /* Set background color to black */
109: setBackground(Color.BLACK);
110:
111: /* Enable key events */
112: enableEvents(AWTEvent.KEY_EVENT_MASK);
113:
114: /* Make the console focusable */
115: setFocusable(true);
116:
117: /* Add a mouse listener */
118: addMouseListener(new ConsoleMouseListener());
119:
120: /* Set a border */
121: setBorder(new EmptyBorder(3, 5, 5, 0));
122:
123: /* Set the cursor color */
124: cursorColor = Color.LIGHT_GRAY;
125: }
126:
127: /**
128: * Set the font
129: */
130: public void setFont(Font font) {
131: plainFont = new Font(font.getFamily(), Font.PLAIN, font
132: .getSize());
133: boldFont = new Font(font.getFamily(), Font.BOLD, font.getSize());
134: fontMetrics = getFontMetrics(plainFont);
135: columnWidth = fontMetrics.charWidth('A');
136: rowHeight = fontMetrics.getHeight();
137: descent = fontMetrics.getDescent();
138: }
139:
140: /**
141: * Return the cursor column
142: */
143: public int getCursorColumn() {
144: return cursorColumn;
145: }
146:
147: /**
148: * Return the table row
149: */
150: public int getCursorRow() {
151: return cursorRow;
152: }
153:
154: /**
155: * Return whether to draw the cursor
156: */
157: public boolean getDrawCursor() {
158: return drawCursor;
159: }
160:
161: /**
162: * Define whether to draw the cursor
163: */
164: public void setDrawCursor(boolean b) {
165: drawCursor = b;
166: }
167:
168: /**
169: * Return the cursor color
170: */
171: public Color getCursorColor() {
172: return cursorColor;
173: }
174:
175: /**
176: * Set the cursor color
177: */
178: public void setCursorColor(Color color) {
179: cursorColor = color;
180: }
181:
182: /**
183: * Setup the layout
184: */
185: public void doLayout() {
186: super .doLayout();
187:
188: width = getWidth();
189: height = getHeight();
190: int scrollBarWidth = scrollBar.getPreferredSize().width;
191:
192: if (width < 0 || height < 0 || scrollBarWidth < 0)
193: return;
194:
195: bufferImage = createImage(width, height);
196:
197: scrollBar.setSize(scrollBarWidth, height);
198: scrollBar.setLocation(width - scrollBarWidth, 0);
199: scrollBar.setUnitIncrement(1);
200: scrollBar.setBlockIncrement(height / rowHeight);
201:
202: dirty = true;
203: updateScrollbar();
204: refresh();
205: }
206:
207: /**
208: * Update the scroll bar values
209: */
210: void updateScrollbar() {
211: Insets insets = getInsets();
212: int visibleRows = (height - insets.top - insets.bottom)
213: / rowHeight;
214: int rowCount = buffer.getRowCount();
215:
216: if (visibleRows > rowCount)
217: visibleRows = rowCount;
218:
219: scrollBar.setMinimum(0);
220: scrollBar.setMaximum(rowCount);
221: scrollBar.setVisibleAmount(visibleRows);
222: if (offset + visibleRows > rowCount)
223: offset = rowCount - visibleRows;
224: scrollBar.setValue(offset);
225: }
226:
227: /**
228: * Scroll to a row
229: */
230: public void scrollToRow(int row) {
231: scrollBar.setValue(row);
232: }
233:
234: /**
235: * Scroll to the bottom
236: */
237: public void scrollToBottom() {
238: scrollBar.setValue(scrollBar.getMaximum()
239: - scrollBar.getVisibleAmount());
240: }
241:
242: /**
243: * Return the console buffer
244: */
245: public ConsoleBuffer getBuffer() {
246: return buffer;
247: }
248:
249: /**
250: * Set the cursor position
251: */
252: public void setCursorPosition(int row, int column) {
253: if (getBuffer().getRowCount() > cursorRow)
254: getBuffer().getRow(cursorRow).markDirty();
255: getBuffer().getRow(row).markDirty();
256: cursorRow = row;
257: cursorColumn = column;
258: }
259:
260: /**
261: * Always call this function after you have changed the console
262: * buffer. This causes a repaint of the modified rows
263: */
264: public void refresh() {
265: if (bufferImage != null) {
266: Graphics g = bufferImage.getGraphics();
267:
268: g.setColor(getBackground());
269: if (dirty)
270: g.fillRect(0, 0, width, height);
271:
272: buffer.paintBuffer(g);
273:
274: dirty = false;
275: repaint();
276: }
277: }
278:
279: /**
280: * Transfer the buffer image to the screen
281: */
282: protected void paintComponent(Graphics g) {
283: Insets insets = getInsets();
284: int row = cursorRow - offset;
285: int visibleRows = (height - insets.top - insets.bottom)
286: / rowHeight;
287: boolean doDrawCursor = drawCursor && row >= 0
288: && row < visibleRows;
289:
290: g.drawImage(bufferImage, 0, 0, width, height, 0, 0, width,
291: height, this);
292:
293: if (doDrawCursor) {
294: g.setXORMode(getBackground());
295: g.setColor(cursorColor);
296: g.fillRect(insets.left + cursorColumn * columnWidth,
297: insets.top + row * rowHeight, columnWidth,
298: rowHeight);
299: g.setPaintMode();
300: }
301: }
302: }
|