private void initConfigPanel(JFrame parent) {
   JPanel configPanel = new JPanel(new GridLayout(0, 1));
   configPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
   getContentPane().add(configPanel, BorderLayout.CENTER);
   for (int i = 0; i < PROPERTIES.getPopularPhrases().length; i++) {
     configPanel.add(createPopularPhrasePanel(i));
   }
 }
 private void saveConfiguration() {
   PROPERTIES.setSplashScreenEnabled(chckbxSplashScreenEnabled.isSelected());
   PROPERTIES.setWelcomeScreenEnabled(chckbxWelcomeScreenEnabled.isSelected());
   PROPERTIES.setStartMinimized(chckbxStartMinimized.isSelected());
   PROPERTIES.setNativeHookEnabled(nativeHookKeyCodes.length > 0);
   PROPERTIES.setNativeHookKeyCodes(nativeHookKeyCodes);
   PROPERTIES.setLaf(((LookAndFeel) lafComboBox.getSelectedItem()).getName());
   PROPERTIES.setSuggestionsEnabled(chckbxShowSuggestions.isSelected());
 }
  private JPanel createPopularPhrasePanel(int index) {
    JPanel popularPhrasePanel = new JPanel();
    popularPhrasePanel.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default"),
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("default:grow"),
              FormFactory.DEFAULT_COLSPEC,
              ColumnSpec.decode("default")
            },
            new RowSpec[] {FormFactory.DEFAULT_ROWSPEC}));

    popularPhrasePanel.add(new JLabel("" + (index + 1)), "1, 1");

    textFields.add(new JTextField(PROPERTIES.getPopularPhrase(index)));
    popularPhrasePanel.add(textFields.get(index), "3, 1");

    JButton playButton = new JButton(Icon.getIcon("/icons/control_play.png"));
    playButton.addActionListener(
        a -> speeker.speek(Arrays.asList(textFields.get(index).getText())));
    popularPhrasePanel.add(playButton, "5, 1");
    return popularPhrasePanel;
  }
  private void initConfigPanel(JFrame parent) {
    JPanel configPanel = new JPanel();
    configPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
    getContentPane().add(configPanel, BorderLayout.CENTER);
    configPanel.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("right:default"),
              ColumnSpec.decode("right:default"),
              ColumnSpec.decode("right:default")
            },
            new RowSpec[] {
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              RowSpec.decode("default:grow"),
            }));

    StringSeparator lafSeparator = new StringSeparator(MESSAGES.get("laf"));
    configPanel.add(lafSeparator, "1, 7, 5, 1");

    LookAndFeel[] allLafs = LookAndFeel.getAll();
    lafComboBox = new JComboBox<>(allLafs);
    LookAndFeel selectedLaf =
        Arrays.stream(allLafs)
            .filter(l -> l.getName().equals(PROPERTIES.getLaf()))
            .findFirst()
            .get();
    lafComboBox.setSelectedItem(selectedLaf);
    configPanel.add(lafComboBox, "3, 9, 3, 1");

    StringSeparator splashScreenSeparator = new StringSeparator(MESSAGES.get("splash_screen"));
    configPanel.add(splashScreenSeparator, "1, 7, 5, 1");

    JLabel lblSplashScreenEnabled = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblSplashScreenEnabled, "3, 9");

    chckbxSplashScreenEnabled = new JCheckBox();
    chckbxSplashScreenEnabled.setSelected(PROPERTIES.isSplashScreenEnabled());
    configPanel.add(chckbxSplashScreenEnabled, "4, 9");

    StringSeparator welcomeScreenSeparator = new StringSeparator(MESSAGES.get("welcome_screen"));
    configPanel.add(welcomeScreenSeparator, "1, 11, 5, 1");

    JLabel lblShowWelcomeScreen = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblShowWelcomeScreen, "4, 13");

    chckbxWelcomeScreenEnabled = new JCheckBox();
    chckbxWelcomeScreenEnabled.setSelected(PROPERTIES.isWelcomeScreenEnabled());
    configPanel.add(chckbxWelcomeScreenEnabled, "5, 13");

    StringSeparator startMinimizedSeparator = new StringSeparator(MESSAGES.get("start_minimized"));
    configPanel.add(startMinimizedSeparator, "1, 15, 5, 1");

    JLabel lblStartMinized = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblStartMinized, "4, 17");

    chckbxStartMinimized = new JCheckBox();
    chckbxStartMinimized.setSelected(PROPERTIES.isStartMinimized());
    configPanel.add(chckbxStartMinimized, "5, 17");

    StringSeparator nativeHookSeparator = new StringSeparator(MESSAGES.get("native_hook"));
    configPanel.add(nativeHookSeparator, "1, 19, 5, 1");

    nativeHookLabel = new JLabel(getNativeHookText(nativeHookKeyCodes));
    configPanel.add(nativeHookLabel, "2, 23");

    JButton btnRecordNativeHook = new JButton(Icon.getIcon("/icons/pencil.png"));
    configPanel.add(btnRecordNativeHook, "4, 23, 2, 1, fill, default");
    btnRecordNativeHook.addActionListener(
        e -> {
          RecordNativeHookDialog dialog = new RecordNativeHookDialog(parent);
          dialog.setVisible(true);
          if (dialog.isOkButtonPressed()) {
            nativeHookKeyCodes = dialog.getNativeHookKeyCodes();
            nativeHookLabel.setText(getNativeHookText(nativeHookKeyCodes));
          }
          dialog.dispose();
        });

    StringSeparator suggestionsSeparator = new StringSeparator(MESSAGES.get("suggestions"));
    configPanel.add(suggestionsSeparator, "1, 25, 5, 1");

    JLabel lblSuggestions = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblSuggestions, "2, 27, 3, 1, right, center");

    chckbxShowSuggestions = new JCheckBox();
    chckbxShowSuggestions.setSelected(PROPERTIES.isSuggestionsEnabled());
    configPanel.add(chckbxShowSuggestions, "5, 27");
  }
