/* * 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 gui.actions.AbstractCanceableAction; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.HeadlessException; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.WindowConstants; import javax.swing.filechooser.FileFilter; import analyser.gui.LineBuilder; import analyser.gui.Settings; import analyser.gui.TextDialog; import analyser.logic.Resolver; public abstract class AbstractMainFrame extends JFrame implements WindowListener { private static final long serialVersionUID = 30185815714572237L; protected JLabel m_bottomInfo = new JLabel(); protected Resolver m_resolver; protected Map<AbstractCanceableAction, ProgressDialog> m_progressBars = new HashMap<AbstractCanceableAction, ProgressDialog>(); protected AbstractMainFrame() { super(); } public void actionStarted(AbstractCanceableAction action) { ProgressDialog pd = m_progressBars.get(action); if (pd == null) { pd = new ProgressDialog(this, action, action.getWorkDescription()); int x = getLocationOnScreen().x + (getWidth() - ProgressDialog.WIDTH) / 2; int y = getLocationOnScreen().y + (getHeight() - ProgressDialog.HEIGHT) / 2; pd.setLocation(x, y); pd.setVisible(true); m_progressBars.put(action, pd); Thread.yield(); } } public void actionCancelled(AbstractCanceableAction action) { actionFinished(action); } public void actionFinished(AbstractCanceableAction action) { ProgressDialog pd = m_progressBars.get(action); if (pd != null) { pd.setVisible(false); pd.dispose(); m_progressBars.put(action, null); } } public void actionReportWork(AbstractCanceableAction action, int percentage) { ProgressDialog pd = m_progressBars.get(action); if (pd != null) { pd.reportWork(percentage); Thread.yield(); } } public void initialize(int width, int height) throws HeadlessException { setTitle(getStaticTitle()); setup(width, height); } protected String getStaticTitle() { return Settings.getApplicationName(); } public void setAppendedTitle(String append) { setTitle(getStaticTitle() + " " + append); } protected void setup(int width, int height) { setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addWindowListener(this); getContentPane().setLayout(new BorderLayout()); getContentPane().add(createMenuBar(), BorderLayout.NORTH); getContentPane().add(m_bottomInfo, BorderLayout.SOUTH); initBottomInfo(); m_bottomInfo.setForeground(Color.DARK_GRAY); JPanel buttons = createButtonBar(); if (buttons == null) { setupGui(getContentPane(), width, height); } else { JPanel subContent = new JPanel(); subContent.setLayout(new BorderLayout()); subContent.add(buttons, BorderLayout.NORTH); getContentPane().add(subContent, BorderLayout.CENTER); setupGui(subContent, width, height - buttons.getHeight()); } } protected abstract void setupGui(Container pane, int width, int height); public int showWarning(String header, String text, int optionType) { return JOptionPane.showConfirmDialog(this, text, header, optionType, JOptionPane.WARNING_MESSAGE); } public void showInformation(String header, String text) { JOptionPane.showMessageDialog(this, text, header, JOptionPane.INFORMATION_MESSAGE); } public void showError(Component c, String header, String text) { JOptionPane .showMessageDialog(c, text, header, JOptionPane.ERROR_MESSAGE); } public void showError(String header, String text) { showError(this, text, header); } public void showError(String header, Throwable e) { showError(this, header, ((e instanceof AppException) ? "" : e.getClass().getName() + ": ") + e.getMessage()); } public File selectFile(String title, String buttonText) { return selectFile(title, buttonText, null, null, false, false); } public File selectFile(String title, String buttonText, String fileSuffix, String filterDesc) { return selectFile(title, buttonText, fileSuffix, filterDesc, false, false); } public File selectFile(String title, String buttonText, boolean filesOnly, boolean directoriesOnly) { return selectFile(title, buttonText, null, null, filesOnly, directoriesOnly); } public File selectFile(String title, String buttonText, final String filterSuffix, final String filterDescr, final boolean filesOnly, final boolean directoriesOnly) { JFileChooser chooser = new JFileChooser(new File(Settings.getDefaultPath())); int fselMode = JFileChooser.FILES_AND_DIRECTORIES; if (filesOnly) { fselMode = JFileChooser.FILES_ONLY; } else if (directoriesOnly) { fselMode = JFileChooser.DIRECTORIES_ONLY; } chooser.setFileSelectionMode(fselMode); if (filterSuffix != null) { chooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return (f.isDirectory() || f.getName().toLowerCase().endsWith(filterSuffix.toLowerCase()) ); } @Override public String getDescription() { return filterDescr; } }); } chooser.setApproveButtonText(buttonText); chooser.setDialogTitle(title); int returnVal = chooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File f = chooser.getSelectedFile(); if (f.isDirectory()) { Settings.setDefaultPath(f.getAbsolutePath()); } else { Settings.setDefaultPath(f.getParentFile().getAbsolutePath()); } return f; } else { return null; } } public File[] selectFiles(String title, String buttonText, final String filterSuffix, final String filterDescr, final boolean filesOnly, final boolean directoriesOnly) { JFileChooser chooser = new JFileChooser(new File(Settings.getDefaultPath())); int fselMode = JFileChooser.FILES_AND_DIRECTORIES; if (filesOnly) { fselMode = JFileChooser.FILES_ONLY; } else if (directoriesOnly) { fselMode = JFileChooser.DIRECTORIES_ONLY; } chooser.setFileSelectionMode(fselMode); chooser.setMultiSelectionEnabled(true); if (filterSuffix != null) { chooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { boolean accept = f.isDirectory(); String[] suffixes = filterSuffix.split(";"); for (String suffix : suffixes) { if (accept == false && f.getName().toLowerCase().endsWith(suffix.toLowerCase())) { accept = true; break; } } return accept; } @Override public String getDescription() { return filterDescr; } }); } chooser.setApproveButtonText(buttonText); chooser.setDialogTitle(title); int returnVal = chooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] f = chooser.getSelectedFiles(); if (f != null && f.length > 0) { if (f[0].isDirectory()) { Settings.setDefaultPath(f[0].getAbsolutePath()); } else { Settings.setDefaultPath(f[0].getParentFile().getAbsolutePath()); } } return f; } else { return null; } } protected abstract JMenuBar createMenuBar(); protected abstract JPanel createButtonBar(); public void exit() { System.exit(0); } public void initBottomInfo() { m_bottomInfo.setText("Ready"); } public void setBottomInfo(String s) { m_bottomInfo.setText(s); } public int showDialog(String title, String message, int options) { return JOptionPane.showConfirmDialog(this, message, title, options, JOptionPane.QUESTION_MESSAGE); } int tX; int tY; void initTextDialog(TextDialog tw) { int w = 900; int h = 700; if (Settings.getTextWindowWidth() > 0 && Settings.getTextWindowHeight() > 0) { w = Settings.getTextWindowWidth(); h = Settings.getTextWindowHeight(); } tw.setSize(w, h); int x = Math.max(0, getLocationOnScreen().x + (getWidth() - w) / 2); int y = Math.max(0, getLocationOnScreen().y + (getHeight() - h) / 2); tw.setLocation(x + tX, y + tY); tw.setVisible(true); tw.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { Component c = e.getComponent(); Settings.setTextWindowWidth(c.getWidth()); Settings.setTextWindowHeight(c.getHeight()); } }); tX += 10; tX &= 0x3f; tY += 22; tY &= 0x3f; } public void showText(String title, String text) { TextDialog tw = new TextDialog(this, title, text); initTextDialog(tw); } public TextDialog showText(String title, LineBuilder lb) { TextDialog tw = new TextDialog(this, title, lb); initTextDialog(tw); return tw; } public void showText(String title, String text, JButton[] customButtons) { TextDialog tw = new TextDialog(this, title, text, customButtons); initTextDialog(tw); } public TextDialog showText(String title, LineBuilder lb, JButton[] customButtons) { TextDialog tw = new TextDialog(this, title, lb, customButtons); initTextDialog(tw); return tw; } // WindowListener Impl @Override public void windowClosing(WindowEvent e) { boolean exit = true; try { Settings.setMainFrameX((int) getLocationOnScreen().getX()); Settings.setMainFrameY((int) getLocationOnScreen().getY()); Settings.setMainFrameHeight(getHeight()); Settings.setMainFrameWidth(getWidth()); saveSettingsOnClose(); Settings.store(); } catch (IOException ioe) { ioe.printStackTrace(); exit = showWarning("Warning!", "Could not save settings file.\nProceed anyway?", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION; } if (exit) { dispose(); exit(); } } protected abstract void saveSettingsOnClose() throws IOException; @Override public void windowClosed(WindowEvent e) { } @Override public void windowOpened(WindowEvent e) { } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } String[] breakString(String s, String separator) { StringTokenizer st = new StringTokenizer(s, separator); List<String> res = new ArrayList<String>(); while (st.hasMoreTokens()) { res.add(st.nextToken()); } return res.toArray(new String[res.size()]); } }