/*
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.