Skip to content
Snippets Groups Projects
BatchPanel.java 27.2 KiB
Newer Older
package cz.fidentis.analyst.batch;

import cz.fidentis.analyst.Logger;
import cz.fidentis.analyst.core.ControlPanel;
import cz.fidentis.analyst.project.ProjectTopComp;
import cz.fidentis.analyst.face.HumanFace;
import cz.fidentis.analyst.face.HumanFaceFactory;
import cz.fidentis.analyst.mesh.io.MeshObjExporter;
import static cz.fidentis.analyst.registration.RegistrationPanel.getStaticIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.openide.filesystems.FileChooserBuilder;

/**
 * A control panel for bath (N:N) processing.
 * 
 * @author Radek Oslejsek
 */
public class BatchPanel extends ControlPanel {
    
    public static final String SIMILARITY_COMPLETE_HD = "Two-way HD of all pairs (very slow)";
    public static final String SIMILARITY_APPROX_HD = "Approximate HD using selected face (fast)";
    
    public static final String ACTION_COMMAND_COMPUTE_ICP = "Compute ICP and average face";
    public static final String ACTION_COMMAND_COMPUTE_SIMILARITY = "Compute similarity";
    public static final String ACTION_COMMAND_SHOW_SELECTED_FACE = "Show selected face";
    public static final String ACTION_COMMAND_EXPORT_SIMILARITY = "Export similarity";
    
    /*
     * Mandatory design elements
     */
    public static final String ICON = "registration28x28.png";
    public static final String NAME = "Batch Processing";
    
    private final List<Path> paths = new ArrayList<>();
    private final HumanFaceFactory factory = new HumanFaceFactory();
    private boolean haveAvgFace = false;
    
    /**
     * Constructor.
     * @param action Action listener
     * @param faces Paths to faces
     * @throws IllegalArgumentException if the {@code faces} argument is empty or missing
     */
    public BatchPanel(ActionListener action, List<Path> faces) {
        this.setName(NAME);
        
        initComponents();
        
        this.paths.addAll(faces);
        paths.stream().forEach(f -> {
            String name = f.toString();
            name = name.substring(name.lastIndexOf(File.separatorChar) + 1, name.length());
            jComboBox1.addItem(name);
        }); // Action event is triggered automatically by the jComboBox1 with the first item set as selected
        
        jButton1.addActionListener(createListener(action, ACTION_COMMAND_COMPUTE_ICP));
        
        spinSlider1.initInteger(1000, 0, 5000, 1); // downsampling strength
        
        jComboBox2.addItem(SIMILARITY_APPROX_HD);
        jComboBox2.addItem(SIMILARITY_COMPLETE_HD);
        
        jButton4.addActionListener(createListener(action, ACTION_COMMAND_COMPUTE_SIMILARITY));
        
        jButton5.addActionListener((ActionEvent e) -> { // [Export AVG face]
            exportAvgFace();
        });
        
        jButton6.addActionListener(createListener(action, ACTION_COMMAND_EXPORT_SIMILARITY)); // [Export results]
        
        jComboBox1.addActionListener(createListener(action, ACTION_COMMAND_SHOW_SELECTED_FACE));
        
        jButtonInfo1.addActionListener((ActionEvent e) -> { 
            showSimilarityInfo();
        });
        
        jButtonInfo2.addActionListener((ActionEvent e) -> { 
            showDatasetInfo();
        });
    }
    
    @Override
    public ImageIcon getIcon() {
        return getStaticIcon();
    }
    
    public boolean getHdAutoCrop() {
        return jCheckBox5.isSelected();
    }
    
     * Sets the similarity export button
     * 
     * @param on set on or off
     */
    public void enableSimilatiryExport(boolean on) {
        jButton6.setEnabled(on);
    }
    
    /**
     * Returns index of a face that is selected or -1
     * @return index of a face that is selected or -1
     */
    public int getSelectedFaceIndex() {
        return (jComboBox1.getItemCount() == 0) ? -1 : jComboBox1.getSelectedIndex();
    }

    /**
     * Returns the face select in the combo box
     * @return the face select in the combo box
     */
    public HumanFace getSelectedFace() {
        if (jComboBox1.getItemCount() == 0) {
            return null;
        }
        
        //Logger.print("AAA " + paths.get(jComboBox1.getSelectedIndex()).toString());
        String id = factory.loadFace(paths.get(jComboBox1.getSelectedIndex()).toFile());
        return factory.getFace(id);
    }
    
