com.sshtools.common.ui.SshToolsApplication.java Source code

Java tutorial

Introduction

Here is the source code for com.sshtools.common.ui.SshToolsApplication.java

Source

//Changes (c) CCLRC 2006
/*
 *  SSHTools - Java SSH2 API
 *
 *  Copyright (C) 2002 Lee David Painter.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public License
 *  as published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  You may also distribute it and/or modify it under the terms of the
 *  Apache style J2SSH Software License. A copy of which should have
 *  been provided with the distribution.
 *
 *  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
 *  License document supplied with your distribution for more details.
 *
 */

package com.sshtools.common.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.security.AccessControlException;
import java.security.AccessController;
import java.util.Iterator;
import java.util.Vector;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sshtools.common.mru.MRUList;
import com.sshtools.common.mru.MRUListModel;
import com.sshtools.common.util.BrowserLauncher;
import com.sshtools.j2ssh.configuration.ConfigurationLoader;
import com.sshtools.j2ssh.io.IOUtil;

/**
 * An abstract application class that provides container management, look
 * and feel configuration and most recently used menus.
 *
 * @author Brett Smith
 * @version $Revision: 1.7 $
 */
public abstract class SshToolsApplication {
    /**  */
    public final static String PREF_CONNECTION_LAST_HOST = "apps.connection.lastHost";

    /**  */
    public final static String PREF_CONNECTION_LAST_USER = "apps.connection.lastUser";

    /**  */
    public final static String PREF_CONNECTION_LAST_PORT = "apps.connection.lastPort";

    /**  */
    public final static String PREF_CONNECTION_LAST_KEY = "apps.connection.lastKey";

    /**  */
    public final static String PREF_LAF = "apps.laf";

    /**  */
    public final static String CROSS_PLATFORM_LAF = "CROSS_PLATFORM";

    /**  */
    public final static String DEFAULT_LAF = "DEFAULT";

    /**  */
    public final static String SYSTEM_LAF = "SYSTEM";

    /**  */
    protected static Vector containers = new Vector();

    /**  */
    protected static Log log = LogFactory.getLog(SshToolsApplication.class);

    /**  */
    protected static MRUListModel mruModel;
    private static UIManager.LookAndFeelInfo[] allLookAndFeelInfo;

    static {
        UIManager.LookAndFeelInfo[] i;

        try {
            i = UIManager.getInstalledLookAndFeels();
        } catch (Throwable t) {
            i = new UIManager.LookAndFeelInfo[0];
        }

        allLookAndFeelInfo = new UIManager.LookAndFeelInfo[i.length + 3];
        System.arraycopy(i, 0, allLookAndFeelInfo, 0, i.length);
        allLookAndFeelInfo[i.length] = new UIManager.LookAndFeelInfo("Default", DEFAULT_LAF);
        allLookAndFeelInfo[i.length + 1] = new UIManager.LookAndFeelInfo("Cross Platform", CROSS_PLATFORM_LAF);
        allLookAndFeelInfo[i.length + 2] = new UIManager.LookAndFeelInfo("System", SYSTEM_LAF);
    }

    /**  */
    protected Class panelClass;

    /**  */
    protected Class defaultContainerClass;

    /**  */
    protected java.util.List additionalOptionsTabs;

