/* * Copyright (C) 2012 Sony Mobile Communications AB * * This file is part of ApkAnalyser. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import util.ProcessHandler; import util.ProcessListener; import andreflect.adb.ConsoleWindowListener; public class ConsoleWindow implements ProcessListener { static ConsoleWindow inst = null; ProcessHandler process; JTextArea text; JFrame console; ConsoleWindowListener listener; protected int curSearchPos = 0; protected String curSearchString = null; protected JButton EButton = null; protected JButton IButton = null; protected JButton WButton = null; protected JButton FButton = null; protected JButton SButton = null; protected JButton DButton = null; protected JButton VButton = null; private ConsoleWindow() { } public synchronized static ConsoleWindow getInstance() { if (inst == null) { inst = new ConsoleWindow(); } return inst; } synchronized void init(String title) { if (console == null) { console = new JFrame(title); text = new JTextArea(); text.setFont(new Font("lucida console", Font.PLAIN, 10)); text.setBackground(Color.black); text.setForeground(new Color(192, 255, 192)); text.setEditable(false); text.setWrapStyleWord(true); text.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { if ((e.getModifiers() & KeyEvent.CTRL_MASK) > 0 && e.getKeyCode() == KeyEvent.VK_F) { String s = (String) JOptionPane.showInputDialog(text.getParent(), "", "Search", JOptionPane.QUESTION_MESSAGE, null, null, (curSearchString == null ? "" : curSearchString)); if (s != null) { curSearchString = s; curSearchPos = 0; findNext(curSearchString); text.repaint(); } } else if (e.getKeyCode() == KeyEvent.VK_F3) { if (curSearchString != null) { if ((e.getModifiers() & KeyEvent.SHIFT_MASK) > 0) { findPrev(curSearchString); } else { findNext(curSearchString); } text.repaint(); } } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } }); console.getContentPane().setLayout(new BorderLayout()); console.getContentPane().add(new JScrollPane(text), BorderLayout.CENTER); console.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent w) { synchronized (ConsoleWindow.this) { console = null; process.kill(); } } }); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); JButton exitButton = new JButton("Close"); exitButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { close(); } }); JButton clsButton = new JButton("Clear"); clsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { text.setText(""); if (listener != null) { listener.onClear(process); } } }); JButton restartButton = new JButton("Relaunch"); restartButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); IButton = new JButton("I"); IButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onI(process); EButton.setEnabled(true); DButton.setEnabled(true); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(false); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); VButton = new JButton("V"); VButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onV(process); EButton.setEnabled(true); DButton.setEnabled(true); VButton.setEnabled(false); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); DButton = new JButton("D"); DButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onD(process); EButton.setEnabled(true); DButton.setEnabled(false); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); SButton = new JButton("S"); SButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onS(process); EButton.setEnabled(true); DButton.setEnabled(true); VButton.setEnabled(true); SButton.setEnabled(false); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); WButton = new JButton("W"); WButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onW(process); EButton.setEnabled(true); DButton.setEnabled(true); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(false); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); FButton = new JButton("F"); FButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onF(process); EButton.setEnabled(true); DButton.setEnabled(true); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(false); WButton.setEnabled(true); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); EButton = new JButton("E"); EButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { text.setText(""); listener.onE(process); EButton.setEnabled(false); DButton.setEnabled(true); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(true); process.restart(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); buttonPanel.add(VButton); buttonPanel.add(DButton); buttonPanel.add(IButton); buttonPanel.add(WButton); buttonPanel.add(EButton); buttonPanel.add(FButton); buttonPanel.add(SButton); buttonPanel.add(clsButton); buttonPanel.add(restartButton); buttonPanel.add(exitButton); console.getContentPane().add(buttonPanel, BorderLayout.SOUTH); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int inset = 200; int x = inset; int y = inset; int width = Math.min(800, screenSize.width - inset * 2); int height = Math.min(600, screenSize.height - inset * 2); console.setBounds(x, y, width, height); console.setVisible(true); } } public synchronized void start(String title, ProcessHandler p, ConsoleWindowListener listener) throws IOException { init(title); this.listener = listener; EButton.setEnabled(true); DButton.setEnabled(false); VButton.setEnabled(true); SButton.setEnabled(true); FButton.setEnabled(true); WButton.setEnabled(true); IButton.setEnabled(true); text.setText(""); if (process != null) { process.kill(); } process = p; process.addProcessListener(this); p.start(); } public synchronized void start(String title, ProcessHandler p) throws IOException { init(title); listener = null; EButton.setEnabled(false); DButton.setEnabled(false); VButton.setEnabled(false); SButton.setEnabled(false); FButton.setEnabled(false); WButton.setEnabled(false); IButton.setEnabled(false); text.setText(""); if (process != null) { process.kill(); } process = p; process.addProcessListener(this); p.start(); } public synchronized void close() { console.dispose(); console = null; process.kill(); } public void findNext(String search) { String t = text.getText(); curSearchPos = t.indexOf(search, curSearchPos + 1); int selPos = curSearchPos; if (curSearchPos >= 0) { text.setCaretPosition(selPos); text.setSelectionStart(selPos); text.setSelectionEnd(selPos + search.length()); } else { java.awt.Toolkit.getDefaultToolkit().beep(); text.setSelectionStart(0); text.setSelectionEnd(0); curSearchPos = 0; } } public void findPrev(String search) { String t = text.getText(); int br = curSearchPos - 1; if (br < 0) { br = 0; } curSearchPos = t.substring(0, br).lastIndexOf(search); int selPos = curSearchPos; if (curSearchPos >= 0) { text.setCaretPosition(selPos); text.setSelectionStart(selPos); text.setSelectionEnd(selPos + search.length()); } else { java.awt.Toolkit.getDefaultToolkit().beep(); text.setSelectionStart(t.length() - 1); text.setSelectionEnd(t.length() - 1); curSearchPos = t.length() - 1; } } // ProcessListener impl @Override public void started() { } @Override public void died(int ret) { //text.append("\n\n[PROCESS DIED, RETURN CODE " + ret + "]\n\n"); } @Override public void stderr(char c) { } @Override public void stdout(char c) { text.append(Character.toString(c)); if (c == '\n') { text.setCaretPosition(text.getText().length()); } } }