    /**
     * Method logic:
     * <ul>
     * <li>If {@code face} is not {@code null} and the previous AVG face exists, 
     * then the AVG face is replaced and selected.</li>
     * <li>If {@code face} is not {@code null} and no previous AVG face exists, 
     * then the AVG face is added and selected.</li>
     * <li>If {@code face} is {@code null} and the previous AVG face exists, 
     * then the previous AVG face is preserved and selected.</li>
     * <li>If {@code face} is {@code null} and no previous AVG face exists, 
     * then nothing happens.</li>
     * </ul>
     *
     * @param face new AVG face
    public void addAndSelectAvgFace(HumanFace face) {
        //this.avgFace = face;
        
        // Copy existing ites of the combobox and clear it
        List<String> items = new ArrayList<>();
        for (int i = 0; i < jComboBox1.getItemCount(); i++) {
            items.add(jComboBox1.getItemAt(i));
        }
        jComboBox1.removeAllItems();
        
        // the logic:
        if (face != null && haveAvgFace) {
            paths.set(0, new File(face.getPath()).toPath()); // replace path
            // do nothing with the combobox
        } else if (face != null && !haveAvgFace) {
            paths.add(0, new File(face.getPath()).toPath());
            items.add(0, "Average face");
        } else if (face == null && haveAvgFace) {
        } else {
            // do nothing at all
        }
        
        // Copy items back to the combobox.
        // Action event is triggered automatically by the jComboBox1 with the first item set as selected
        items.stream().forEach(i -> jComboBox1.addItem(i));
        
        haveAvgFace = (face != null || haveAvgFace);
        jButton5.setEnabled(haveAvgFace);
    }
    
    /**
     * Returns paths to faces to be processed
     * @return paths to faces to be processed
     */
    public List<Path> getFacePaths() {
        return Collections.unmodifiableList(paths);
    }
    
    /**
     * Returns human face factory
     * 
     * @return human face factory
     */
    public HumanFaceFactory getHumanFaceFactory() {
        return this.factory;
    }
    
    /**
     * Returns the number of desired points, 0 for no downsampling
     * @return the number of desired points, 0 for no downsampling
     */
    public int getIcpUndersampling() {
        return (int) spinSlider1.getValue();
    }
    
    /**
     * Determines whether to compute average face.
     * @return if {@code true}, then average face will be computed
     */
    public boolean computeAvgFace() {
        return this.jCheckBox1.isSelected();
    }
    
    /**
     * Determines whether to scale during ICP registration.
     * @return if {@code true}, then ICP scales
     */
    public boolean scaleIcp() {
        return jCheckBox4.isSelected();
    }
    
    /**
     * Determines whether to show ICP transformation in the 3D scene
     * @return if {@code true}, then ICP transformations are shown in the 3D scene
     */
    public boolean showIcpPreview() {
        return this.jCheckBox3.isSelected();
    }
    
    /**
     * Determines whether to compute ICP transformations.
     * @return if {@code true}, then ICP transformations will be computed
     */
    public boolean computeICP() {
        return this.jCheckBox2.isSelected();
    }
    
    /**
     * Returns selected similarity strategy
     * @return selected similarity strategy
     */
    public String getSimilarityStrategy() {
        return jComboBox2.getSelectedItem().toString();
    }
    
    private void showSimilarityInfo() {
        JOptionPane.showMessageDialog(
                this, 
                "<html>"
                        + "<strong>" + SIMILARITY_APPROX_HD + "</strong>: <br/>"
                        + "First, a relative Hausdorff distance is computed between all faces and the selected face T.<br/>"
                        + "Then, the distance of each pair A,B is estimated as the difference between A,T and B,T.<br/>"
                        + "<br/>"
                        + "<strong>" + SIMILARITY_COMPLETE_HD + "</strong>: <br/>"
                        + "Hausdorff distance is computed for all paris in both directions.<br/>"
                        + "<br/>"
                        + "<strong>HD auto-crop</strong>: <br/>"
                        + "If selected, then only overlapping parts of faces are included<br/>"
                        + "in the calculation of Hausdorff distance.<br/>"
                        + "<br/>"
                        + "</html>",
                "Distance computation strategies",
                JOptionPane.INFORMATION_MESSAGE
        );
    }
    
    private void showDatasetInfo() {
        JOptionPane.showMessageDialog(
                this, 
                "<html>"
                        + "In the <strong>Registration</strong> step, the selected face is used<br>"
                        + "as an initial face for the computation of average face.<br/>"
                        + "Newly computed average face is automatically added to the dataset and selected.<br/>"
                        + "<br/>"
                        + "In the <strong>Similarity computation</strong> step, the selected face is used<br/>"
                        + "as a template (intermediate) face through which the mutual distances are computed.<br/>"                        
                        + "<br/>"
                        + "Selected face is shown in the scene.<br/>"
                        + "<br/>"
                        + "</html>",
                "Distance computation strategies",
                JOptionPane.INFORMATION_MESSAGE
        );
    }

