de.ipk_gatersleben.ag_nw.graffiti.services.GUIhelper.java Source code

Java tutorial

Introduction

Here is the source code for de.ipk_gatersleben.ag_nw.graffiti.services.GUIhelper.java

Source

/*******************************************************************************
 * Copyright (c) 2003-2007 Network Analysis Group, IPK Gatersleben
 *******************************************************************************/
package de.ipk_gatersleben.ag_nw.graffiti.services;

import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstants;

import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

import org.AttributeHelper;
import org.BackgroundTaskStatusProviderSupportingExternalCall;
import org.ErrorMsg;
import org.FolderPanel;
import org.JLabelJavaHelpLink;
import org.JMButton;
import org.ObjectRef;
import org.OpenFileDialogService;
import org.ReleaseInfo;
import org.apache.commons.net.ProtocolCommandEvent;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.graffiti.editor.MainFrame;
import org.graffiti.editor.MessageType;
import org.graffiti.plugin.algorithm.ThreadSafeOptions;

import de.ipk_gatersleben.ag_nw.graffiti.plugins.databases.FileDownloadStatusInformationProvider;
import de.ipk_gatersleben.ag_nw.graffiti.services.task.BackgroundTaskHelper;
import de.ipk_gatersleben.ag_nw.graffiti.services.task.BackgroundTaskStatusProviderSupportingExternalCallImpl;

public class GUIhelper {

    public static Component getHelpTextComponent(String plainText, String title, String helpTopic) {
        JPanel result = new JPanel();
        plainText = plainText.replaceAll("<br>", "\n");
        plainText = plainText.replaceAll("<html>", "");
        plainText = plainText.replaceAll("<small>", "");
        FolderPanel fp = new FolderPanel(title, false, false, false,
                JLabelJavaHelpLink.getHelpActionListener(helpTopic));
        JTextArea helpText = new JTextArea();
        helpText.setLineWrap(true);
        helpText.setWrapStyleWord(true);
        helpText.setText(plainText);
        helpText.setEditable(false);
        fp.addGuiComponentRow(new JLabel(""), helpText, false);
        fp.layoutRows();
        fp.setFrameColor(Color.LIGHT_GRAY, Color.WHITE, 1, 5);

        double border = 2;
        double topBorder = 12;
        double[][] size = { { border, TableLayoutConstants.FILL, border }, // Columns
                { topBorder, TableLayoutConstants.PREFERRED, border } }; // Rows
        result.setLayout(new TableLayout(size));
        result.add(fp, "1,1");
        return result;
    }

    // returns index of pressed button or -1 if no button was clicked but the
    // window is
    // closed
    public static int showMessageDialog(Object guiComponentOrText, String title, String[] buttons) {

        JComponent content = null;

        if (guiComponentOrText instanceof String) {
            content = new JLabel((String) guiComponentOrText);
            ((JLabel) content).setOpaque(false);
            ((JLabel) content).setBackground(null);
        } else
            content = (JComponent) guiComponentOrText;

        MyDialog md = new MyDialog(MainFrame.getInstance(), title, buttons, content, 5);
        md.setBounds(MainFrame.getRelativeCenterPosition(md));
        md.setVisible(true);
        return md.getReturnValue();
    }

    public static JComponent getWebsiteButton(String title, final String url, final String opt_local_folder,
            final String optIntroText, final String optIntroDialogTitle) {
        JButton res = new JButton(title);
        res.setToolTipText("<html>Click button to open URL:<br><code><b>" + url);
        res.addActionListener(getDialogAction(url, opt_local_folder, optIntroText, optIntroDialogTitle));
        return res;
    }

