content: package org.netbeans.modules.python.options;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import javax.swing.DefaultListModel;
  import javax.swing.JFileChooser;
  import javax.swing.event.DocumentEvent;
  import javax.swing.event.DocumentListener;
  import javax.swing.event.TableModelEvent;
  import javax.swing.table.DefaultTableModel;
  import org.javatuples.Quartet;
  import org.json.JSONObject;
  import org.netbeans.modules.python.PythonUtility;
  import org.netbeans.modules.python.projectsample.PythonPoetryPanelVisual;
  import org.netbeans.modules.python.projectsample.PythonProjectPanelVisual;
  import org.openide.util.Exceptions;
  import org.openide.util.NbPreferences;
  import org.openide.util.RequestProcessor;
  
  final class PythonPlatformPanel extends javax.swing.JPanel {
  
      private static final long serialVersionUID = 1L;
  
      private final PythonPlatformOptionsPanelController controller;
  
      RequestProcessor RP = new RequestProcessor(this.getClass().getName(), 1);
  
      PythonPlatformPanel(PythonPlatformOptionsPanelController controller) {
          this.controller = controller;
          initComponents();
          platformName.getDocument().addDocumentListener(new DocumentListener() {
              @Override
              public void insertUpdate(DocumentEvent de) {
                  controller.changed();
              }
  
              @Override
              public void removeUpdate(DocumentEvent de) {
                  controller.changed();
              }
  
              @Override
              public void changedUpdate(DocumentEvent de) {
                  controller.changed();
              }
          });
          platformList.setCellRenderer(new PythonPlatformListRenderer());
          userEnvsTable.getModel().addTableModelListener((TableModelEvent tme) -> {
              controller.changed();
          });
          //  listen to changes in form fields and call controller.changed()
      }
  
      /**
       * 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.
       */
      // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
      private void initComponents() {
  
          platformScrollPane = new javax.swing.JScrollPane();
          platformList = new javax.swing.JList();
          platformLabel = new javax.swing.JLabel();
          newPlatform = new javax.swing.JButton();
          removePlatform = new javax.swing.JButton();
          autoDetectPlatform = new javax.swing.JButton();
          infoTabbedPane = new javax.swing.JTabbedPane();
          mainPanel = new javax.swing.JPanel();
          platformNameLabel = new javax.swing.JLabel();
          platformName = new javax.swing.JTextField();
          platformCommandLabel = new javax.swing.JLabel();
          command = new javax.swing.JTextField();
          sysPathPanel = new javax.swing.JPanel();
          sysPathLabel = new javax.swing.JLabel();
          sysPathScrollPane = new javax.swing.JScrollPane();
          sysPathList = new javax.swing.JList<>();
          envsPanel = new javax.swing.JPanel();
          envsSplitPane = new javax.swing.JSplitPane();
          userEnvsPanel = new javax.swing.JPanel();
          userEnvsScrollPane = new javax.swing.JScrollPane();
          userEnvsTable = new javax.swing.JTable();
          sysCheckBox = new javax.swing.JCheckBox();
          addVariableButton = new javax.swing.JButton();
          deleteButton = new javax.swing.JButton();
          sysEnvsPanel = new javax.swing.JPanel();
          sysEnvsScrollPane = new javax.swing.JScrollPane();
          sysEnvsTable = new javax.swing.JTable();
          makePlatformDefault = new javax.swing.JButton();
  
          platformList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
          platformList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
              public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                  platformListValueChanged(evt);
              }
          });
          platformScrollPane.setViewportView(platformList);
  
          org.openide.awt.Mnemonics.setLocalizedText(platformLabel, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.platformLabel.text")); // NOI18N
  
          org.openide.awt.Mnemonics.setLocalizedText(newPlatform, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.newPlatform.text")); // NOI18N
          newPlatform.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  newPlatformActionPerformed(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(removePlatform, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.removePlatform.text")); // NOI18N
          removePlatform.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  removePlatformActionPerformed(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(autoDetectPlatform, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.autoDetectPlatform.text")); // NOI18N
          autoDetectPlatform.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  autoDetectPlatformActionPerformed(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(platformNameLabel, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.platformNameLabel.text")); // NOI18N
  
          platformName.setText(org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.platformName.text")); // NOI18N
          platformName.addFocusListener(new java.awt.event.FocusAdapter() {
              public void focusLost(java.awt.event.FocusEvent evt) {
                  platformNameFocusLost(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(platformCommandLabel, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.platformCommandLabel.text")); // NOI18N
  
          command.setEditable(false);
          command.setText(org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.command.text")); // NOI18N
  
          javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
          mainPanel.setLayout(mainPanelLayout);
          mainPanelLayout.setHorizontalGroup(
              mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(mainPanelLayout.createSequentialGroup()
                  .addGap(44, 44, 44)
                  .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                      .addComponent(platformCommandLabel)
                      .addComponent(platformNameLabel))
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                      .addComponent(platformName, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE)
                      .addComponent(command))
                  .addGap(24, 24, 24))
          );
          mainPanelLayout.setVerticalGroup(
              mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(mainPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(platformNameLabel)
                      .addComponent(platformName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(platformCommandLabel)
                      .addComponent(command, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addContainerGap(400, Short.MAX_VALUE))
          );
  
          infoTabbedPane.addTab(org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.mainPanel.TabConstraints.tabTitle"), mainPanel); // NOI18N
  
          org.openide.awt.Mnemonics.setLocalizedText(sysPathLabel, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.sysPathLabel.text")); // NOI18N
  
          sysPathScrollPane.setViewportView(sysPathList);
  
          javax.swing.GroupLayout sysPathPanelLayout = new javax.swing.GroupLayout(sysPathPanel);
          sysPathPanel.setLayout(sysPathPanelLayout);
          sysPathPanelLayout.setHorizontalGroup(
              sysPathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(sysPathPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addGroup(sysPathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                      .addComponent(sysPathScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE)
                      .addGroup(sysPathPanelLayout.createSequentialGroup()
                          .addComponent(sysPathLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 172, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addGap(0, 0, Short.MAX_VALUE)))
                  .addContainerGap())
          );
          sysPathPanelLayout.setVerticalGroup(
              sysPathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(sysPathPanelLayout.createSequentialGroup()
                  .addGap(0, 0, 0)
                  .addComponent(sysPathLabel)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addComponent(sysPathScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 431, Short.MAX_VALUE)
                  .addContainerGap())
          );
  
          infoTabbedPane.addTab(org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.sysPathPanel.TabConstraints.tabTitle"), sysPathPanel); // NOI18N
  
          envsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
  
          userEnvsTable.setModel(new javax.swing.table.DefaultTableModel(
              new Object [][] {
  
              },
              new String [] {
                  "Name", "Value"
              }
          ));
          userEnvsScrollPane.setViewportView(userEnvsTable);
  
          sysCheckBox.setSelected(true);
          org.openide.awt.Mnemonics.setLocalizedText(sysCheckBox, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.sysCheckBox.text")); // NOI18N
          sysCheckBox.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  sysCheckBoxActionPerformed(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(addVariableButton, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.addVariableButton.text")); // NOI18N
          addVariableButton.setMaximumSize(new java.awt.Dimension(100, 29));
          addVariableButton.setMinimumSize(new java.awt.Dimension(100, 29));
          addVariableButton.setPreferredSize(new java.awt.Dimension(100, 29));
          addVariableButton.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  addVariableButtonActionPerformed(evt);
              }
          });
  
          org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.deleteButton.text")); // NOI18N
          deleteButton.setMaximumSize(new java.awt.Dimension(100, 29));
          deleteButton.setMinimumSize(new java.awt.Dimension(100, 29));
          deleteButton.setPreferredSize(new java.awt.Dimension(100, 29));
          deleteButton.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  deleteButtonActionPerformed(evt);
              }
          });
  
          javax.swing.GroupLayout userEnvsPanelLayout = new javax.swing.GroupLayout(userEnvsPanel);
          userEnvsPanel.setLayout(userEnvsPanelLayout);
          userEnvsPanelLayout.setHorizontalGroup(
              userEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(userEnvsPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addGroup(userEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                      .addComponent(userEnvsScrollPane)
                      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, userEnvsPanelLayout.createSequentialGroup()
                          .addComponent(sysCheckBox)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 136, Short.MAX_VALUE)
                          .addComponent(addVariableButton, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                          .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                  .addContainerGap())
          );
          userEnvsPanelLayout.setVerticalGroup(
              userEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(userEnvsPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addComponent(userEnvsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 215, Short.MAX_VALUE)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addGroup(userEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(sysCheckBox)
                      .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                      .addComponent(addVariableButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addContainerGap())
          );
  
          envsSplitPane.setLeftComponent(userEnvsPanel);
  
          sysEnvsTable.setModel(new javax.swing.table.DefaultTableModel(
              new Object [][] {
  
              },
              new String [] {
                  "Name", "Value"
              }
          ) {
              boolean[] canEdit = new boolean [] {
                  false, false
              };
  
              public boolean isCellEditable(int rowIndex, int columnIndex) {
                  return canEdit [columnIndex];
              }
          });
          sysEnvsScrollPane.setViewportView(sysEnvsTable);
  
          javax.swing.GroupLayout sysEnvsPanelLayout = new javax.swing.GroupLayout(sysEnvsPanel);
          sysEnvsPanel.setLayout(sysEnvsPanelLayout);
          sysEnvsPanelLayout.setHorizontalGroup(
              sysEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(sysEnvsPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addComponent(sysEnvsScrollPane)
                  .addContainerGap())
          );
          sysEnvsPanelLayout.setVerticalGroup(
              sysEnvsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(sysEnvsPanelLayout.createSequentialGroup()
                  .addContainerGap()
                  .addComponent(sysEnvsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE)
                  .addContainerGap())
          );
  
          envsSplitPane.setRightComponent(sysEnvsPanel);
  
          javax.swing.GroupLayout envsPanelLayout = new javax.swing.GroupLayout(envsPanel);
          envsPanel.setLayout(envsPanelLayout);
          envsPanelLayout.setHorizontalGroup(
              envsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGap(0, 660, Short.MAX_VALUE)
              .addGroup(envsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(envsPanelLayout.createSequentialGroup()
                      .addGap(6, 6, 6)
                      .addComponent(envsSplitPane)
                      .addGap(6, 6, 6)))
          );
          envsPanelLayout.setVerticalGroup(
              envsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGap(0, 462, Short.MAX_VALUE)
              .addGroup(envsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(envsPanelLayout.createSequentialGroup()
                      .addGap(7, 7, 7)
                      .addComponent(envsSplitPane)
                      .addGap(8, 8, 8)))
          );
  
          infoTabbedPane.addTab(org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.envsPanel.TabConstraints.tabTitle"), envsPanel); // NOI18N
  
          org.openide.awt.Mnemonics.setLocalizedText(makePlatformDefault, org.openide.util.NbBundle.getMessage(PythonPlatformPanel.class, "PythonPlatformPanel.makePlatformDefault.text")); // NOI18N
          makePlatformDefault.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  makePlatformDefaultActionPerformed(evt);
              }
          });
  
          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, false)
                      .addComponent(platformLabel)
                      .addComponent(platformScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                      .addComponent(autoDetectPlatform, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                      .addComponent(makePlatformDefault, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                      .addGroup(layout.createSequentialGroup()
                          .addComponent(newPlatform, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                          .addComponent(removePlatform, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addComponent(infoTabbedPane)
                  .addContainerGap())
          );
          layout.setVerticalGroup(
              layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(layout.createSequentialGroup()
                  .addContainerGap()
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                      .addComponent(infoTabbedPane)
                      .addGroup(layout.createSequentialGroup()
                          .addComponent(platformLabel)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                          .addComponent(platformScrollPane)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                          .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                              .addComponent(removePlatform)
                              .addComponent(newPlatform))
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                          .addComponent(autoDetectPlatform)
                          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                          .addComponent(makePlatformDefault))))
          );
      }// </editor-fold>//GEN-END:initComponents
  
      private void platformListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_platformListValueChanged
          if (platformList.getSelectedIndex() != -1) {
              Quartet<String, String, String, Boolean> py = (Quartet) platformList.getSelectedValue();
              platformName.setText(py.getValue0());
              command.setText(py.getValue1());
              setSysPaths(py.getValue1());
  
          }
      }//GEN-LAST:event_platformListValueChanged
  
      private void newPlatformActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newPlatformActionPerformed
          final JFileChooser fc = new JFileChooser();
          fc.setFileHidingEnabled(false);
          fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
          if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
              PythonPlatformManager.insert(fc.getSelectedFile().getAbsolutePath());
              reloadDetection();
              controller.changed();
          }
  
      }//GEN-LAST:event_newPlatformActionPerformed
  
      private void removePlatformActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removePlatformActionPerformed
          int selectedIndex = platformList.getSelectedIndex();
          if (selectedIndex != -1) {
              Quartet<String, String, String, Boolean> py = (Quartet) platformList.getSelectedValue();
              DefaultListModel model = (DefaultListModel) platformList.getModel();
              model.remove(selectedIndex);
              PythonPlatformManager.delete(py.getValue1());
              reloadDetection();
              controller.changed();
          }
      }//GEN-LAST:event_removePlatformActionPerformed
  
      private void autoDetectPlatformActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoDetectPlatformActionPerformed
          PythonPlatformManager.refresh();
          reloadDetection();
      }//GEN-LAST:event_autoDetectPlatformActionPerformed
  
      int defaultIndex = 0;
  
      private void reloadDetection() {
          List<Quartet<String, String, String, Boolean>> pythonExes = PythonPlatformManager.getPythonExes();
          if (!pythonExes.isEmpty()) {
              DefaultListModel<Quartet<String, String, String, Boolean>> listModel = new DefaultListModel<>();
              for (Quartet<String, String, String, Boolean> pythonExe : pythonExes) {
                  listModel.addElement(Quartet.with(
                          pythonExe.getValue0(),
                          pythonExe.getValue1(),
                          pythonExe.getValue2(),
                          pythonExe.getValue3()
                  ));
                  if (pythonExe.getValue3()) {
                      defaultIndex = pythonExes.indexOf(pythonExe);
                  }
              }
              platformList.setModel(listModel);
              controller.changed();
          }
      }
  
      private void makePlatformDefaultActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_makePlatformDefaultActionPerformed
          if (platformList.getSelectedIndex() != -1) {
              Quartet<String, String, String, Boolean> py = (Quartet) platformList.getSelectedValue();
              PythonPlatformManager.setSelected(py.getValue1(), "true");
              reloadDetection();
              controller.changed();
          }
      }//GEN-LAST:event_makePlatformDefaultActionPerformed
  
      private void addVariableButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addVariableButtonActionPerformed
          ((DefaultTableModel) userEnvsTable.getModel()).addRow(new Object[]{"", ""});
          controller.changed();
      }//GEN-LAST:event_addVariableButtonActionPerformed
  
      private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
          if (userEnvsTable.getSelectedRow() != -1) {
              ((DefaultTableModel) userEnvsTable.getModel()).removeRow(userEnvsTable.getSelectedRow());
              controller.changed();
          }
      }//GEN-LAST:event_deleteButtonActionPerformed
  
      private void sysCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sysCheckBoxActionPerformed
          controller.changed();
      }//GEN-LAST:event_sysCheckBoxActionPerformed
  
      private void platformNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_platformNameFocusLost
          if (!controller.isChanged()) {
              return;
          }
  
          if (platformList.getSelectedIndex() != -1) {
              Quartet<String, String, String, Boolean> py = (Quartet) platformList.getSelectedValue();
              PythonPlatformManager.setName(py.getValue1(), platformName.getText());
              reloadDetection();
          }
      }//GEN-LAST:event_platformNameFocusLost
  
      void load() {
          RP.post(() -> {
              PythonPlatformManager.refresh();
              reloadDetection();
  
              DefaultTableModel model1 = (DefaultTableModel) sysEnvsTable.getModel();
              model1.setRowCount(0);
              DefaultTableModel model2 = (DefaultTableModel) userEnvsTable.getModel();
              model2.setRowCount(0);
  
              Map<String, String> envs = PythonUtility.getEnvs();
              envs.forEach((key, value) -> {
                  ((DefaultTableModel) sysEnvsTable.getModel()).addRow(new Object[]{key, value});
              });
  
              try {
                  PythonUtility.getUserEnvs().forEach((key, value) -> {
                      ((DefaultTableModel) userEnvsTable.getModel()).addRow(new Object[]{key, value});
                  });
              } catch (IOException ex) {
                  Exceptions.printStackTrace(ex);
              }
  
              try {
                  if (!PythonPlatformManager.getDefault().isEmpty()) {
                      platformList.setSelectedIndex(defaultIndex);
                  }
              } catch (IOException ex) {
                  Exceptions.printStackTrace(ex);
              }
          });
      }
  
      void store() {
          if (controller.isChanged()) {
              NbPreferences.root().putBoolean("sysEnv", sysCheckBox.isSelected());
              HashMap<String, String> hashMap = new HashMap<>();
              for (int i = 0; i < userEnvsTable.getRowCount(); i++) {
                  Object key = userEnvsTable.getValueAt(i, 0);
                  Object value = userEnvsTable.getValueAt(i, 1);
                  hashMap.put(key.toString().trim(), value.toString().trim());
  
              }
              PythonUtility.insertUserEnvs(new JSONObject(hashMap).toString());
  
          }
          if (PythonProjectPanelVisual.pythonTextField != null) {
              try {
                  PythonProjectPanelVisual.pythonTextField.setText(PythonUtility.getPlatformPythonExe());
              } catch (IOException ex) {
                  Exceptions.printStackTrace(ex);
              }
  
          }
          if (PythonPoetryPanelVisual.pythonTextField != null) {
              try {
                  PythonPoetryPanelVisual.pythonTextField.setText(PythonUtility.getPlatformPythonExe());
              } catch (IOException ex) {
                  Exceptions.printStackTrace(ex);
              }
  
          }
      }
  
      boolean valid() {
          return true;
      }
  
      // Variables declaration - do not modify//GEN-BEGIN:variables
      private javax.swing.JButton addVariableButton;
      private javax.swing.JButton autoDetectPlatform;
      private javax.swing.JTextField command;
      private javax.swing.JButton deleteButton;
      private javax.swing.JPanel envsPanel;
      private javax.swing.JSplitPane envsSplitPane;
      private javax.swing.JTabbedPane infoTabbedPane;
      private javax.swing.JPanel mainPanel;
      private javax.swing.JButton makePlatformDefault;
      private javax.swing.JButton newPlatform;
      private javax.swing.JLabel platformCommandLabel;
      private javax.swing.JLabel platformLabel;
      private javax.swing.JList platformList;
      private javax.swing.JTextField platformName;
      private javax.swing.JLabel platformNameLabel;
      private javax.swing.JScrollPane platformScrollPane;
      private javax.swing.JButton removePlatform;
      private javax.swing.JCheckBox sysCheckBox;
      private javax.swing.JPanel sysEnvsPanel;
      private javax.swing.JScrollPane sysEnvsScrollPane;
      private javax.swing.JTable sysEnvsTable;
      private javax.swing.JLabel sysPathLabel;
      private javax.swing.JList<String> sysPathList;
      private javax.swing.JPanel sysPathPanel;
      private javax.swing.JScrollPane sysPathScrollPane;
      private javax.swing.JPanel userEnvsPanel;
      private javax.swing.JScrollPane userEnvsScrollPane;
      private javax.swing.JTable userEnvsTable;
      // End of variables declaration//GEN-END:variables
  
      private void setSysPaths(String value1) {
          try {
              DefaultListModel<String> listModel = new DefaultListModel<>();
              PythonUtility.getCommandOutput(new String[]{value1, "-c",
                  "import sys; print('\\n'.join(sys.path))"}, null)
                      .lines().forEach(string -> {
                          listModel.addElement(string);
                      });
              sysPathList.setModel(listModel);
          } catch (IOException ex) {
              Exceptions.printStackTrace(ex);
          }
      }
  
  }
  