/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.netbeans.modules.gradle;

import org.netbeans.modules.gradle.spi.GradleSettings;
import org.openide.util.NbBundle.Messages;

/**
 *
 * @author lkishalmi
 */
@Messages({
        "# {0} - Gradle Version",
        "MSG_Install=<html>It seems the required Gradle Version <b>{0}</b> " +
        "is not installed in the system. Would you like to install it?"
})
public class GradleInstallPanel extends javax.swing.JPanel {

    /**
     * Creates new form GradleInstallPanel
     */
    public GradleInstallPanel(String version) {
        initComponents();
        lbInfo.setText(Bundle.MSG_Install(version));
        cbSilentInstall.setSelected(GradleSettings.getDefault().isSilentInstall());
    }

    public boolean isSilentInstall() {
        return cbSilentInstall.isSelected();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cbSilentInstall = new javax.swing.JCheckBox();
        lbInfo = new javax.swing.JLabel();

        org.openide.awt.Mnemonics.setLocalizedText(cbSilentInstall, org.openide.util.NbBundle.getMessage(GradleInstallPanel.class, "GradleInstallPanel.cbSilentInstall.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(lbInfo, org.openide.util.NbBundle.getMessage(GradleInstallPanel.class, "GradleInstallPanel.lbInfo.text")); // NOI18N
        lbInfo.setVerticalAlignment(javax.swing.SwingConstants.TOP);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lbInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 348, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(cbSilentInstall)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lbInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 77, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cbSilentInstall)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox cbSilentInstall;
    private javax.swing.JLabel lbInfo;
    // End of variables declaration//GEN-END:variables
}
