Package org.spoutcraft.launcher.skin

Source Code of org.spoutcraft.launcher.skin.ConsoleFrame$ContextMenu

/*
* This file is part of Spoutcraft Launcher.
*
* Copyright (c) 2011 Spout LLC <http://www.spout.org/>
* Spoutcraft Launcher is licensed under the Spout License Version 1.
*
* Spoutcraft Launcher 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 3 of the License, or
* (at your option) any later version.
*
* In addition, 180 days after any changes are published, you can use the
* software, incorporating those changes, under the terms of the MIT license,
* as described in the Spout License Version 1.
*
* Spoutcraft Launcher 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,
* the MIT license and the Spout License Version 1 along with this program.
* If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
* License and see <http://spout.in/licensev1> for the full license,
* including the MIT license.
*/
/*
* SK's Minecraft Launcher
* Copyright (C) 2010, 2011 Albert Pham <http://www.sk89q.com>
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.spoutcraft.launcher.skin;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import org.apache.commons.io.IOUtils;

import org.spoutcraft.launcher.skin.components.LoginFrame;
import org.spoutcraft.launcher.util.Compatibility;

/**
* Console dialog for showing console messages.
*
* @author sk89q
*
* This code reused and relicensed as LGPLv3 with permission.
*/
public class ConsoleFrame extends JFrame implements MouseListener {
  private static final long serialVersionUID = 1L;
  private static final Logger rootLogger = Logger.getLogger("launcher");
  private Process trackProc;
  private Handler loggerHandler;
  private JTextComponent textComponent;
  private Document document;
  private int numLines;
  private boolean colorEnabled = false;
  private final SimpleAttributeSet defaultAttributes = new SimpleAttributeSet();
  private final SimpleAttributeSet highlightedAttributes;
  private final SimpleAttributeSet errorAttributes;
  private final SimpleAttributeSet infoAttributes;
  private final SimpleAttributeSet debugAttributes;

  /**
   * Construct the frame.
   *
   * @param numLines number of lines to show at a time
   * @param colorEnabled true to enable a colored console
   */
  public ConsoleFrame(int numLines, boolean colorEnabled) {
    this(numLines, colorEnabled, null, false);
  }