public class GuiConfigDialog extends JDialog {

  private static final Messages MESSAGES = Messages.getInstance();
  private static final TypeTalkProperties PROPERTIES = TypeTalkProperties.getInstance();

  @Getter private boolean okPressed;
  @Getter private boolean settingsChanged;
  private int[] nativeHookKeyCodes = PROPERTIES.getNativeHookKeyCodes();

  private JCheckBox chckbxSplashScreenEnabled;
  private JCheckBox chckbxWelcomeScreenEnabled;
  private JCheckBox chckbxStartMinimized;
  private JCheckBox chckbxShowSuggestions;
  private JLabel nativeHookLabel;
  private JComboBox<LookAndFeel> lafComboBox;

  public GuiConfigDialog(JFrame parent) {
    super(parent, MESSAGES.get("gui_config_title"), true);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(450, 450);
    ScreenPositioner.centerOnScreen(this);
    initActionsPanel();
    initConfigPanel(parent);
  }

  private void initConfigPanel(JFrame parent) {
    JPanel configPanel = new JPanel();
    configPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
    getContentPane().add(configPanel, BorderLayout.CENTER);
    configPanel.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("default:grow"),
              ColumnSpec.decode("right:default"),
              ColumnSpec.decode("right:default"),
              ColumnSpec.decode("right:default")
            },
            new RowSpec[] {
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              RowSpec.decode("default:grow"),
            }));

    StringSeparator lafSeparator = new StringSeparator(MESSAGES.get("laf"));
    configPanel.add(lafSeparator, "1, 7, 5, 1");

    LookAndFeel[] allLafs = LookAndFeel.getAll();
    lafComboBox = new JComboBox<>(allLafs);
    LookAndFeel selectedLaf =
        Arrays.stream(allLafs)
            .filter(l -> l.getName().equals(PROPERTIES.getLaf()))
            .findFirst()
            .get();
    lafComboBox.setSelectedItem(selectedLaf);
    configPanel.add(lafComboBox, "3, 9, 3, 1");

    StringSeparator splashScreenSeparator = new StringSeparator(MESSAGES.get("splash_screen"));
    configPanel.add(splashScreenSeparator, "1, 7, 5, 1");

    JLabel lblSplashScreenEnabled = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblSplashScreenEnabled, "3, 9");

    chckbxSplashScreenEnabled = new JCheckBox();
    chckbxSplashScreenEnabled.setSelected(PROPERTIES.isSplashScreenEnabled());
    configPanel.add(chckbxSplashScreenEnabled, "4, 9");

    StringSeparator welcomeScreenSeparator = new StringSeparator(MESSAGES.get("welcome_screen"));
    configPanel.add(welcomeScreenSeparator, "1, 11, 5, 1");

    JLabel lblShowWelcomeScreen = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblShowWelcomeScreen, "4, 13");

    chckbxWelcomeScreenEnabled = new JCheckBox();
    chckbxWelcomeScreenEnabled.setSelected(PROPERTIES.isWelcomeScreenEnabled());
    configPanel.add(chckbxWelcomeScreenEnabled, "5, 13");

    StringSeparator startMinimizedSeparator = new StringSeparator(MESSAGES.get("start_minimized"));
    configPanel.add(startMinimizedSeparator, "1, 15, 5, 1");

    JLabel lblStartMinized = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblStartMinized, "4, 17");

    chckbxStartMinimized = new JCheckBox();
    chckbxStartMinimized.setSelected(PROPERTIES.isStartMinimized());
    configPanel.add(chckbxStartMinimized, "5, 17");

    StringSeparator nativeHookSeparator = new StringSeparator(MESSAGES.get("native_hook"));
    configPanel.add(nativeHookSeparator, "1, 19, 5, 1");

    nativeHookLabel = new JLabel(getNativeHookText(nativeHookKeyCodes));
    configPanel.add(nativeHookLabel, "2, 23");

    JButton btnRecordNativeHook = new JButton(Icon.getIcon("/icons/pencil.png"));
    configPanel.add(btnRecordNativeHook, "4, 23, 2, 1, fill, default");
    btnRecordNativeHook.addActionListener(
        e -> {
          RecordNativeHookDialog dialog = new RecordNativeHookDialog(parent);
          dialog.setVisible(true);
          if (dialog.isOkButtonPressed()) {
            nativeHookKeyCodes = dialog.getNativeHookKeyCodes();
            nativeHookLabel.setText(getNativeHookText(nativeHookKeyCodes));
          }
          dialog.dispose();
        });

    StringSeparator suggestionsSeparator = new StringSeparator(MESSAGES.get("suggestions"));
    configPanel.add(suggestionsSeparator, "1, 25, 5, 1");

    JLabel lblSuggestions = new JLabel(MESSAGES.get("enabled"));
    configPanel.add(lblSuggestions, "2, 27, 3, 1, right, center");

    chckbxShowSuggestions = new JCheckBox();
    chckbxShowSuggestions.setSelected(PROPERTIES.isSuggestionsEnabled());
    configPanel.add(chckbxShowSuggestions, "5, 27");
  }

  private void initActionsPanel() {
    JPanel actionPanel = new JPanel();
    getContentPane().add(actionPanel, BorderLayout.SOUTH);
    FormLayout layout =
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default:grow"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(40dlu;default)"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(40dlu;default)"),
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(5dlu;default)"),
            },
            new RowSpec[] {
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              RowSpec.decode("max(5dlu;default)"),
            });
    actionPanel.setLayout(layout);

    JButton btnCancel = new JButton(MESSAGES.get("cancel"));
    btnCancel.addActionListener(e -> setVisible(false));
    actionPanel.add(btnCancel, "7, 1, 2, 1");

    JButton btnOk = new JButton(MESSAGES.get("ok"));
    btnOk.addActionListener(
        e -> {
          checkSettingsChanged();
          saveConfiguration();
          okPressed = true;
          setVisible(false);
        });
    actionPanel.add(btnOk, "11, 1, 2, 1");
  }

  private void saveConfiguration() {
    PROPERTIES.setSplashScreenEnabled(chckbxSplashScreenEnabled.isSelected());
    PROPERTIES.setWelcomeScreenEnabled(chckbxWelcomeScreenEnabled.isSelected());
    PROPERTIES.setStartMinimized(chckbxStartMinimized.isSelected());
    PROPERTIES.setNativeHookEnabled(nativeHookKeyCodes.length > 0);
    PROPERTIES.setNativeHookKeyCodes(nativeHookKeyCodes);
    PROPERTIES.setLaf(((LookAndFeel) lafComboBox.getSelectedItem()).getName());
    PROPERTIES.setSuggestionsEnabled(chckbxShowSuggestions.isSelected());
  }

  private void checkSettingsChanged() {
    settingsChanged =
        !Arrays.equals(PROPERTIES.getNativeHookKeyCodes(), nativeHookKeyCodes)
            || !((LookAndFeel) lafComboBox.getSelectedItem()).getName().equals(PROPERTIES.getLaf())
            || chckbxShowSuggestions.isSelected() != PROPERTIES.isSuggestionsEnabled();
  }

  private String getNativeHookText(int[] nativeHookKeyCodes) {
    return Arrays.stream(nativeHookKeyCodes)
        .mapToObj(kc -> NativeKeyEvent.getKeyText(kc))
        .collect(Collectors.joining(", "));
  }

  public static void main(String[] args) {
    new GuiConfigDialog(null).setVisible(true);
  }
}
 private void checkSettingsChanged() {
   settingsChanged =
       !Arrays.equals(PROPERTIES.getNativeHookKeyCodes(), nativeHookKeyCodes)
           || !((LookAndFeel) lafComboBox.getSelectedItem()).getName().equals(PROPERTIES.getLaf())
           || chckbxShowSuggestions.isSelected() != PROPERTIES.isSuggestionsEnabled();
 }
