// This is example code for the install4j API
// Please feel free to adapt it for your own purposes.

import com.install4j.api.*;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

// This custom screen allows the user to select a JDK that the
// installed application will be running with.
//
// Usually, install4j will select a JRE based on the configured
// version requirements. However, if you have more specific
// requirements, such as a JDK, you can use the JVMSelector class
// in the API to get information on all installed JREs and set the
// preferred JRE for the installed application.
public class SelectJdkScreen extends CustomScreen {

    // the list where the JDKs are displayed
    private JList jdkList;

    public SelectJdkScreen() {

        // in the following code, the custom screen is populated
        // with controls

        jdkList = new JList();

        setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = GridBagConstraints.RELATIVE;
        gc.anchor = GridBagConstraints.WEST;

        add(new JLabel("Available JDKs:"), gc);

        gc.fill = GridBagConstraints.BOTH;
        gc.weightx = gc.weighty = 1;

        add(new JScrollPane(jdkList), gc);

    }

    // has to be implemented.
    public String getTitle() {
        return "Which JDK should the application be running with?";
    }

    // has to be implemented.
    public String getSubTitle() {
        return "Please select one of the installed JDKs on your computer.";
    }

    // has to be implemented. Since the list should occupy all vertical space, we return true.
    public boolean isFillVertical() {
        return true;
    }

    // has to be implemented. Since the list should occupy all horizontal space, we return true.
    public boolean isFillHorizontal() {
        return true;
    }

    // invoked by the framework when the next button is clicked
    public boolean next() {
        // Show warning message if no JDK is selected
        if (jdkList.getSelectedIndex() < 0) {
            Util.showMessage("Please select a JDK.", JOptionPane.WARNING_MESSAGE);
            // and stay on the current screen
            return false;
        }

        // retrieve selected JVMLocation object from the list
        JVMSelector.JVMLocation jdkLocation = (JVMSelector.JVMLocation)jdkList.getSelectedValue();

        // Now we set the preferred JVM for the application.
        JVMSelector.setPreferredJVM(jdkLocation.getJavaHome().getPath());

        // advance to the next screen
        return true;
    }

    public void activated() {

        // Only search for new JDKs if the
        if (jdkList.getModel().getSize() == 0) {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            // This operation can take some time on Unix platforms,
            // so we set a wait cursor around it
            JVMSelector.JVMLocation[] jvmLocations = JVMSelector.getJVMLocations();
            setCursor(Cursor.getDefaultCursor());

            // We only want to display JDKs
            JVMSelector.JVMLocation[] jdkLocations = filterJDKLocations(jvmLocations);

            // The list is filled with the jvmLocations. The JVMSelector.JVMLocation
            // object has a suitable toString() method.
            jdkList.setListData(jdkLocations);
        }

    }

    // helper method that filters the JDKs from an array with JVMLocations
    private JVMSelector.JVMLocation[] filterJDKLocations(JVMSelector.JVMLocation[] jvmLocations) {
        ArrayList jdkLocations = new ArrayList();
        for (int i = 0; i < jvmLocations.length; i++) {
            JVMSelector.JVMLocation jvmLocation = jvmLocations[i];
            if (jvmLocation.isJDK()) {
                jdkLocations.add(jvmLocation);
            }
        }
        return (JVMSelector.JVMLocation[])jdkLocations.toArray(new JVMSelector.JVMLocation[jdkLocations.size()]);
    }
}