  /**
   * Construct the frame.
   *
   * @param numLines number of lines to show at a time
   * @param colorEnabled true to enable a colored console
   * @param trackProc process to track
   * @param killProcess true to kill the process on console close
   */
  public ConsoleFrame(int numLines, boolean colorEnabled, final Process trackProc, final boolean killProcess) {
    super("Spoutcraft Console");
    this.numLines = numLines;
    this.colorEnabled = colorEnabled;
    this.trackProc = trackProc;

    this.highlightedAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground(highlightedAttributes, Color.BLACK);
    StyleConstants.setBackground(highlightedAttributes, Color.YELLOW);

    this.errorAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground(errorAttributes, new Color(200, 0, 0));
    this.infoAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground(infoAttributes, new Color(200, 0, 0));
    this.debugAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground(debugAttributes, Color.DARK_GRAY);

    setSize(new Dimension(650, 400));
    buildUI();

    Compatibility.setIconImage(this, Toolkit.getDefaultToolkit().getImage(LoginFrame.spoutcraftIcon));

    if (trackProc != null) {
      track(trackProc);
    }

    addMouseListener(this);

    setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent event) {
        if (trackProc != null && killProcess) {
          trackProc.destroy();
          if (loggerHandler != null) {
            rootLogger.removeHandler(loggerHandler);
          }
          event.getWindow().dispose();
        }
      }
    });
  }

  /**
   * Build the interface.
   */
  private void buildUI() {
    if (colorEnabled) {
      JTextPane text = new JTextPane();
      this.textComponent = text;
    } else {
      JTextArea text = new JTextArea();
      this.textComponent = text;
      text.setLineWrap(true);

    }
    textComponent.addMouseListener(this);
    textComponent.setFont(getMonospaceFont());
    textComponent.setEditable(false);
    DefaultCaret caret = (DefaultCaret) textComponent.getCaret();
    caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    document = textComponent.getDocument();
    document.addDocumentListener(new LimitLinesDocumentListener(numLines, true));

    JScrollPane scrollText = new JScrollPane(textComponent);
    scrollText.setBorder(null);
    scrollText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

    add(scrollText, BorderLayout.CENTER);
  }

  /**
   * Log a message.
   *
   * @param line line
   */
  public void log(String line) {
    log(line, null);
  }

  /**
   * Log a message given the {@link AttributeSet}.
   *
   * @param line line
   * @param attributes attribute set, or null for none
   */
  public void log(String line, AttributeSet attributes) {
    if (colorEnabled && line.startsWith("(!!)")) {
      attributes = highlightedAttributes;
    }

    try {
      int offset = document.getLength();
      document.insertString(offset, line,  (attributes != null && colorEnabled) ? attributes : defaultAttributes);
      textComponent.setCaretPosition(document.getLength());
    } catch (BadLocationException ble) {
    } catch (NullPointerException npe) {
    }
  }

  /**
   * Get an output stream that can be written to.
   *
   * @return output stream
   */
  public ConsoleOutputStream getOutputStream() {
    return getOutputStream((AttributeSet) null);
  }

  /**
   * Get an output stream with the given attribute set.
   *
   * @param attributes attributes
   * @return output stream
   */
  public ConsoleOutputStream getOutputStream(AttributeSet attributes) {
    return new ConsoleOutputStream(attributes);
  }

  /**
   * Get an output stream using the give color.
   *
   * @param color color to use
   * @return output stream
   */
  public ConsoleOutputStream getOutputStream(Color color) {
    SimpleAttributeSet attributes = new SimpleAttributeSet();
    StyleConstants.setForeground(attributes, color);
    return getOutputStream(attributes);
  }

  /**
   * Consume an input stream and print it to the dialog. The consumer
   * will be in a separate daemon thread.
   *
   * @param from stream to read
   */
  public void consume(InputStream from) {
    consume(from, getOutputStream());
  }

  /**
   * Consume an input stream and print it to the dialog. The consumer
   * will be in a separate daemon thread.
   *
   * @param from stream to read
   * @param color color to use
   */
  public void consume(InputStream from, Color color) {
    consume(from, getOutputStream(color));
  }

  /**
   * Consume an input stream and print it to the dialog. The consumer
   * will be in a separate daemon thread.
   *
   * @param from stream to read
   * @param attributes attributes
   */
  public void consume(InputStream from, AttributeSet attributes) {
    consume(from, getOutputStream(attributes));
  }

  /**
   * Internal method to consume a stream.
   *
   * @param from stream to consume
   * @param outputStream console stream to write to
   */
  private void consume(InputStream from, ConsoleOutputStream outputStream) {
    final InputStream in = from;
    final PrintWriter out = new PrintWriter(outputStream, true);
    Thread thread = new Thread(new Runnable() {
      public void run() {
        byte[] buffer = new byte[1024];
        try {
          int len;
          while ((len = in.read(buffer)) != -1) {
            String s = new String(buffer, 0, len);
            System.out.print(s);
            out.append(s);
            out.flush();
          }
        } catch (IOException e) {
        } finally {
          IOUtils.closeQuietly(in);
          IOUtils.closeQuietly(out);
        }
      }
    });
    thread.setDaemon(true);
    thread.start();
  }

  /**
   * Track a process in a separate daemon thread.
   *
   * @param process process
   */
  private void track(Process process) {
    final PrintWriter out = new PrintWriter(getOutputStream(Color.MAGENTA), true);
    Thread thread = new Thread(new Runnable() {
      public void run() {
        try {
          int code = trackProc.waitFor();
          out.println("Process ended with code " + code);
        } catch (InterruptedException e) {
          out.println("Process tracking interrupted!");
        }
      }
    });
    thread.setDaemon(true);
    thread.start();
  }

  /**
   * Registera global logger listener.
   */
  public void registerLoggerHandler() {
    for (Handler handler : rootLogger.getHandlers()) {
      rootLogger.removeHandler(handler);
    }

    loggerHandler = new ConsoleLoggerHandler();
    rootLogger.addHandler(loggerHandler);
  }

  /**
   * Used to send console messages to the console.
   */
  public final class ConsoleOutputStream extends ByteArrayOutputStream {
    private AttributeSet attributes;

    private ConsoleOutputStream(AttributeSet attributes) {
      this.attributes = attributes;
    }

    @Override
    public void flush() {
      String data = toString();
      if (data.length() == 0) return;
      log(data, attributes);
      reset();
    }
  }

  /**
   * Used to send logger messages to the console.
   */
  private class ConsoleLoggerHandler extends Handler {
    @Override
    public void publish(LogRecord record) {
      Level level = record.getLevel();
      Throwable t = record.getThrown();
      AttributeSet attributes = defaultAttributes;

      if (level.intValue() >= Level.WARNING.intValue()) {
        attributes = errorAttributes;
      } else if (level.intValue() < Level.INFO.intValue()) {
        attributes = debugAttributes;
      }

      log(record.getMessage() + "\n", attributes);
      if (t != null) {
        log(getStackTrace(t) + "\n", attributes);
      }
    }

    @Override
    public void flush() {
    }

    @Override
    public void close() throws SecurityException {
    }
  }

  private static String[] monospaceFontNames = {"Consolas", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Lucida Console"};

  /**
   * Get a supported monospace font.
   *
   * @return font
   */
  public static Font getMonospaceFont() {
    for (String fontName : monospaceFontNames) {
      Font font = Font.decode(fontName + "-11");
      if (!font.getFamily().equalsIgnoreCase("Dialog")) {
        return font;
      }
    }
    return new Font("Monospace", Font.PLAIN, 11);
  }

  /**
   * Get a stack trace as a string.
   *
   * @param t exception
   * @return stack trace
   */
  public static String getStackTrace(Throwable t) {
    Writer result = new StringWriter();
    try {
      PrintWriter printWriter = new PrintWriter(result);
      t.printStackTrace(printWriter);
    } finally {
      IOUtils.closeQuietly(result);
    }
    return result.toString();
  }

  public void mousePressed(MouseEvent e) {
    if (e.isPopupTrigger()) {
      doPop(e);
    }
  }

  public void mouseReleased(MouseEvent e) {
    if (e.isPopupTrigger()) {
      doPop(e);
    }
  }

  public void mouseClicked(MouseEvent e) {
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  private void doPop(MouseEvent e) {
    ContextMenu menu = new ContextMenu();
    menu.show(e.getComponent(), e.getX(), e.getY());
  }

  private class ContextMenu extends JPopupMenu {
    private static final long serialVersionUID = 1L;
    JMenuItem copy;
    JMenuItem clear;
    public ContextMenu() {
      copy = new JMenuItem("Copy");
      add(copy);
      copy.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          textComponent.copy();
        }
      });

      clear = new JMenuItem("Clear");
      add(clear);
      clear.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          textComponent.setText("");
        }
      });
    }
  }
}
TOP

Related Classes of org.spoutcraft.launcher.skin.ConsoleFrame$ContextMenu

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.