    /**
     * Creates a new SshToolsApplication object.
     *
     * @param panelClass
     * @param defaultContainerClass
     */
    public SshToolsApplication(Class panelClass, Class defaultContainerClass) {
        this.panelClass = panelClass;
        this.defaultContainerClass = defaultContainerClass;
        additionalOptionsTabs = new java.util.ArrayList();

        try {
            if (System.getSecurityManager() != null) {
                AccessController.checkPermission(new FilePermission("<<ALL FILES>>", "write"));
            }

            File a = getApplicationPreferencesDirectory();

            if (a == null) {
                throw new AccessControlException("Application preferences directory not specified.");
            }

            InputStream in = null;
            MRUList mru = new MRUList();

            try {
                File f = new File(a, getApplicationName() + ".mru");

                if (f.exists()) {
                    if (log.isDebugEnabled()) {
                        log.debug("Loading MRU from " + f.getAbsolutePath());
                    }

                    in = new FileInputStream(f);
                    mru.reload(in);
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug("MRU file " + f.getAbsolutePath() + " doesn't exist, creating empty list");
                    }
                }
            } catch (Exception e) {
                log.error("Could not load MRU list.", e);
            } finally {
                IOUtil.closeStream(in);
            }

            mruModel = new MRUListModel();
            mruModel.setMRUList(mru);
        } catch (AccessControlException ace) {
            log.error("Could not load MRU.", ace);
        }
    }

    /**
     *
     *
     * @return
     */
    public static UIManager.LookAndFeelInfo[] getAllLookAndFeelInfo() {
        return allLookAndFeelInfo;
    }

    /**
     *
     *
     * @return
     */
    public MRUListModel getMRUModel() {
        return mruModel;
    }

    /**
     *
     *
     * @return
     */
    public abstract String getApplicationName();

    /**
     *
     *
     * @return
     */
    public abstract String getApplicationVersion();

    /**
     *
     *
     * @return
     */
    public abstract Icon getApplicationLargeIcon();

    /**
     *
     *
     * @return
     */
    public abstract String getAboutLicenseDetails();

    /**
     *
     *
     * @return
     */
    public abstract String getAboutURL();

    /**
     *
     *
     * @return
     */
    public abstract String getAboutAuthors();

    /**
     *
     *
     * @return
     */
    public abstract File getApplicationPreferencesDirectory();

    /**
     *
     *
     * @return
     */
    public OptionsTab[] getAdditionalOptionsTabs() {
        OptionsTab[] t = new OptionsTab[additionalOptionsTabs.size()];
        additionalOptionsTabs.toArray(t);

        return t;
    }

    /**
     *
     *
     * @param tab
     */
    public void addAdditionalOptionsTab(OptionsTab tab) {
        if (!additionalOptionsTabs.contains(tab)) {
            additionalOptionsTabs.add(tab);
        }
    }

    /**
     *
     *
     * @param tab
     */
    public void removeAdditionalOptionsTab(OptionsTab tab) {
        additionalOptionsTabs.remove(tab);
    }

    /**
     *
     *
     * @param title
     */
    public void removeAdditionalOptionsTab(String title) {
        OptionsTab t = getOptionsTab(title);

        if (t != null) {
            removeAdditionalOptionsTab(t);
        }
    }

    /**
     *
     *
     * @param title
     *
     * @return
     */
    public OptionsTab getOptionsTab(String title) {
        for (Iterator i = additionalOptionsTabs.iterator(); i.hasNext();) {
            OptionsTab t = (OptionsTab) i.next();

            if (t.getTabTitle().equals(title)) {
                return t;
            }
        }

        return null;
    }

    /**
     *
     */
    public void exit(boolean kill) {
        log.debug("Exiting application");
        PreferencesStore.savePreferences();

        FileOutputStream out = null;
        File a = getApplicationPreferencesDirectory();

        if (a != null) {
            try {
                File f = new File(getApplicationPreferencesDirectory(), getApplicationName() + ".mru");
                ;

                if (log.isDebugEnabled()) {
                    log.debug("Saving MRU to " + f.getAbsolutePath());
                }

                out = new FileOutputStream(f);

                PrintWriter w = new PrintWriter(out, true);
                w.println(mruModel.getMRUList().toString());
            } catch (IOException ioe) {
                log.error("Could not save MRU. ", ioe);
            } finally {
                IOUtil.closeStream(out);
            }
        } else {
            log.debug("Not saving preferences because no preferences directory is available.");
        }
        if (kill) {
            com.sshtools.common.util.ShutdownHooks.exit(kill);
        }
    }

    /**
     *
     *
     * @return
     */
    public int getContainerCount() {
        return containers.size();
    }

    /**
     *
     *
     * @param idx
     *
     * @return
     */
    public SshToolsApplicationContainer getContainerAt(int idx) {
        return (SshToolsApplicationContainer) containers.elementAt(idx);
    }

    /**
     *
     *
     * @param panel
     *
     * @return
     */
    public SshToolsApplicationContainer getContainerForPanel(SshToolsApplicationPanel panel) {
        for (Iterator i = containers.iterator(); i.hasNext();) {
            SshToolsApplicationContainer c = (SshToolsApplicationContainer) i.next();

            if (c.getApplicationPanel() == panel) {
                return c;
            }
        }

        return null;
    }

    /**
     *
     *
     * @param container
     */
    public void closeContainer(SshToolsApplicationContainer container) {
        if (log.isDebugEnabled()) {
            log.debug("Asking " + container + " if it can close");
        }

        if (container.getApplicationPanel().canClose()) {
            if (log.isDebugEnabled()) {
                log.debug("Closing");

                for (Iterator i = containers.iterator(); i.hasNext();) {
                    log.debug(i.next() + " is currently open");
                }
            }

            container.getApplicationPanel().close();
            container.closeContainer();
            containers.removeElement(container);

            if (containers.size() == 0) {
                exit(true);
            } else {
                log.debug("Not closing completely because there are containers still open");

                for (Iterator i = containers.iterator(); i.hasNext();) {
                    log.debug(i.next() + " is still open");
                }
            }
        }
    }

    /**
     * Show an 'About' dialog
     *
     *
     */
    public void showAbout(final Component parent) {

        JPanel p = new JPanel(new GridBagLayout());
        p.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

        GridBagConstraints gBC = new GridBagConstraints();
        gBC.anchor = GridBagConstraints.CENTER;
        gBC.fill = GridBagConstraints.HORIZONTAL;
        gBC.insets = new Insets(1, 1, 1, 1);

        JLabel a = new JLabel(getApplicationName());
        a.setFont(a.getFont().deriveFont(24f));
        UIUtil.jGridBagAdd(p, a, gBC, GridBagConstraints.REMAINDER);

        MultilineLabel v = new MultilineLabel(getApplicationName() + " " + getApplicationVersion());
        v.setFont(v.getFont().deriveFont(10f));
        UIUtil.jGridBagAdd(p, v, gBC, GridBagConstraints.REMAINDER);

        MultilineLabel x = new MultilineLabel(getAboutAuthors());
        x.setBorder(BorderFactory.createEmptyBorder(8, 0, 8, 0));
        x.setFont(x.getFont().deriveFont(12f));
        UIUtil.jGridBagAdd(p, x, gBC, GridBagConstraints.REMAINDER);

        MultilineLabel c = new MultilineLabel(getAboutLicenseDetails());
        c.setFont(c.getFont().deriveFont(10f));
        UIUtil.jGridBagAdd(p, c, gBC, GridBagConstraints.REMAINDER);

        final JLabel h = new JLabel(getAboutURL());
        h.setForeground(Color.blue);
        h.setFont(new Font(h.getFont().getName(), Font.BOLD, 10));
        h.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        h.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                try {
                    BrowserLauncher.openURL(getAboutURL());
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        });
        UIUtil.jGridBagAdd(p, h, gBC, GridBagConstraints.REMAINDER);

        JOptionPane.showMessageDialog(parent, p, "About", JOptionPane.PLAIN_MESSAGE, getApplicationLargeIcon());
    }

    public void openChangelog(Component parent) {

        JPanel p = new JPanel(new GridBagLayout());
        p.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

        GridBagConstraints gBC = new GridBagConstraints();
        gBC.anchor = GridBagConstraints.CENTER;
        gBC.fill = GridBagConstraints.HORIZONTAL;
        gBC.insets = new Insets(1, 1, 1, 1);

        JLabel a = new JLabel(getApplicationName());
        a.setFont(a.getFont().deriveFont(24f));
        UIUtil.jGridBagAdd(p, a, gBC, GridBagConstraints.REMAINDER);

        String changelog = "";
        try {
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(getClass().getResourceAsStream("/changelog")));
            String line = br.readLine();
            while (line != null) {
                changelog += line + "\n";
                line = br.readLine();
            }
            br.close();
        } catch (Exception e) {
            changelog = "<Error opening changelog>\n";
        }

        javax.swing.JTextArea message = new javax.swing.JTextArea(changelog);
        message.setEditable(false);
        message.setBorder(javax.swing.BorderFactory.createEmptyBorder(4, 4, 4, 4));
        javax.swing.JLabel jl = new javax.swing.JLabel();
        message.setFont(jl.getFont());
        message.setBackground(jl.getBackground());

        //   MultilineLabel x = new MultilineLabel(changelog);
        //   x.setBorder(BorderFactory.createEmptyBorder(8, 0, 8, 0));
        //   x.setFont(x.getFont().deriveFont(12f));   
        javax.swing.JScrollPane scrollPane = new javax.swing.JScrollPane();
        scrollPane.getViewport().add(message);
        scrollPane.setSize(400, 200);
        scrollPane.setPreferredSize(new java.awt.Dimension(400, 200));
        UIUtil.jGridBagAdd(p, scrollPane, gBC, GridBagConstraints.REMAINDER);

        JOptionPane.showMessageDialog(parent, p, "Change log", JOptionPane.PLAIN_MESSAGE,
                getApplicationLargeIcon());
    }

    /**
     *
     *
     * @return
     *
     * @throws SshToolsApplicationException
     */
    public SshToolsApplicationContainer newContainer() throws SshToolsApplicationException {
        SshToolsApplicationContainer container = null;

        try {
            container = (SshToolsApplicationContainer) defaultContainerClass.newInstance();
            newContainer(container);

            return container;
        } catch (Throwable t) {
            throw new SshToolsApplicationException(t);
        }
    }

    /**
     *
     *
     * @param container
     *
     * @throws SshToolsApplicationException
     */
    public void newContainer(SshToolsApplicationContainer container) throws SshToolsApplicationException {
        try {
            SshToolsApplicationPanel panel = (SshToolsApplicationPanel) panelClass.newInstance();
            panel.init(this);
            panel.rebuildActionComponents();
            panel.setAvailableActions();
            container.init(this, panel);
            panel.setContainer(container);

            if (!container.isContainerVisible()) {
                container.setContainerVisible(true);
            }

            containers.addElement(container);
        } catch (Throwable t) {
            throw new SshToolsApplicationException(t);
        }
    }

    /**
     *
     *
     * @param container
     * @param newContainerClass
     *
     * @return
     *
     * @throws SshToolsApplicationException
     */
    public SshToolsApplicationContainer convertContainer(SshToolsApplicationContainer container,
            Class newContainerClass) throws SshToolsApplicationException {
        log.info("Converting container of class " + container.getClass().getName() + " to "
                + newContainerClass.getName());

        int idx = containers.indexOf(container);

        if (idx == -1) {
            throw new SshToolsApplicationException("Container is not being manager by the application.");
        }

        SshToolsApplicationContainer newContainer = null;

        try {
            container.closeContainer();

            SshToolsApplicationPanel panel = container.getApplicationPanel();
            newContainer = (SshToolsApplicationContainer) newContainerClass.newInstance();
            newContainer.init(this, panel);
            panel.setContainer(newContainer);

            if (!newContainer.isContainerVisible()) {
                newContainer.setContainerVisible(true);
            }

            containers.setElementAt(newContainer, idx);

            return newContainer;
        } catch (Throwable t) {
            throw new SshToolsApplicationException(t);
        }
    }

    /**
     *
     *
     * @param args
     *
     * @throws SshToolsApplicationException
     */
    public void init(String[] args) throws SshToolsApplicationException {
        File f = getApplicationPreferencesDirectory();

        if (f != null) {
            //
            PreferencesStore.init(new File(f, getApplicationName() + ".properties"));
            log.info("Preferences will be saved to " + f.getAbsolutePath());
        } else {
            log.warn("No preferences can be saved.");
        }

        try {
            setLookAndFeel(PreferencesStore.get(PREF_LAF, SYSTEM_LAF));

            UIManager.put("OptionPane.errorIcon", new ResourceIcon(SshToolsApplication.class, "dialog-error4.png"));
            UIManager.put("OptionPane.informationIcon",
                    new ResourceIcon(SshToolsApplication.class, "dialog-information.png"));
            UIManager.put("OptionPane.warningIcon",
                    new ResourceIcon(SshToolsApplication.class, "dialog-warning2.png"));
            UIManager.put("OptionPane.questionIcon",
                    new ResourceIcon(SshToolsApplication.class, "dialog-question3.png"));
        } catch (Throwable t) {
            log.error(t);
        }
    }

    /**
     *
     *
     * @param className
        
        
     *
     * @throws Exception
     */
    public static void setLookAndFeel(String className) throws Exception {
        LookAndFeel laf = null;

        if (!className.equals(DEFAULT_LAF)) {
            if (className.equals(SYSTEM_LAF)) {
                String systemLaf = UIManager.getSystemLookAndFeelClassName();
                log.debug("System Look And Feel is " + systemLaf);
                laf = (LookAndFeel) Class.forName(systemLaf).newInstance();
            } else if (className.equals(CROSS_PLATFORM_LAF)) {
                String crossPlatformLaf = UIManager.getCrossPlatformLookAndFeelClassName();
                log.debug("Cross Platform Look And Feel is " + crossPlatformLaf);
                laf = (LookAndFeel) Class.forName(crossPlatformLaf).newInstance();
            } else {
                laf = (LookAndFeel) Class.forName(className).newInstance();
            }
        }

        //  Now actually set the look and feel
        if (laf != null) {
            log.info("Setting look and feel " + laf.getName() + " (" + laf.getClass().getName() + ")");
            UIManager.setLookAndFeel(laf);
            UIManager.put("EditorPane.font", UIManager.getFont("TextArea.font"));
        }
    }
}