/** Initializes the members. */
  protected void initialize() {
    ExtensionFileFilter filter;

    super.initialize();

    m_FileChooserPdfTemplate = new BaseFileChooser();
    m_FileChooserPdfTemplate.addChoosableFileFilter(ExtensionFileFilter.getPdfFileFilter());
    m_FileChooserPdfTemplate.setAcceptAllFileFilterUsed(false);
    m_FileChooserPdfTemplate.setMultiSelectionEnabled(false);

    m_FileChooserParams = new BaseFileChooser();
    m_FileChooserParams.addChoosableFileFilter(ExtensionFileFilter.getCsvFileFilter());
    m_FileChooserParams.setAcceptAllFileFilterUsed(false);
    m_FileChooserParams.setMultiSelectionEnabled(false);

    filter = new ExtensionFileFilter("Groovy script", "groovy");
    m_FileChooserGroovy = new BaseFileChooser();
    m_FileChooserGroovy.addChoosableFileFilter(filter);
    m_FileChooserGroovy.setAcceptAllFileFilterUsed(false);
    m_FileChooserGroovy.setMultiSelectionEnabled(false);

    m_DirChooser = new BaseDirectoryChooser();

    m_Processing = false;
  }
  /** Initializes the widgets. */
  protected void initGUI() {
    JPanel panelParams;
    List<JLabel> labels;

    setLayout(new BorderLayout());

    // the parameters
    panelParams = new JPanel(new GridLayout(4, 1));
    panelParams.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    labels = new ArrayList<>();
    add(panelParams, BorderLayout.CENTER);
    // PDF template
    {
      JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
      panelParams.add(panel);
      m_TextPdfTemplate = new JTextField(30);
      m_TextPdfTemplate
          .getDocument()
          .addDocumentListener(
              new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                  checkDir();
                }

                protected void checkDir() {
                  if (m_TextPdfTemplate.getText().trim().isEmpty()
                      || isValidFile(m_TextPdfTemplate.getText()))
                    m_TextPdfTemplate.setForeground(Color.BLACK);
                  else m_TextPdfTemplate.setForeground(Color.RED);
                  updateButtons();
                }
              });
      JLabel label = new JLabel("PDF Template");
      label.setDisplayedMnemonic('P');
      label.setLabelFor(m_TextPdfTemplate);

      m_ButtonPdfTemplate = new JButton("...");
      m_ButtonPdfTemplate.setPreferredSize(
          new Dimension(
              (int) m_ButtonPdfTemplate.getPreferredSize().getWidth(),
              (int) m_TextPdfTemplate.getPreferredSize().getHeight()));
      m_ButtonPdfTemplate.addActionListener(
          (ActionEvent e) -> {
            if (!m_TextPdfTemplate.getText().isEmpty())
              m_FileChooserPdfTemplate.setCurrentDirectory(new File(m_TextPdfTemplate.getText()));
            int retVal = m_FileChooserPdfTemplate.showOpenDialog(ScriptedPDFOverlayGUI.this);
            if (retVal != BaseFileChooser.APPROVE_OPTION) return;
            m_TextPdfTemplate.setText(m_FileChooserPdfTemplate.getSelectedFile().getAbsolutePath());
          });

      panel.add(label);
      panel.add(m_TextPdfTemplate);
      panel.add(m_ButtonPdfTemplate);
      labels.add(label);
    }
    // Params (CSV spreadshet)
    {
      JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
      panelParams.add(panel);
      m_TextParams = new JTextField(30);
      m_TextParams
          .getDocument()
          .addDocumentListener(
              new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                  checkDir();
                }

                protected void checkDir() {
                  if (m_TextParams.getText().trim().isEmpty()
                      || isValidFile(m_TextParams.getText()))
                    m_TextParams.setForeground(Color.BLACK);
                  else m_TextParams.setForeground(Color.RED);
                  updateButtons();
                }
              });
      JLabel label = new JLabel("CSV Spreadsheet");
      label.setDisplayedMnemonic('C');
      label.setLabelFor(m_TextParams);

      m_ButtonParams = new JButton("...");
      m_ButtonParams.setPreferredSize(
          new Dimension(
              (int) m_ButtonParams.getPreferredSize().getWidth(),
              (int) m_TextParams.getPreferredSize().getHeight()));
      m_ButtonParams.addActionListener(
          (ActionEvent e) -> {
            if (!m_TextParams.getText().isEmpty())
              m_FileChooserParams.setCurrentDirectory(new File(m_TextParams.getText()));
            int retVal = m_FileChooserParams.showOpenDialog(ScriptedPDFOverlayGUI.this);
            if (retVal != BaseFileChooser.APPROVE_OPTION) return;
            m_TextParams.setText(m_FileChooserParams.getSelectedFile().getAbsolutePath());
          });

      panel.add(label);
      panel.add(m_TextParams);
      panel.add(m_ButtonParams);
      labels.add(label);
    }
    // Groovy
    {
      JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
      panelParams.add(panel);
      m_TextGroovy = new JTextField(30);
      m_TextGroovy
          .getDocument()
          .addDocumentListener(
              new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                  checkDir();
                }

                protected void checkDir() {
                  if (m_TextGroovy.getText().trim().isEmpty()
                      || isValidFile(m_TextGroovy.getText()))
                    m_TextGroovy.setForeground(Color.BLACK);
                  else m_TextGroovy.setForeground(Color.RED);
                  updateButtons();
                }
              });
      JLabel label = new JLabel("Groovy script");
      label.setDisplayedMnemonic('G');
      label.setLabelFor(m_TextGroovy);

      m_ButtonGroovy = new JButton("...");
      m_ButtonGroovy.setPreferredSize(
          new Dimension(
              (int) m_ButtonGroovy.getPreferredSize().getWidth(),
              (int) m_TextGroovy.getPreferredSize().getHeight()));
      m_ButtonGroovy.addActionListener(
          (ActionEvent e) -> {
            if (!m_TextGroovy.getText().isEmpty())
              m_FileChooserGroovy.setCurrentDirectory(new File(m_TextGroovy.getText()));
            int retVal = m_FileChooserGroovy.showOpenDialog(ScriptedPDFOverlayGUI.this);
            if (retVal != BaseFileChooser.APPROVE_OPTION) return;
            m_TextGroovy.setText(m_FileChooserGroovy.getSelectedFile().getAbsolutePath());
          });

      panel.add(label);
      panel.add(m_TextGroovy);
      panel.add(m_ButtonGroovy);
      labels.add(label);
    }
    // output dir
    {
      JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
      panelParams.add(panel);
      m_TextOutputDir = new JTextField(30);
      m_TextOutputDir
          .getDocument()
          .addDocumentListener(
              new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                  checkDir();
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                  checkDir();
                }

                protected void checkDir() {
                  if (m_TextOutputDir.getText().trim().isEmpty() || isValidOutputDir())
                    m_TextOutputDir.setForeground(Color.BLACK);
                  else m_TextOutputDir.setForeground(Color.RED);
                  updateButtons();
                }
              });
      JLabel label = new JLabel("Output directory");
      label.setDisplayedMnemonic('O');
      label.setLabelFor(m_TextOutputDir);

      m_ButtonOutputDir = new JButton("...");
      m_ButtonOutputDir.setPreferredSize(
          new Dimension(
              (int) m_ButtonOutputDir.getPreferredSize().getWidth(),
              (int) m_TextOutputDir.getPreferredSize().getHeight()));
      m_ButtonOutputDir.addActionListener(
          (ActionEvent e) -> {
            if (!m_TextOutputDir.getText().isEmpty())
              m_DirChooser.setCurrentDirectory(new File(m_TextOutputDir.getText()));
            int retVal = m_DirChooser.showOpenDialog(ScriptedPDFOverlayGUI.this);
            if (retVal != BaseDirectoryChooser.APPROVE_OPTION) return;
            m_TextOutputDir.setText(m_DirChooser.getSelectedFile().getAbsolutePath());
          });

      panel.add(label);
      panel.add(m_TextOutputDir);
      panel.add(m_ButtonOutputDir);
      labels.add(label);
    }

    // the buttons at the bottom
    {
      JPanel panelBottom = new JPanel(new BorderLayout());
      add(panelBottom, BorderLayout.SOUTH);

      JPanel panelRight = new JPanel(new FlowLayout(FlowLayout.RIGHT));
      panelBottom.add(panelRight, BorderLayout.EAST);

      m_ButtonGenerate = new JButton("Generate", GUIHelper.getIcon("run.gif"));
      m_ButtonGenerate.addActionListener((ActionEvent e) -> process());
      panelRight.add(m_ButtonGenerate);

      m_ButtonClose = new JButton("Close", GUIHelper.getIcon("stop.gif"));
      m_ButtonClose.addActionListener(
          (ActionEvent e) -> GUIHelper.closeParent(ScriptedPDFOverlayGUI.this));
      panelRight.add(m_ButtonClose);
    }

    // adjust labels
    validate();
    int max = 0;
    for (JLabel label : labels) {
      if (label.getPreferredSize().getWidth() > max)
        max = (int) label.getPreferredSize().getWidth();
    }
    max += 5;
    for (JLabel label : labels)
      label.setPreferredSize(new Dimension(max, (int) label.getPreferredSize().getHeight()));
  }