commit 5b4d557e7dd82aabd1f5c536b2edc42f813d720c Author: Gabriel Augendre Date: Mon Apr 18 17:03:33 2016 +0200 Add working project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d3377dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ + +# Created by https://www.gitignore.io/api/intellij,java,maven + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/ + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Intellij Patch ### +*.iml + + +### Java ### +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4352c64 --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + info.augendre + name-picker + 1.0-SNAPSHOT + jar + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + + ihm-base + + + + info.augendre.name_picker.Main + + + name-picker + + package + + single + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.1 + + private + true + + + + + + + + com.intellij + forms_rt + 7.0.3 + + + junit + junit + 4.10 + test + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.1 + + public + + + + + \ No newline at end of file diff --git a/src/main/java/info/augendre/name_picker/ChooseFileAction.java b/src/main/java/info/augendre/name_picker/ChooseFileAction.java new file mode 100644 index 0000000..4951dd5 --- /dev/null +++ b/src/main/java/info/augendre/name_picker/ChooseFileAction.java @@ -0,0 +1,41 @@ +package info.augendre.name_picker; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.File; + +/** + * Created by gaugendre on 18/04/2016 13:32. + */ +public class ChooseFileAction extends AbstractAction { + private JFrame parent; + private MainPanel mainPanel; + + public ChooseFileAction(MainPanel mainPanel) { + this.mainPanel = mainPanel; + this.parent = mainPanel.getMainFrame(); + } + + @Override + public void actionPerformed(ActionEvent e) { + File file = null; + FileDialog dialog; + String mHomeDir = System.getProperty("user.home"); + + dialog = new FileDialog(parent, "Save", FileDialog.LOAD); + dialog.setDirectory(mHomeDir); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + + if (dialog.getFile() != null) { + mHomeDir = dialog.getDirectory(); + file = new File(mHomeDir + dialog.getFile()); + } + + if (file != null) { + mainPanel.setNamesFile(file); + } + + } +} diff --git a/src/main/java/info/augendre/name_picker/ComputeResults.java b/src/main/java/info/augendre/name_picker/ComputeResults.java new file mode 100644 index 0000000..bec56b5 --- /dev/null +++ b/src/main/java/info/augendre/name_picker/ComputeResults.java @@ -0,0 +1,104 @@ +package info.augendre.name_picker; + +import javax.swing.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.Normalizer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Created by gaugendre on 18/04/2016 13:56. + */ +public class ComputeResults implements Runnable { + private final int LENGTH = 6; + private final String VOWELS = "aeiouy"; + private final MainPanel mainPanel; + private File file; + + public ComputeResults(MainPanel mainPanel) { + this.file = mainPanel.getNamesFile(); + this.mainPanel = mainPanel; + } + + @Override + public void run() { + try { + Path filePath = Paths.get(file.getAbsolutePath()); + List validStrings = Files.lines(filePath).parallel().filter(this::isValid).collect(Collectors.toList()); + mainPanel.getValidNamesList().setListData(validStrings.toArray()); + } + catch (FileNotFoundException e) { + System.err.println("ERR: Le fichier source n'existe pas ou le fichier de destination ne peut être crée ou ouvert."); + } + catch (IOException e) { + System.err.println("ERR: entrée/sortie."); + } + } + + private boolean isValid(String s) { + s = Normalizer.normalize(s, Normalizer.Form.NFD); + s = s.replaceAll("\\p{M}", ""); + s = s.toLowerCase(); + return lengthValidator(s) + && vowelsAlternanceValidator(s) + && containsValidator(s) + && touchesOnceValidator(s) + && noLetterRepeatValidator(s); + } + + private boolean lengthValidator(String s) { + return s.length() == LENGTH; + } + + private boolean vowelsAlternanceValidator(String s) { + boolean previousIsVowel = isVowel(s.charAt(0)); + + for (int i = 1; i < s.length(); i++) { + char c = s.charAt(i); + boolean currentIsVowel = isVowel(c); + + if (currentIsVowel && previousIsVowel || !currentIsVowel && !previousIsVowel) { + return false; + } + previousIsVowel = currentIsVowel; + } + return true; + } + + private boolean isVowel(char o) { + o = Character.toLowerCase(o); + return VOWELS.indexOf(o) >= 0; + } + + private boolean containsValidator(String s) { + return s.charAt(s.length() - 1) != 'a' && s.indexOf('h') < 0; + } + + private boolean touchesOnceValidator(String s) { + return (s.contains("b") ? 1 : 0) + + (s.contains("m") ? 1 : 0) + + (s.contains("p") ? 1 : 0) == 1; + } + + private boolean noLetterRepeatValidator(String s) { + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char current = s.charAt(i); + int count = map.getOrDefault(current, 0) + 1; + if (count > 1) { + return false; + } + map.put(current, count + 1); + } + return true; + } + +} diff --git a/src/main/java/info/augendre/name_picker/Main.java b/src/main/java/info/augendre/name_picker/Main.java new file mode 100644 index 0000000..c4fa75d --- /dev/null +++ b/src/main/java/info/augendre/name_picker/Main.java @@ -0,0 +1,45 @@ +package info.augendre.name_picker; + +import javax.swing.*; +import java.awt.event.KeyEvent; + +/** + * Created by gaugendre on 18/04/2016 12:51. + */ +public class Main implements Runnable { + private JPanel mainPanel; + private JFrame mainFrame; + private final static String CLOSE = "close"; + private final static int AFC = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT; + private final static KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); + + public Main() { + mainFrame = new JFrame("Name Picker"); + this.mainPanel = new MainPanel(mainFrame).getMainPanel(); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Main()); + } + + @Override + public void run() { + try { + UIManager.setLookAndFeel( + UIManager.getSystemLookAndFeelClassName()); + } + catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(System.err); + } + + // Add key binding + mainPanel.getInputMap(AFC).put(escapeStroke, CLOSE); + mainPanel.getActionMap().put(CLOSE, new QuitAction(mainFrame)); + + mainFrame.setContentPane(mainPanel); + mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + } +} diff --git a/src/main/java/info/augendre/name_picker/MainPanel.form b/src/main/java/info/augendre/name_picker/MainPanel.form new file mode 100644 index 0000000..515fcc1 --- /dev/null +++ b/src/main/java/info/augendre/name_picker/MainPanel.form @@ -0,0 +1,112 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/info/augendre/name_picker/MainPanel.java b/src/main/java/info/augendre/name_picker/MainPanel.java new file mode 100644 index 0000000..0a66d96 --- /dev/null +++ b/src/main/java/info/augendre/name_picker/MainPanel.java @@ -0,0 +1,142 @@ +package info.augendre.name_picker; + +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.core.Spacer; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.*; +import java.io.File; +import java.util.ResourceBundle; + +/** + * Created by gaugendre on 18/04/2016 12:57. + */ +public class MainPanel { + private final JFrame mainFrame; + private JPanel mainPanel; + private JButton chooseAFileButton; + private JTextField fileNameField; + private JButton computeButton; + private JList validNamesList; + private JPanel inputPanel; + private JPanel containerPanel; + private JScrollPane namesListScrollPane; + private File namesFile; + + public MainPanel(JFrame mainFrame) { + this.mainFrame = mainFrame; + $$$setupUI$$$(); + chooseAFileButton.addActionListener(new ChooseFileAction(this)); + computeButton.addActionListener(e -> computeResults()); + } + + public void computeResults() { + SwingUtilities.invokeLater(new ComputeResults(this)); + } + + public JPanel getMainPanel() { + return mainPanel; + } + + public File getNamesFile() { + return namesFile; + } + + public void setNamesFile(File namesFile) { + this.namesFile = namesFile; + fileNameField.setText(namesFile.getAbsolutePath()); + mainFrame.pack(); + computeResults(); + } + + public JFrame getMainFrame() { + return mainFrame; + } + + public JList getValidNamesList() { + return validNamesList; + } + + private void createUIComponents() { + validNamesList = new JList<>(); + } + + /** + * Method generated by IntelliJ IDEA GUI Designer + * >>> IMPORTANT!! <<< + * DO NOT edit this method OR call it in your code! + * + * @noinspection ALL + */ + private void $$$setupUI$$$() { + createUIComponents(); + mainPanel = new JPanel(); + mainPanel.setLayout(new GridLayoutManager(3, 3, new Insets(0, 0, 0, 0), -1, -1)); + containerPanel = new JPanel(); + containerPanel.setLayout(new GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1)); + mainPanel.add(containerPanel, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + inputPanel = new JPanel(); + inputPanel.setLayout(new GridLayoutManager(1, 3, new Insets(0, 0, 0, 0), -1, -1)); + containerPanel.add(inputPanel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + fileNameField = new JTextField(); + fileNameField.setEditable(false); + inputPanel.add(fileNameField, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(250, -1), null, 0, false)); + chooseAFileButton = new JButton(); + this.$$$loadButtonText$$$(chooseAFileButton, ResourceBundle.getBundle("GUI").getString("button.choosefile")); + inputPanel.add(chooseAFileButton, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + computeButton = new JButton(); + this.$$$loadButtonText$$$(computeButton, ResourceBundle.getBundle("GUI").getString("button.compute")); + inputPanel.add(computeButton, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JPanel panel1 = new JPanel(); + panel1.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); + containerPanel.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + panel1.setBorder(BorderFactory.createTitledBorder(ResourceBundle.getBundle("GUI").getString("label.valid_names"))); + namesListScrollPane = new JScrollPane(); + panel1.add(namesListScrollPane, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + namesListScrollPane.setViewportView(validNamesList); + final Spacer spacer1 = new Spacer(); + mainPanel.add(spacer1, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, 1, null, new Dimension(5, -1), null, 0, false)); + final Spacer spacer2 = new Spacer(); + mainPanel.add(spacer2, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, 1, null, new Dimension(5, -1), null, 0, false)); + final Spacer spacer3 = new Spacer(); + mainPanel.add(spacer3, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 5), null, 1, false)); + final Spacer spacer4 = new Spacer(); + mainPanel.add(spacer4, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 5), null, 1, false)); + } + + /** + * @noinspection ALL + */ + private void $$$loadButtonText$$$(AbstractButton component, String text) { + StringBuffer result = new StringBuffer(); + boolean haveMnemonic = false; + char mnemonic = '\0'; + int mnemonicIndex = -1; + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) == '&') { + i++; + if (i == text.length()) break; + if (!haveMnemonic && text.charAt(i) != '&') { + haveMnemonic = true; + mnemonic = text.charAt(i); + mnemonicIndex = result.length(); + } + } + result.append(text.charAt(i)); + } + component.setText(result.toString()); + if (haveMnemonic) { + component.setMnemonic(mnemonic); + component.setDisplayedMnemonicIndex(mnemonicIndex); + } + } + + /** + * @noinspection ALL + */ + public JComponent $$$getRootComponent$$$() { + return mainPanel; + } +} diff --git a/src/main/java/info/augendre/name_picker/QuitAction.java b/src/main/java/info/augendre/name_picker/QuitAction.java new file mode 100644 index 0000000..71be51e --- /dev/null +++ b/src/main/java/info/augendre/name_picker/QuitAction.java @@ -0,0 +1,21 @@ +package info.augendre.name_picker; + +import javax.swing.*; +import java.awt.event.ActionEvent; + +/** + * Created by gaugendre on 18/04/2016 13:00. + */ +public class QuitAction extends AbstractAction { + private JFrame mainFrame; + + public QuitAction(JFrame mainFrame) { + this.mainFrame = mainFrame; + } + + @Override + public void actionPerformed(ActionEvent e) { + mainFrame.dispose(); + System.exit(0); + } +} diff --git a/src/main/resources/GUI.properties b/src/main/resources/GUI.properties new file mode 100644 index 0000000..e447616 --- /dev/null +++ b/src/main/resources/GUI.properties @@ -0,0 +1,3 @@ +button.choosefile=Choose a file +button.compute=Compute +label.valid_names=Valid names diff --git a/src/main/resources/GUI_fr.properties b/src/main/resources/GUI_fr.properties new file mode 100644 index 0000000..6a9c099 --- /dev/null +++ b/src/main/resources/GUI_fr.properties @@ -0,0 +1,3 @@ +button.choosefile=Choisissez un fichier +button.compute=Calcul +label.valid_names=Noms conformes diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep new file mode 100644 index 0000000..e69de29