/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package app.navigps.gui.VerboseTextPane;
import app.navigps.gui.MyPopupMenu;
import app.navigps.gui.NaviRootWindow;
import app.navigps.utils.MyFileFilter;
import app.navigps.utils.NaviLogger;
import app.navigps.utils.OutputVerboseStreamAdapter;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;
/**
* Created on 2008-12-18, 13:53:36
* @author Grzegorz (vara) Warywoda
*/
public class MyTextPane extends JTextPane{
private StyledDocument document;
private SimpleAttributeSet defaultAttributes;
private SimpleAttributeSet errorAtributes;
private DocumentStatus pipe = new DocumentStatus();
private LinkedList<Action> actions = new LinkedList<Action>();
private boolean autoRoll = true;
/**
*
*/
public static final Font DEFAULT_FONT = new Font("monospaced",Font.PLAIN,12);
/**
*
*/
public MyTextPane(){
setFont(DEFAULT_FONT);
StyleContext context = new StyleContext();
Style style = context.getStyle(StyleContext.DEFAULT_STYLE);
StyleConstants.setAlignment(style, StyleConstants.ALIGN_LEFT);
StyleConstants.setFontSize(style, 4);
StyleConstants.setSpaceAbove(style, 1);
StyleConstants.setSpaceBelow(style, 1);
//StyleConstants.setBold(attributes, true);
int positions[] = { TabStop.ALIGN_BAR, TabStop.ALIGN_CENTER, TabStop.ALIGN_DECIMAL,
TabStop.ALIGN_LEFT, TabStop.ALIGN_RIGHT };
TabStop [] tabstop = new TabStop[] {new TabStop(130, positions[3], TabStop.ALIGN_CENTER)};
TabSet tabset = new TabSet(tabstop);
defaultAttributes = new SimpleAttributeSet();
errorAtributes = new SimpleAttributeSet();
StyleConstants.setTabSet(defaultAttributes,tabset);
StyleConstants.setForeground(errorAtributes, new Color(165,2,2));
document = new DefaultStyledDocument(context);
document.setParagraphAttributes(0,1,defaultAttributes,true);
document.addDocumentListener(new MyDocumentListener());
setDocument(document);
setEditable(false);
actions.add(new ClearAllAction("Clear All",
null,
"Clear All text from document",KeyEvent.VK_C));
actions.add(new ShowTimeAction(ShowTimeAction.SHOW_TIME,
null,
"Show/Hide Time Stemp", KeyEvent.VK_T));
actions.add(new SaveAsAction("SaveAs...",
null, "Save content area text", KeyEvent.VK_S));
addMouseListener(new MouseForVerboseTextPane());
addEndTextnl(new Date()+"\nVerbose text pane created ", errorAtributes);
}
@Override
public boolean getScrollableTracksViewportWidth() {
Component parent = getParent();
ComponentUI compUi = getUI();
return parent != null ?
(compUi.getPreferredSize(this).width <= parent.getSize().width) : true;
}
@Override
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g2);
}
/**
*
* @return
*/
public DocumentStatus getDocumentStatus(){
return pipe;
}
/**
* @return the actions
*/
public LinkedList<Action> getMyActions() {
return actions;
}
/**
* @return the defaultAttributes
*/
protected SimpleAttributeSet getDefaultAttributes() {
return defaultAttributes;
}
/**
* @param defaultAttributes the defaultAttributes to set
*/
protected void setDefaultAttributes(SimpleAttributeSet defaultAttributes) {
this.defaultAttributes = defaultAttributes;
}
/**
* @return the errorAtributes
*/
protected SimpleAttributeSet getErrorAtributes() {
return errorAtributes;
}
/**
* @param errorAtributes the errorAtributes to set
*/
protected void setErrorAtributes(SimpleAttributeSet errorAtributes) {
this.errorAtributes = errorAtributes;
}
/**
*
* @param str
* @param attr
*/
public void addEndText(final String str,final SimpleAttributeSet attr){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
((StyledDocument)getDocument()).
insertString(getDocument().getLength(), str, attr);
/* if(isAutoScroll()){
Component c = getParent();
if(c instanceof JViewport){
JViewport vp = (JViewport)c;
vp.scrollRectToVisible(vp.getViewRect());
}
}*/
} catch (BadLocationException ex) {
NaviLogger.logger.logp(Level.WARNING,getClass().getName(),
"addEndTextnl(String str)","str \""+str+"\"",ex);
}
}
});
}
/**
*
* @param str
* @param attr
*/
public void addEndTextnl(String str,SimpleAttributeSet attr){
addEndText(str+"\n", attr);
}
/**
* @return the autoScroll
*/
public boolean isAutoScroll() {
return autoRoll;
}
/**
* @param autoScroll the autoScroll to set
*/
public void setAutoScroll(boolean autoScroll) {
this.autoRoll = autoScroll;
}
/**
*
*/
protected class DocumentStatus extends OutputVerboseStreamAdapter{
/**
*
*/
public DocumentStatus(){
//setTimeEnabled(true);
}
/**
*
* @param text
*/
@Override
public void outputVerboseStream(String text){
SimpleAttributeSet attr = new SimpleAttributeSet(getDefaultAttributes());
if(isTimeEnabled()){
addEndText(getTime()+" ", attr);
}
addEndTextnl(text,attr);
}
/**
*
* @param text
*/
@Override
public void outputErrorVerboseStream(String text) {
SimpleAttributeSet attr = new SimpleAttributeSet(getErrorAtributes());
if(isTimeEnabled()){
addEndText(getTime()+" ", attr);
}
if(text.startsWith("\tat")){
StyleConstants.setForeground(attr,Color.BLUE);
if(isAutoScroll()!=false)
setAutoScroll(false);
}
addEndTextnl(text,attr);
}
}
/**
*
*/
protected class MyDocumentListener implements DocumentListener {
@Override
public void insertUpdate(DocumentEvent e) {
//displayEditInfo(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
//displayEditInfo(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
//displayEditInfo(e);
}
private void displayEditInfo(DocumentEvent e) {
Document document = (Document)e.getDocument();
int changeLength = e.getLength();
System.out.println(e.getType().toString() + ": "
+ changeLength + " character"
+ ((changeLength == 1) ? ". " : "s. ")
+ " Text length = " + document.getLength());
}
}
/**
*
*/
private class ClearAllAction extends AbstractAction{
/**
*
* @param text
* @param icon
* @param desc
* @param mnemonic
*/
public ClearAllAction(String text, ImageIcon icon,
String desc, Integer mnemonic){
super(text);
putValue(AbstractAction.SMALL_ICON, icon);
putValue(AbstractAction.SHORT_DESCRIPTION, desc);
putValue(AbstractAction.MNEMONIC_KEY, mnemonic);
putValue(AbstractAction.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(mnemonic,InputEvent.ALT_DOWN_MASK));
setEnabled(true);
}
@Override
public void actionPerformed(ActionEvent e) {
setText("");
//setEnabled(false);
}
}
/**
*
*/
private class ShowTimeAction extends AbstractAction{
/**
*
*/
public static final String SHOW_TIME = "Show Time";
/**
*
*/
public static final String HIDE_TIME = "Hide Time";
/**
*
* @param text
* @param icon
* @param desc
* @param mnemonic
*/
public ShowTimeAction(String text, ImageIcon icon,
String desc, Integer mnemonic){
super(text);
putValue(AbstractAction.SMALL_ICON, icon);
putValue(AbstractAction.SHORT_DESCRIPTION, desc);
putValue(AbstractAction.MNEMONIC_KEY, mnemonic);
putValue(AbstractAction.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(mnemonic,InputEvent.ALT_DOWN_MASK));
setEnabled(true);
checkDisplayText();
}
private void checkDisplayText(){
putValue(AbstractAction.NAME, pipe.isTimeEnabled() ? HIDE_TIME : SHOW_TIME);
}
@Override
public void actionPerformed(ActionEvent e) {
pipe.setTimeEnabled(!pipe.isTimeEnabled());
checkDisplayText();
}
}
private class SaveAsAction extends AbstractAction{
private String CANCEL = "Save command cancelled by user.";
private String SAVING = "Saving LOG to file : ";
private String CAN_NOT_WRITE = "Can not write to file !!!";
public SaveAsAction(String text, ImageIcon icon,
String desc, Integer mnemonic){
super(text);
putValue(AbstractAction.SMALL_ICON, icon);
putValue(AbstractAction.SHORT_DESCRIPTION, desc);
putValue(AbstractAction.MNEMONIC_KEY, mnemonic);
putValue(AbstractAction.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(mnemonic,InputEvent.ALT_DOWN_MASK));
setEnabled(true);
}
@Override
public void actionPerformed(ActionEvent e) {
File currentDir = null;
String msg = "";
currentDir = new File(System.getProperty("user.dir"));
JFileChooser chooser = new JFileChooser();
String fileFilter = "txt";
chooser.addChoosableFileFilter(new MyFileFilter(new String[]{"txt"}, fileFilter));
chooser.setAcceptAllFileFilterUsed(false);
chooser.setCurrentDirectory(currentDir);
int retour = chooser.showSaveDialog(null);
if (retour == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
NaviLogger.logger.log(Level.FINE, "Prepare to "+SAVING+file);
if(!file.exists()){
try {
file.createNewFile();
if (!file.canWrite()) {
msg = CAN_NOT_WRITE;
NaviLogger.logger.log(Level.WARNING, msg);
return;
}
} catch (IOException ex) {
NaviLogger.logger.log(Level.WARNING, "Create new file exception",ex);
return;
}
}else{
int option = JOptionPane.showConfirmDialog(
MyTextPane.this.getTopLevelAncestor(),
"Override existing file ?", "Override File",
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
NaviRootWindow.LOGO_APPICATION_IMAGE);
if(option!=0){
NaviLogger.logger.log(Level.FINE, CANCEL);
return;
}
}
String str = getText();
writeToFile(file, str);
}else{
msg = CANCEL;
}
}
private void writeToFile(final File file,final String str){
new Thread(new Runnable() {
@Override
public void run() {
FileWriter fw = null;
try {
fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(str);
bw.flush();
} catch (IOException ex) {
NaviLogger.logger.log(Level.WARNING, "Write to file exception", ex);
} finally {
try {
fw.close();
String msg = SAVING+ file.getName();
NaviLogger.logger.log(Level.FINE, msg);
System.err.println(""+msg);
NaviRootWindow.getBridgeInformationPipe().currentStatusChanged(msg);
} catch (IOException ex) {
NaviLogger.logger.log(Level.WARNING, "Close file exception", ex);
}
}
}
}).start();
}
}
/**
*
*/
protected class MouseForVerboseTextPane extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e){
if(e.getButton()==MouseEvent.BUTTON3){
MyPopupMenu popup = new MyPopupMenu();
for (Action action : actions) {
popup.add(new JMenuItem(action));
}
/*
for (Action action : getActions()) {
popup.add(new JMenuItem(action));
}
*/
popup.show(MyTextPane.this,e.getX(),e.getY());
}
}
}
}