    private static ActionListener getDialogAction(final String url, final String opt_local_folder,
            final String optIntroText, final String optIntroDialogTitle) {
        return new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                if (optIntroText != null) {
                    Thread t = new Thread() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(5000);
                            } catch (InterruptedException e) {
                                // empty
                            }
                            AttributeHelper.showInBrowser(url);
                            if (opt_local_folder != null && opt_local_folder.length() > 0)
                                AttributeHelper.showInBrowser(opt_local_folder);
                        }
                    };
                    t.start();
                    showMessageDialog(optIntroText, optIntroDialogTitle, new String[] { "OK" });
                } else {
                    AttributeHelper.showInBrowser(url);
                    if (opt_local_folder != null && opt_local_folder.length() > 0)
                        AttributeHelper.showInBrowser(opt_local_folder);
                }
            }
        };
    }

    public static JComponent getWebsiteDownloadButton(final String title, final String optUrlManualDownloadWebsite,
            final String target_dir_null_ask_user, final String optIntroText, final String[] downloadURLs,
            final String optIntroDialogTitle, final FileDownloadStatusInformationProvider statusProvider) {
        return getWebsiteDownloadButton(title, optUrlManualDownloadWebsite, target_dir_null_ask_user, optIntroText,
                downloadURLs, optIntroDialogTitle, statusProvider, null);
    }

    public static JComponent getWebsiteDownloadButton(final String title, final String optUrlManualDownloadWebsite,
            final String target_dir_null_ask_user, final String optIntroText, final String[] downloadURLs,
            final String optIntroDialogTitle, final FileDownloadStatusInformationProvider statusProvider,
            final Runnable optFinishSwingTask) {

        final JButton res = new JMButton("Download/Update");
        res.setToolTipText(
                "<html>Click button to start automatic download<br><code><b>Check License/Disclaimers first!");
        res.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                final String opt_local_folder;
                if (target_dir_null_ask_user == null) {
                    File file = OpenFileDialogService.getDirectoryFromUser("Select folder");
                    if (file == null)
                        return;
                    else
                        opt_local_folder = file.getAbsolutePath();
                } else {
                    opt_local_folder = target_dir_null_ask_user;
                }

                res.setEnabled(false);
                res.setText("Downloading");
                final BackgroundTaskStatusProviderSupportingExternalCallImpl status = new BackgroundTaskStatusProviderSupportingExternalCallImpl(
                        "Please wait...", "Downloading files...");
                BackgroundTaskHelper.issueSimpleTask(title, "Please wait...", new Runnable() {
                    public void run() {
                        boolean allOK = true;
                        for (String downloadURL : downloadURLs) {
                            allOK = performDownload(downloadURL, opt_local_folder, status);
                            if (status.wantsToStop()) {
                                break;
                            }
                        }
                        if (status.wantsToStop()) {
                            allOK = true;
                            try {
                                status.setCurrentStatusText1("Cancel...");
                                for (String downloadURL : downloadURLs) {
                                    String fileName = downloadURL.substring(downloadURL.lastIndexOf("/") + 1);
                                    if (downloadURL.contains("|"))
                                        fileName = downloadURL.substring(downloadURL.lastIndexOf("|") + 1);
                                    String targetFileName = ReleaseInfo.getAppFolderWithFinalSep() + fileName;
                                    if (new File(targetFileName).exists()) {
                                        new File(targetFileName).delete();
                                        status.setCurrentStatusText2("Delete " + targetFileName);
                                    }
                                }
                            } catch (Exception e) {
                                //
                            }
                        }

                        if (!allOK) {
                            res.setEnabled(true);
                            res.setText(
                                    "<html><small>Automatic download failure<br>Click here for manual download");
                            res.removeActionListener(res.getActionListeners()[0]);
                            res.addActionListener(getDialogAction(optUrlManualDownloadWebsite, opt_local_folder,
                                    optIntroText, optIntroDialogTitle));
                            res.requestFocus();
                            final JDialog jd = (JDialog) ErrorMsg.findParentComponent(res, JDialog.class);
                            if (jd != null) {
                                SwingUtilities.invokeLater(new Runnable() {
                                    public void run() {
                                        jd.pack();
                                    }
                                });
                            }
                        } else {
                            if (status.wantsToStop()) {
                                res.setText("Canceled");
                                status.pleaseContinueRun();
                                status.setCurrentStatusText2("Canceled!");
                            } else {
                                res.setText("Downloaded");
                            }
                            res.setEnabled(false);
                            if (statusProvider != null)
                                statusProvider.finishedNewDownload();
                            if (optFinishSwingTask != null)
                                SwingUtilities.invokeLater(optFinishSwingTask);
                        }
                    }
                }, null, status);
            }
        });
        return res;
    }

    public static boolean performDownload(String downloadURL, String opt_local_folder,
            BackgroundTaskStatusProviderSupportingExternalCallImpl status) {
        return performDownload(downloadURL, opt_local_folder, status, null);
    }

    public static ArrayList<String> performDirectoryListing(String downloadURL,
            BackgroundTaskStatusProviderSupportingExternalCall status) {
        if (status == null)
            status = new BackgroundTaskConsoleLogger("downloading: " + downloadURL, "please wait", false);
        String server, remote;

        runIdx++;
        final int thisRun = runIdx;

        server = downloadURL.substring("ftp://".length());
        remote = server.substring(server.indexOf("/") + "/".length());
        server = server.substring(0, server.indexOf("/"));

        ArrayList<String> result = null;

        final FTPClient ftp;
        ThreadSafeOptions tso;
        synchronized (host2ftp) {
            if (!host2ftp.containsKey(server)) {
                ThreadSafeOptions ttt = new ThreadSafeOptions();
                ttt.setParam(0, new FTPClient());
                host2ftp.put(server, ttt);
            }
            tso = host2ftp.get(server);
            ftp = (FTPClient) tso.getParam(0, null);
        }
        status.setCurrentStatusValue(0);

        try {
            result = listFiles(status, downloadURL, server, remote, ftp);
            status.setCurrentStatusText2("Finished: " + downloadURL);

            BackgroundTaskHelper.executeLaterOnSwingTask(10000, new Runnable() {
                public void run() {
                    try {
                        synchronized (GUIhelper.class) {
                            if (runIdx == thisRun) {
                                System.out.println("Disconnect FTP connection");
                                ftp.disconnect();
                            }
                        }
                    } catch (Exception err) {
                        ErrorMsg.addErrorMessage(err);
                    }
                }
            });
        } catch (Exception e) {
            ErrorMsg.addErrorMessage(e);
        }
        return result;
    }

    public static boolean performDownload(String downloadURL, String opt_local_folder,
            BackgroundTaskStatusProviderSupportingExternalCallImpl status, String targetfilename) {
        if (status == null)
            status = new BackgroundTaskConsoleLogger("downloading: " + downloadURL,
                    "target folder: " + opt_local_folder, false);
        String fileName = targetfilename;
        if (fileName == null)
            fileName = downloadURL.substring(downloadURL.lastIndexOf("/") + 1);
        if (downloadURL.contains("|")) {
            fileName = downloadURL.substring(downloadURL.lastIndexOf("|") + 1);
            downloadURL = downloadURL.substring(0, downloadURL.indexOf("|"));
        }
        String target = opt_local_folder;
        String targetFileName = target + fileName;
        boolean downloadOK = true;

        OutputStream out = null;
        URLConnection conn = null;
        InputStream in = null;
        long numWritten = 0;
        boolean ftp = false;
        ObjectRef lastStatus = new ObjectRef();
        try {
            boolean downloadNeeded = true;
            if (downloadURL.indexOf("ftp://") == 0) {
                ftp = true;
                try {
                    if (!processFTPdownload(status, downloadURL, targetFileName, lastStatus))
                        downloadOK = false;
                    else
                        downloadNeeded = false;
                } catch (Exception err) {
                    ftp = false;
                    System.out.println("ERROR: FTP download failed: " + err.getMessage());
                    System.out.println("INFO: TRYING DEFAULT URL DOWNLOAD METHOD");
                }
            }
            ;
            if (downloadNeeded) {
                URL url = new URL(downloadURL);
                conn = url.openConnection();
                int contentLength = conn.getContentLength();
                in = conn.getInputStream();
                byte[] buffer = new byte[512 * 1024];
                int numRead;
                out = new BufferedOutputStream(new FileOutputStream(targetFileName));
                status.setCurrentStatusText1(downloadURL);
                status.setCurrentStatusText2("Received " + (numWritten / 1024) + " KB");
                while ((numRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, numRead);
                    numWritten += numRead;
                    status.setCurrentStatusText1(downloadURL);
                    status.setCurrentStatusText2("Received " + (numWritten / 1024) + " KB");
                    if (contentLength > 0) {
                        status.setCurrentStatusValueFine(100d * numWritten / contentLength);
                    }
                    if (status.wantsToStop()) {
                        break;
                    }
                }
                downloadOK = true;
            }
        } catch (Exception e) {
            ErrorMsg.addErrorMessage(e);
            downloadOK = false;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
                if (ftp) {
                    if (lastStatus != null && lastStatus.getObject() != null
                            && (lastStatus.getObject() instanceof String)) {
                        status.setCurrentStatusText1((String) lastStatus.getObject());
                    } else
                        status.setCurrentStatusText1(status.getCurrentStatusMessage2());
                    status.setCurrentStatusText2("Finished: " + fileName);
                } else {
                    status.setCurrentStatusText1("Received " + (numWritten / 1024) + " KB");
                    status.setCurrentStatusText2("Finished: " + fileName);
                }
            } catch (Exception e) {
                ErrorMsg.addErrorMessage(e);
                downloadOK = false;
            }
        }
        return downloadOK;
    }

    private static final HashMap<String, ThreadSafeOptions> host2ftp = new HashMap<String, ThreadSafeOptions>();
    private static int runIdx = 0;

    private static boolean processFTPdownload(final BackgroundTaskStatusProviderSupportingExternalCallImpl status,
            String downloadURL, String targetFileName, ObjectRef lastStatus) throws InterruptedException {
        runIdx++;
        final int thisRun = runIdx;
        status.setCurrentStatusText1(downloadURL);
        status.setCurrentStatusText2("FTP DOWNLOAD...");
        String server, remote;

        server = downloadURL.substring("ftp://".length());
        remote = server.substring(server.indexOf("/") + "/".length());
        server = server.substring(0, server.indexOf("/"));

        final FTPClient ftp;
        ThreadSafeOptions tso;
        synchronized (host2ftp) {
            if (!host2ftp.containsKey(server)) {
                ThreadSafeOptions ttt = new ThreadSafeOptions();
                ttt.setParam(0, new FTPClient());
                host2ftp.put(server, ttt);
            }
            tso = host2ftp.get(server);
            ftp = (FTPClient) tso.getParam(0, null);
        }
        status.setCurrentStatusValue(0);
        boolean res;

        try {
            boolean wait = false;

            BackgroundTaskHelper.lockAquire(server, 1);
            if (wait) {
                while (wait) {
                    status.setCurrentStatusText1("Waiting for shared FTP connection");
                    status.setCurrentStatusText2("Server: " + server);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                    }
                    synchronized (tso) {
                        wait = tso.getBval(1, false);
                    }
                }
            }
            status.setCurrentStatusValue(-1);
            status.setCurrentStatusText1(downloadURL);
            status.setCurrentStatusText2("FTP DOWNLOAD...");
            res = processDownload(status, downloadURL, targetFileName, lastStatus, thisRun, server, remote, ftp);
        } finally {
            BackgroundTaskHelper.lockRelease(server);
        }
        return res;
    }

    private static boolean processDownload(final BackgroundTaskStatusProviderSupportingExternalCallImpl status,
            String downloadURL, String targetFileName, ObjectRef lastStatus, final int thisRun, String server,
            String remote, final FTPClient ftp) {
        String username;
        String password;
        String local;
        username = "anonymous@" + server;
        password = "anonymous";
        local = targetFileName;

        final ObjectRef myoutputstream = new ObjectRef();

        ftp.addProtocolCommandListener(new ProtocolCommandListener() {
            public void protocolCommandSent(ProtocolCommandEvent arg0) {
                // System.out.print("out: " + arg0.getMessage());
                status.setCurrentStatusText1("Command: " + arg0.getMessage());
            }

            public void protocolReplyReceived(ProtocolCommandEvent arg0) {
                // System.out.print("in : " + arg0.getMessage());
                status.setCurrentStatusText2("Message: " + arg0.getMessage());
                if (myoutputstream.getObject() != null) {
                    String msg = arg0.getMessage();
                    if (msg.indexOf("Opening BINARY mode") >= 0) {
                        if (msg.indexOf("(") > 0) {
                            msg = msg.substring(msg.indexOf("(") + "(".length());
                            if (msg.indexOf(" ") > 0) {
                                msg = msg.substring(0, msg.indexOf(" "));
                                try {
                                    long max = Long.parseLong(msg);
                                    MyOutputStream os = (MyOutputStream) myoutputstream.getObject();
                                    os.setMaxBytes(max);
                                } catch (Exception e) {
                                    System.out.println(
                                            "Could not determine file length for detailed progress information");
                                }
                            }
                        }
                    }
                }
            }
        });

        System.out.println("FTP DOWNLOAD: " + downloadURL);

        try {
            if (ftp.isConnected()) {
                status.setCurrentStatusText2("Using open FTP connection");
                System.out.println("Reusing open FTP connection");
            } else {
                ftp.connect(server);
                int reply = ftp.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftp.disconnect();
                    status.setCurrentStatusText1("Can't connect to FTP server");
                    status.setCurrentStatusText2("ERROR");
                    return false;
                }
                if (!ftp.login("anonymous", "anonymous")) {
                    if (!ftp.login(username, password)) {
                        ftp.disconnect();
                        status.setCurrentStatusText1("Can't login to FTP server");
                        status.setCurrentStatusText2("ERROR");
                        return false;
                    }
                }
                status.setCurrentStatusText1("Set Binary Transfer Mode");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                status.setCurrentStatusText2("Activate Passive Transfer Mode");
                ftp.enterLocalPassiveMode();
            }
            status.setCurrentStatusText1("Start download...");
            status.setCurrentStatusText2("Please Wait.");

            // ftp.listFiles(pathname);

            OutputStream output = new MyOutputStream(lastStatus, status, new FileOutputStream(local));
            myoutputstream.setObject(output);
            ftp.setRemoteVerificationEnabled(false);
            long tA = System.currentTimeMillis();
            boolean result = ftp.retrieveFile(remote, output);
            output.close();
            long tB = System.currentTimeMillis();
            if (!result) {
                new File(local).delete();
                MainFrame.showMessage("Can't download " + downloadURL + ". File not available.", MessageType.INFO);
            } else {
                File f = new File(local);
                System.out.println("Download completed (" + f.getAbsolutePath() + ", " + (f.length() / 1024)
                        + " KB, " + (int) ((f.length() / 1024d / (tB - tA) * 1000d)) + " KB/s).");
            }
            BackgroundTaskHelper.executeLaterOnSwingTask(10000, new Runnable() {
                public void run() {
                    try {
                        synchronized (GUIhelper.class) {
                            if (runIdx == thisRun) {
                                System.out.println("Disconnect FTP connection");
                                ftp.disconnect();
                            }
                        }
                    } catch (Exception err) {
                        ErrorMsg.addErrorMessage(err);
                    }
                }
            });
            return result;
        } catch (Exception err) {
            System.out.println("ERROR: FTP DOWNLOAD ERROR: " + err.getMessage());
            if (ftp != null && ftp.isConnected()) {
                try {
                    System.out.println("Disconnect FTP connection (following error condition)");
                    ftp.disconnect();
                } catch (Exception err2) {
                    ErrorMsg.addErrorMessage(err2);
                }
            }
            return false;
        }
    }

    private static ArrayList<String> listFiles(final BackgroundTaskStatusProviderSupportingExternalCall status,
            String downloadURL, String server, String remotePath, final FTPClient ftp) {
        String username;
        String password;
        username = "anonymous@" + server;
        password = "anonymous";

        final ObjectRef myoutputstream = new ObjectRef();

        ftp.addProtocolCommandListener(new ProtocolCommandListener() {
            public void protocolCommandSent(ProtocolCommandEvent arg0) {
                status.setCurrentStatusText1("Command: " + arg0.getMessage());
            }

            public void protocolReplyReceived(ProtocolCommandEvent arg0) {
                status.setCurrentStatusText2("Message: " + arg0.getMessage());
                if (myoutputstream.getObject() != null) {
                    String msg = arg0.getMessage();
                    if (msg.indexOf("Opening BINARY mode") >= 0) {
                        if (msg.indexOf("(") > 0) {
                            msg = msg.substring(msg.indexOf("(") + "(".length());
                            if (msg.indexOf(" ") > 0) {
                                msg = msg.substring(0, msg.indexOf(" "));
                                try {
                                    long max = Long.parseLong(msg);
                                    MyOutputStream os = (MyOutputStream) myoutputstream.getObject();
                                    os.setMaxBytes(max);
                                } catch (Exception e) {
                                    System.out.println(
                                            "Could not determine file length for detailed progress information");
                                }
                            }
                        }
                    }
                }
            }
        });

        System.out.println("FTP LIST DIRECTORY: " + downloadURL);

        try {
            if (ftp.isConnected()) {
                status.setCurrentStatusText2("Using open FTP connection");
                System.out.println("Reusing open FTP connection");
            } else {
                ftp.connect(server);
                int reply = ftp.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftp.disconnect();
                    status.setCurrentStatusText1("Can't connect to FTP server");
                    status.setCurrentStatusText2("ERROR");
                    return new ArrayList<String>();
                }
                if (!ftp.login("anonymous", "anonymous")) {
                    if (!ftp.login(username, password)) {
                        ftp.disconnect();
                        status.setCurrentStatusText1("Can't login to FTP server");
                        status.setCurrentStatusText2("ERROR");
                        return new ArrayList<String>();
                    }
                }
                status.setCurrentStatusText1("Set Binary Transfer Mode");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                status.setCurrentStatusText2("Activate Passive Transfer Mode");
                ftp.enterLocalPassiveMode();
            }
            status.setCurrentStatusText1("Start download...");
            status.setCurrentStatusText2("Please Wait.");

            ftp.setRemoteVerificationEnabled(false);

            FTPFile[] res = ftp.listFiles(remotePath);

            ArrayList<String> result = new ArrayList<String>();

            for (FTPFile r : res) {
                result.add(r.getName());
            }

            return result;
        } catch (Exception err) {
            ErrorMsg.addErrorMessage(err);
            if (ftp != null && ftp.isConnected()) {
                try {
                    System.out.println("Disconnect FTP connection (following error condition)");
                    ftp.disconnect();
                } catch (Exception err2) {
                    ErrorMsg.addErrorMessage(err2);
                }
            }
            return new ArrayList<String>();
        }
    }
}

