/*
 This file is part of the software framework JStatCom, 
 a library for building applications for data based analysis.

 Copyright (C) 2000-2005  Markus Kraetzig

 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 of the
 License, or (at your option) any later version.

 This library 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
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA
 */

package com.jstatcom.component;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;

import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import org.apache.log4j.Logger;

import com.jstatcom.io.FileSupport;
import com.jstatcom.util.UString;

/**
 * This class provides a convenient to use scrollable text field for presenting
 * output in text form. It has a default popup menu, which can also be set to a
 * different implementation.
 * 

* All methods that change the displayed text make sure that these operations * occur in the event dispatching thread. Otherwise this class is not designed * to be thread-save. * * @author Markus Kraetzig */ public final class ResultField extends JScrollPane implements OutHolder { private boolean appendWithoutScroll = false; private static final Logger log = Logger.getLogger(ResultField.class); private PageFormat pageFormat = null; private final PrintableTextArea resultTextArea = new PrintableTextArea(); private boolean editable = true; private JPopupMenu rfPopup = ResultFieldPopup.getInstance(); private int maxFontSize = 16; private int minFontSize = 8; /** * The printable text area. */ private static class PrintableTextArea extends JTextArea implements Printable { private int fontSize = 12; public PrintableTextArea() { super(); setFont(new java.awt.Font("monospaced", Font.PLAIN, fontSize)); setMargin(new java.awt.Insets(3, 5, 3, 5)); } public int getFontSize() { return fontSize; } public int getPageCount(PageFormat pf) { double height = getHeight(); int pages = (int) Math.ceil(height / pf.getImageableHeight()); return pages; } public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { Graphics2D g2 = (Graphics2D) g; g2.translate(pf.getImageableX(), pf.getImageableY() + pf.getImageableHeight() * -pi); Font f = new Font(null, Font.PLAIN, 12); g2.setFont(f); paint(g2); return Printable.PAGE_EXISTS; } public void setFontSize(int newFontSize) { setFont(new java.awt.Font("monospaced", Font.PLAIN, newFontSize)); fontSize = newFontSize; } } /** * The MouseAdapter for triggering the right click popup menu. */ private MouseListener triggerPopUp = new MouseAdapter() { public void mouseReleased(MouseEvent e) { if (getPopup() != null) { getPopup().processMouseEvent(e, null, null); } } }; /** * ResultField default constructor. */ public ResultField() { super(); setName("ResultField"); setSize(270, 200); setViewportView(resultTextArea); resultTextArea.setDocument(new PlainDocument() { @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (offs > 1000000) remove(0, 200000); super.insertString(offs, str, a); } }); resultTextArea.addMouseListener(triggerPopUp); } /** * Appends text to the text area and scrolls to the end if * necessary by setting the caret position. This happens always within the * EventDispatchingThread. * * @param text * the string to append to the text */ public void append(final String text) { if (appendWithoutScroll) { appendWithoutScroll(text); return; } Runnable runner = new Thread() { public void run() { resultTextArea.append(text); int temp = resultTextArea.getText().length(); resultTextArea.setCaretPosition(temp); } }; CompSettings.syncWithSwing(runner); } /** * Appends text to the text area without scrolling to the * end. This happens always within the EventDispatchingThread. * * @param text * the string to append to the text */ public void appendWithoutScroll(final String text) { Runnable runner = new Thread() { public void run() { int temp = resultTextArea.getText().length(); resultTextArea.append(text); resultTextArea.setCaretPosition(temp); } }; CompSettings.syncWithSwing(runner); } /** * Clears the text area from text. This happens always within the * EventDispatchingThread. */ public void clear() { Runnable runner = new Thread() { public void run() { resultTextArea.setText(""); } }; CompSettings.syncWithSwing(runner); } /** * Gets the default display font size. * * @return the default font size */ public int getDefaultFontSize() { return 12; } /** * Gets the currently displayed font size. * * @return the font size */ public int getFontSize() { return resultTextArea.getFontSize(); } /** * Gets the maximum size for the font displaying the text. * * @return maximum size */ public int getMaxFontSize() { return maxFontSize; } /** * Gets the minimum size for the font displaying the text. * * @return minimum size */ public int getMinFontSize() { return minFontSize; } /** * Gets the currently used RIGHT mouse JPopupMenu. * * @return the currently used RIGHT mouse popup */ public JPopupMenu getPopup() { return rfPopup; } /** * Gets the text displayed in the text area * * @return the displayed text */ public String getText() { return resultTextArea.getText(); } /** * Gets the underlying text area. * * @return the text area of this ResultField */ public JTextArea getTextArea() { return resultTextArea; } /** * Gets whether editing is allowed. * * @return true if editable */ public boolean isEditable() { return editable; } /** * Printing support method to enable multi page printing. * * @return the assembled Book object to print */ private Book makeBook() { if (pageFormat == null) { PrinterJob printJob = PrinterJob.getPrinterJob(); pageFormat = printJob.defaultPage(); } Book book = new Book(); book.append(resultTextArea, pageFormat, resultTextArea .getPageCount(pageFormat)); return book; } /** * Prints the text in the text area in a new printer thread. * */ public void print() { Thread printer = new Thread(new Runnable() { public void run() { PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setPageable(makeBook()); if (printJob.printDialog()) { try { printJob.print(); } catch (PrinterException ex) { log.error("Printing error", ex); } } } }); printer.start(); } /** * Saves the text in this component to a file. First ask to select the file * to write to. */ public void saveToFile() { File file = FileSupport.getInstance().saveTextFile( TopFrameReference.getTopFrameRef()); String text = resultTextArea.getText(); text = UString.replaceAllSubStrings(text, "\n", "\r\n"); if (file != null) FileSupport.getInstance().saveStringToFile(file, text, false); } /** * Sets whether editing is allowed. This happens always within the * EventDispatchingThread. * * @param newEditable * true if editable */ public void setEditable(final boolean newEditable) { editable = newEditable; resultTextArea.setEditable(editable); } /** * Sets the currently displayed font size. This happens always within the * EventDispatchingThread. * * @param newFontSize * the font size */ public void setFontSize(final int newFontSize) { Runnable runner = new Thread() { public void run() { resultTextArea.setFontSize(newFontSize); } }; CompSettings.syncWithSwing(runner); } /** * Sets a new popup whose processMouseEvent method is called, * when a mouseReleased event occured. * * @param newRfPopup * if null then it is just removed */ public void setPopup(JPopupMenu newRfPopup) { rfPopup = newRfPopup; } /** * Sets text to the text area. This happens always within the * EventDispatchingThread. * * @param text * the string to set as text */ public void setText(final String text) { Runnable runner = new Thread() { public void run() { resultTextArea.setText(text); } }; CompSettings.syncWithSwing(runner); } /** * Whether append scrolls down or not. * * @return */ public boolean isAppendWithoutScroll() { return appendWithoutScroll; } /** * Set whether append scrolls down or not. * * @param appendWithoutScroll if true do not scroll, default is false (do scroll down) */ public void setAppendWithoutScroll(boolean appendWithoutScroll) { this.appendWithoutScroll = appendWithoutScroll; } }

Ads help maintain this website.