Package tzar.mafiabot.gui

Source Code of tzar.mafiabot.gui.MafiaView$JTextComponentOutputStream

package tzar.mafiabot.gui;

import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

import net.miginfocom.swing.MigLayout;
import tzar.mafiabot.engine.Parser;


@SuppressWarnings("serial")
public class MafiaView extends JFrame {

  private File cacheFile;

  private final JPanel contentPanel = new JPanel();
  private final JLabel titleLabel = new JLabel("MafiaBot");
  private final JLabel helpLabel = new JLabel("");
  private final JTextField urlField = new JTextField();
  private final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
  private final JProgressBar progressBar = new JProgressBar();
  private final JButton btnStop = new JButton("Stop");
  private final JButton btnReparse = new JButton("Reparse Thread");
  private final JButton btnDeleteCacheAndReparse = new JButton("Delete Cache & Reparse Thread");

  private static boolean canSpecifyThread = false;

  // TRS
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=13&t=714"; // Glaed's game
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=13&t=961"; // WW's game
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=13&t=1045"; // Chunky's game
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=13&t=1429"; // Grilox's game
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=6&t=1647"; // Westy's game
  //String thread = "http://www.mlponies.com/forums/viewtopic.php?f=6&t=2151";  // Chunky's CYOR
  //String thread = "http://www.roundstable.com/forums/viewtopic.php?f=6&t=3158"; // Sharkmafia's game

  // BHP
  //String thread = "http://www.bluehellproductions.com/forum/index.php?showtopic=25403"; // Glaed's game
  //String thread = "http://www.bluehellproductions.com/forum/index.php?showtopic=25548"; // Westy's game
  //String thread = "https://www.bluehellproductions.com/forum/index.php?showtopic=25603"; // Nodlied's game

  // ELP
  //String thread = "http://eridanipony.com/viewtopic.php?f=30&t=3316"; // Hylius's game
  String thread = "http://eridanipony.com/viewtopic.php?f=30&t=3415"; // Westy's game

  /**
   * Launch the application.
   */
  public static void main(String[] args) {
    MafiaView gui = new MafiaView();
    gui.maximize();
    if (!canSpecifyThread) {
      gui.reparse();
    } else {
      gui.parseCompleted();
    }
  }