    private void exportAvgFace() {
        if (!haveAvgFace) {
            return;
        }
        
        File file = new FileChooserBuilder(ProjectTopComp.class)
                .setTitle("Specify a file to save")
                .setDefaultWorkingDirectory(new File(System.getProperty("user.home")))
                .setFileFilter(new FileNameExtensionFilter("obj files (*.obj)", "obj"))
                .showSaveDialog();
        
        if (file != null) {
            try {
                String id = factory.loadFace(paths.get(0).toFile()); // first face is average
                new MeshObjExporter(factory.getFace(id).getMeshModel()).exportModelToObj(file);
            } catch (IOException ex) {
                Logger.print(ex.toString());
            }
        }
    }    

    /**
     * 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() {

        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        jCheckBox1 = new javax.swing.JCheckBox();
        jCheckBox2 = new javax.swing.JCheckBox();
        jCheckBox3 = new javax.swing.JCheckBox();
        jCheckBox4 = new javax.swing.JCheckBox();
        jButton5 = new javax.swing.JButton();
        spinSlider1 = new cz.fidentis.analyst.core.SpinSlider();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jComboBox1 = new javax.swing.JComboBox<>();
        jButtonInfo2 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jComboBox2 = new javax.swing.JComboBox<>();
        jButton4 = new javax.swing.JButton();
        jButtonInfo1 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        jCheckBox5 = new javax.swing.JCheckBox();

        setPreferredSize(new java.awt.Dimension(600, 600));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jPanel1.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jButton1.text")); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

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

        jCheckBox1.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(jCheckBox1, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jCheckBox1.text_1")); // NOI18N
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        jCheckBox2.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(jCheckBox2, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jCheckBox2.text")); // NOI18N
        jCheckBox2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox2ActionPerformed(evt);
            }
        });
        jCheckBox3.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(jCheckBox3, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jCheckBox3.text")); // NOI18N

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

        org.openide.awt.Mnemonics.setLocalizedText(jButton5, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jButton5.text")); // NOI18N
        jButton5.setEnabled(false);
        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jCheckBox3)
                    .addComponent(jCheckBox1)
                    .addComponent(jCheckBox2)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton5))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(spinSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jCheckBox4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(spinSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(25, 25, 25)
                        .addComponent(jLabel2)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 14, Short.MAX_VALUE)
                .addComponent(jCheckBox4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox3)
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton5))
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jPanel2.border.title_1"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N

        jLabel1.setFont(new java.awt.Font("Ubuntu", 1, 15)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jLabel1.text")); // NOI18N

        jButtonInfo2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/info.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jButtonInfo2, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jButtonInfo2.text")); // NOI18N
        jButtonInfo2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jButtonInfo2.setBorderPainted(false);
        jButtonInfo2.setFocusPainted(false);
        jButtonInfo2.setFocusable(false);
        jButtonInfo2.setRequestFocusEnabled(false);
        jButtonInfo2.setRolloverEnabled(false);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jButtonInfo2)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButtonInfo2)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel1)
                        .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(23, Short.MAX_VALUE))
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jPanel3.border.title_1"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N

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

        jButtonInfo1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/info.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jButtonInfo1, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jButtonInfo1.text")); // NOI18N
        jButtonInfo1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jButtonInfo1.setBorderPainted(false);
        jButtonInfo1.setFocusPainted(false);
        jButtonInfo1.setFocusable(false);
        jButtonInfo1.setRequestFocusEnabled(false);
        jButtonInfo1.setRolloverEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(jButton6, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jButton6.text")); // NOI18N
        jButton6.setEnabled(false);

        jCheckBox5.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(jCheckBox5, org.openide.util.NbBundle.getMessage(BatchPanel.class, "BatchPanel.jCheckBox5.text")); // NOI18N

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jButton4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jButton6))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jCheckBox5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jButtonInfo1)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(14, 14, 14)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jCheckBox5))
                    .addComponent(jButtonInfo1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton4)
                    .addComponent(jButton6))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        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(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(99, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jCheckBox2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox2ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jCheckBox2ActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButtonInfo1;
    private javax.swing.JButton jButtonInfo2;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox2;
    private javax.swing.JCheckBox jCheckBox3;
    private javax.swing.JCheckBox jCheckBox4;
    private javax.swing.JCheckBox jCheckBox5;
    private javax.swing.JComboBox<String> jComboBox1;
    private javax.swing.JComboBox<String> jComboBox2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private cz.fidentis.analyst.core.SpinSlider spinSlider1;
    // End of variables declaration//GEN-END:variables