@Slf4j
public class PopularPhrasesConfigDialog extends JDialog {

  private static final Messages MESSAGES = Messages.getInstance();
  private static final TypeTalkProperties PROPERTIES = TypeTalkProperties.getInstance();

  @Getter private boolean okPressed;
  private List<JTextField> textFields = new ArrayList<>();
  private Speeker speeker;

  public PopularPhrasesConfigDialog(JFrame parent) {
    super(parent, MESSAGES.get("popular_phrases_config_title"), true);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    initSpeeker();
    initActionsPanel();
    initConfigPanel(parent);
    setSize(800, 450);
    ScreenPositioner.centerOnScreen(this);
  }

  private void initSpeeker() {
    try {
      speeker = new Speeker();
    } catch (MaryConfigurationException e) {
      log.error("Unable to start configure popular phrases dialog", e);
      JOptionPane.showMessageDialog(
          PopularPhrasesConfigDialog.this,
          MESSAGES.get("init_marytts_error"),
          MESSAGES.get("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  private void initConfigPanel(JFrame parent) {
    JPanel configPanel = new JPanel(new GridLayout(0, 1));
    configPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
    getContentPane().add(configPanel, BorderLayout.CENTER);
    for (int i = 0; i < PROPERTIES.getPopularPhrases().length; i++) {
      configPanel.add(createPopularPhrasePanel(i));
    }
  }

  private JPanel createPopularPhrasePanel(int index) {
    JPanel popularPhrasePanel = new JPanel();
    popularPhrasePanel.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default"),
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("default:grow"),
              FormFactory.DEFAULT_COLSPEC,
              ColumnSpec.decode("default")
            },
            new RowSpec[] {FormFactory.DEFAULT_ROWSPEC}));

    popularPhrasePanel.add(new JLabel("" + (index + 1)), "1, 1");

    textFields.add(new JTextField(PROPERTIES.getPopularPhrase(index)));
    popularPhrasePanel.add(textFields.get(index), "3, 1");

    JButton playButton = new JButton(Icon.getIcon("/icons/control_play.png"));
    playButton.addActionListener(
        a -> speeker.speek(Arrays.asList(textFields.get(index).getText())));
    popularPhrasePanel.add(playButton, "5, 1");
    return popularPhrasePanel;
  }