class MyDialog extends JDialog {
    private static final long serialVersionUID = 1L;

    private String title;
    private String[] buttons;
    private int returnValue;
    private JComponent mainView;
    private double border;

    public MyDialog(Frame instance, String title, String[] buttons, JComponent mainView, int border) {
        super(instance);
        this.title = title;
        this.buttons = buttons;
        this.mainView = mainView;
        this.border = 5;
        setReturnValue(-1);
        myInit();
    }

    private void myInit() {
        super.dialogInit();
        setTitle(title);

        double[][] size = { { border, TableLayoutConstants.PREFERRED, border }, // Columns
                { border, TableLayoutConstants.PREFERRED, border } }; // Rows
        setLayout(new TableLayout(size));

        JButton[] commandButtons = new JButton[buttons.length];
        ArrayList<JComponent> buttonArr = new ArrayList<JComponent>();
        for (int i = 0; i < buttons.length; i++) {
            JButton button = new JButton(buttons[i]);
            final int fi = i;
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                    returnValue = fi;
                    dispose();
                }
            });
            commandButtons[i] = button;
            buttonArr.add(button);
        }
        // final JScrollPane sp = new JScrollPane(mainView);
        // SwingUtilities.invokeLater(new Runnable() {
        // public void run() {
        // sp.getVerticalScrollBar().setValue(0);
        // }});
        add(TableLayout.getSplitVertical(mainView,
                TableLayout.getMultiSplit(buttonArr, TableLayoutConstants.PREFERRED, 5, 0, 5, 3),
                TableLayoutConstants.FILL, TableLayoutConstants.PREFERRED), "1,1");
        validate();

        setResizable(false);
        // setSize(getPreferredSize());
        setModal(true);
        getRootPane().setDefaultButton(commandButtons[0]);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        final String ESC_ACTION_KEY = "ESC_ACTION_KEY";
        getRootPane().getActionMap().put(ESC_ACTION_KEY, new AbstractAction() {
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                dispose();
            }
        });

        getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), ESC_ACTION_KEY);
        pack();
    }

    public void setReturnValue(int returnValue) {
        this.returnValue = returnValue;
    }

    public int getReturnValue() {
        return returnValue;
    }
}