  /**
   * Create the frame.
   */
  public MafiaView() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception ignored) { }
    setVisible(false);
    setTitle("MafiaBot by Tzar469");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 505, 560);
    contentPanel.setForeground(Color.LIGHT_GRAY);
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPanel);
    contentPanel.setLayout(new MigLayout("insets 0", "[477px,grow]", "[35px][23px][330px,grow][23px][23px][23px][23px]"));
    titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
    titleLabel.setFont(new Font("Papyrus", Font.PLAIN, 21));
    contentPanel.add(titleLabel, "flowx,cell 0 0,grow");
    helpLabel.setToolTipText("Help");
    helpLabel.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent arg0) {
        try {
          Desktop d = Desktop.getDesktop();
          d.browse(new URI("https://docs.google.com/document/d/1URv0ozD0kBYfDm3SmbY8_ceiXnIe_ofBzWlC_pQQ08c/pub"));
        } catch (Exception ignored) { }
      }
    });
    helpLabel.setIcon(new ImageIcon(MafiaView.class.getResource("/javax/swing/plaf/metal/icons/ocean/question.png")));

    contentPanel.add(helpLabel, "cell 0 0");
    urlField.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent arg0) {
        try {
          if (!canSpecifyThread) {
            Desktop d = Desktop.getDesktop();
            d.browse(new URI(urlField.getText()));
          }
        } catch (Exception ignored) { }
      }
    });
    urlField.setFont(new Font("Palatino Linotype", Font.PLAIN, 12));
    urlField.setBackground(Color.WHITE);
    urlField.setText("Paste URL of thread here, then press Enter key.");
    urlField.setEditable(canSpecifyThread);
    urlField.setHorizontalAlignment(SwingConstants.CENTER);
    urlField.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent key) {
        if (key.getKeyCode() == KeyEvent.VK_ENTER) {
          reparse();
        }
      }
    });
    contentPanel.add(urlField, "cell 0 1,growx,aligny center");
    contentPanel.add(tabbedPane, "cell 0 2,grow");
    progressBar.setStringPainted(true);
    contentPanel.add(progressBar, "cell 0 3,growx,aligny center");
    btnStop.setEnabled(false);
    btnStop.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        parseCompleted();
      }
    });
    contentPanel.add(btnStop, "cell 0 4,growx,aligny center");
    btnReparse.setEnabled(false);
    btnReparse.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
        reparse();
      }
    });
    contentPanel.add(btnReparse, "cell 0 5,growx,aligny center");
    btnDeleteCacheAndReparse.setEnabled(false);
    btnDeleteCacheAndReparse.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (cacheFile != null && cacheFile.delete()) {
          btnDeleteCacheAndReparse.setEnabled(false);
        }
        reparse();
      }
    });
    contentPanel.add(btnDeleteCacheAndReparse, "cell 0 6,growx,aligny center");

    if (!canSpecifyThread) {
      urlField.setBackground(new Color(240,240,240));
      urlField.setBorder(javax.swing.BorderFactory.createEmptyBorder());
    }
    redirectSystemStreams();
   
  }
 
  private void maximize() {
    setExtendedState(MAXIMIZED_BOTH);
    setVisible(true);
  }

  private void reparse() {
    tabbedPane.removeAll();
    setPhase("Day 0");
    setProgress(0);
    if (canSpecifyThread) {
      if (urlField.getText().contains("URL") || urlField.getText().trim().isEmpty()) {
        urlField.setBackground(Color.YELLOW);
        return;
      } else {
        urlField.setBackground(Color.WHITE);
      }
    }
    btnStop.setText("Stop");
    btnStop.setEnabled(true);
    btnReparse.setEnabled(false);
    urlField.setEditable(false);
    parse();
  }

  private void parse() {
    new Thread() {
      public void run() {
        if (!canSpecifyThread) {
          urlField.setText(thread);
        } else {
          thread = urlField.getText();
        }

        cacheFile = new File("MafiaBot-" + thread.hashCode() + ".cache");
        Parser bot = new Parser(thread, MafiaView.this);
        if (!isStopped())
          bot.start();
      }
    }.start();
  }

  public void setProgress(int progress) {
    progressBar.setValue(progress);
  }

  public void setPhase(final String phase) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JTextPane errorPane = new JTextPane();
        errorPane.setEditable(false);

        StyledDocument errorDoc = errorPane.getStyledDocument();
        addStyles(errorDoc);
        insertStyledString(errorDoc, "bold", "Debugging & Error Log (" + phase + "):\n");


        JTextPane outputTextPane = new JTextPane();
        //outputTextPane.setDragEnabled(true);
        makeUndoable(outputTextPane);
        //outputTextArea.setEditable(false);

        StyledDocument outputDoc = outputTextPane.getStyledDocument();
        addStyles(outputDoc);
        insertStyledString(outputDoc, "bold", "Action log (" + phase + "):\n");

        JSplitPane splitPane = new JSplitPane();
        splitPane.setLeftComponent(new JScrollPane(errorPane));
        splitPane.setRightComponent(new JScrollPane(outputTextPane));
        splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);

        splitPane.setContinuousLayout(true);
        splitPane.setOneTouchExpandable(true);
        splitPane.setDividerLocation(0.0d);
        tabbedPane.addTab(phase, splitPane);
        if (tabbedPane.getSelectedIndex() == tabbedPane.getTabCount() - 2)
          tabbedPane.setSelectedComponent(splitPane);
      }
    });
  }

  public void parseCompleted() {
    //getTextArea(false).setCaretPosition(0);
    //btnStop.setText("Save action log");
    btnStop.setEnabled(false);
    btnReparse.setEnabled(true);

    if (canSpecifyThread) {
      urlField.setEditable(true);
    }

    if (cacheFile != null && cacheFile.exists()) {
      btnDeleteCacheAndReparse.setEnabled(true);
    }
  }

  public boolean isStopped() {
    // mutual exclusion: the reparse button is only enabled when the parsing has stopped
    return btnReparse.isEnabled();
  }

  private void makeUndoable(JTextComponent textComponent) {
    // code from: http://stackoverflow.com/a/12030993
    final UndoManager undoManager = new UndoManager();
    Document doc = textComponent.getDocument();
    doc.addUndoableEditListener(new UndoableEditListener() {
      @Override
      public void undoableEditHappened(UndoableEditEvent e) {
        //System.out.println("Add edit");
        undoManager.addEdit(e.getEdit());
      }
    });

    InputMap im = textComponent.getInputMap(JComponent.WHEN_FOCUSED);
    ActionMap am = textComponent.getActionMap();

    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Undo");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Redo");

    am.put("Undo", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent e) {
        try {
          if (undoManager.canUndo()) {
            undoManager.undo();
          }
        } catch (CannotUndoException exp) {
          exp.printStackTrace();
        }
      }
    });
    am.put("Redo", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent e) {
        try {
          if (undoManager.canRedo()) {
            undoManager.redo();
          }
        } catch (CannotUndoException exp) {
          exp.printStackTrace();
        }
      }
    });
  }

  private void addStyles(StyledDocument doc) {
    //Initialize some styles.
    Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);

    Style regular = doc.addStyle("regular", def);
    StyleConstants.setFontFamily(def, "Courier New");
    StyleConstants.setFontSize(def, 12);

    Style s = doc.addStyle("italic", regular);
    StyleConstants.setItalic(s, true);

    s = doc.addStyle("bold", regular);
    StyleConstants.setBold(s, true);

    s = doc.addStyle("small", regular);
    StyleConstants.setFontSize(s, 10);

    s = doc.addStyle("large", regular);
    StyleConstants.setFontSize(s, 16);

    // style for JButton
    /*
    s = doc.addStyle("button", regular);
        StyleConstants.setAlignment(s, StyleConstants.ALIGN_CENTER);
        ImageIcon soundIcon = createImageIcon("images/sound.gif",
                                              "sound icon");
        JButton button = new JButton();
        if (soundIcon != null) {
            button.setIcon(soundIcon);
        } else {
            button.setText("BEEP");
        }
        button.setCursor(Cursor.getDefaultCursor());
        button.setMargin(new Insets(0,0,0,0));
        button.setActionCommand(buttonString);
        button.addActionListener(this);
        StyleConstants.setComponent(s, button);
     */
  }

  private void insertStyledString(StyledDocument doc, String style, String str) {
    try {
      doc.insertString(doc.getLength(), str, doc.getStyle(style));
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }

  private void redirectSystemStreams() { 
    OutputStream out = new JTextComponentOutputStream(false);
    OutputStream error = new JTextComponentOutputStream(true);
    System.setOut(new PrintStream(out, true))
    System.setErr(new PrintStream(error, true))
 

  private class JTextComponentOutputStream extends OutputStream {
    boolean isErrorStream = false;

    private JTextComponentOutputStream(boolean isErrorStream) {
      this.isErrorStream = isErrorStream;
    }

    @Override 
    public void write(int b) throws IOException
      updateTextComponent(String.valueOf((char) b), isErrorStream)
    }
    @Override
    public void write(byte[] b) throws IOException
      write(b, 0, b.length)
    }
    @Override 
    public void write(byte[] b, int off, int len) throws IOException
      updateTextComponent(new String(b, off, len), isErrorStream)
    }

    // methods to select the right text component
    private void updateTextComponent(final String text, final boolean isError) { 
      SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
          insertStyledString(getTextComponent(isError).getStyledDocument(), "regular", text)
       
      });
    }

    private JTextPane getTextComponent(boolean errorPane) {
      JSplitPane splitPane = (JSplitPane) tabbedPane.getComponentAt(tabbedPane.getTabCount() - 1);
      JScrollPane scrollPane = (JScrollPane) (errorPane ? splitPane.getLeftComponent() : splitPane.getRightComponent());
      return (JTextPane) scrollPane.getViewport().getView();
    }

  }

}
TOP

Related Classes of tzar.mafiabot.gui.MafiaView$JTextComponentOutputStream

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.