/* Copyright 2009 Hauke Rehfeld This file is part of QuakeInjector. QuakeInjector is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QuakeInjector 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 QuakeInjector. If not, see <http://www.gnu.org/licenses/>. */ package de.haukerehfeld.quakeinjector; import java.awt.BorderLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingWorker; import javax.swing.KeyStroke; import javax.swing.JComponent; import de.haukerehfeld.quakeinjector.gui.OkayCancelApplyPanel; public class EngineOutputDialog extends JDialog { private final static String windowTitle = "Engine Output"; private final static String outputQIPrefix = "[Quake Injector]: "; private final InputStream engineOut; private final JTextArea output; public EngineOutputDialog(final JFrame parent, final InputStream engineOut) { super(parent, windowTitle, true); this.engineOut = engineOut; output = new JTextArea(30, 80); output.setLineWrap(true); JScrollPane panelScroll = new JScrollPane(output); panelScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); panelScroll.getViewport().setBackground(javax.swing.UIManager.getColor("TextPane.background")); add(panelScroll, BorderLayout.CENTER); final JButton close = new JButton("Close"); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); } }); add(new OkayCancelApplyPanel(close, null, null, false), BorderLayout.PAGE_END); addEscapeListener(this); // this is probably not how you do it... -Spirit new SwingWorker<Void,Void>() { @Override public Void doInBackground() { try { InputStreamReader in = new InputStreamReader(engineOut); BufferedReader b = new BufferedReader(in); output.append(outputQIPrefix+"Starting engine...\n"); String line; int lineCount = 0; while ((line = b.readLine()) != null) { //append is thread safe output.append(line.trim() + "\n"); lineCount++; //scroll on the event thread javax.swing.SwingUtilities.invokeLater(new SwingWorker<Void,Void>() { public Void doInBackground() { output.scrollRectToVisible(new Rectangle(0, output.getHeight(), 0, 10)); return null; } }); } if (lineCount == 0) { output.append(outputQIPrefix+"Done with no output.\n"); } else { output.append(outputQIPrefix+"Done.\n"); } } catch (java.io.IOException e) { output.append(outputQIPrefix+"Error: Couldn't read engine output from stream"); } return null; } @Override public void done() { } }.execute(); } // from http://stackoverflow.com/questions/642925/swing-how-do-i-close-a-dialog-when-the-esc-key-is-pressed -Spirit public static void addEscapeListener(final JDialog dialog) { ActionListener escListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dialog.dispose(); } }; dialog.getRootPane().registerKeyboardAction(escListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); } }