  private void initActionsPanel() {
    JPanel actionPanel = new JPanel();
    getContentPane().add(actionPanel, BorderLayout.SOUTH);
    FormLayout layout =
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("default:grow"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(40dlu;default)"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(40dlu;default)"),
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("max(5dlu;default)"),
            },
            new RowSpec[] {
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              RowSpec.decode("max(5dlu;default)"),
            });
    actionPanel.setLayout(layout);

    JButton btnCancel = new JButton(MESSAGES.get("cancel"));
    btnCancel.addActionListener(e -> setVisible(false));
    actionPanel.add(btnCancel, "7, 1, 2, 1");

    JButton btnDefaults = new JButton(MESSAGES.get("load_defaults"));
    btnDefaults.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            setDefaults();
          }
        });
    actionPanel.add(btnDefaults, "3, 1");

    JButton btnOk = new JButton(MESSAGES.get("ok"));
    btnOk.addActionListener(
        e -> {
          saveConfiguration();
          okPressed = true;
          setVisible(false);
        });
    actionPanel.add(btnOk, "11, 1, 2, 1");
  }

  private void saveConfiguration() {
    for (int i = 0; i < PROPERTIES.getPopularPhrases().length; i++) {
      PROPERTIES.setPopularPhrase(textFields.get(i).getText().trim(), i);
    }
  }

  private void setDefaults() {
    for (int i = 0; i < TypeTalkProperties.DEFAULT_POPULAR_PHRASES.split(",").length; i++) {
      textFields.get(i).setText(TypeTalkProperties.DEFAULT_POPULAR_PHRASES.split(",")[i]);
    }
  }
}
 private void saveConfiguration() {
   for (int i = 0; i < PROPERTIES.getPopularPhrases().length; i++) {
     PROPERTIES.setPopularPhrase(textFields.get(i).getText().trim(), i);
   }
 }