wordstudent

Word learning program
git clone git://git.wimdupont.com/wordstudent.git
Log | Files | Refs | LICENSE

WordTester.java (7448B)


      1 package com.wimdupont.service;
      2 
      3 import com.fasterxml.jackson.core.JsonProcessingException;
      4 import com.wimdupont.client.Client;
      5 import com.wimdupont.client.DictionaryApi;
      6 import com.wimdupont.client.WordRepository;
      7 import com.wimdupont.model.dto.WordDto;
      8 
      9 import javax.swing.AbstractAction;
     10 import javax.swing.ActionMap;
     11 import javax.swing.Box;
     12 import javax.swing.BoxLayout;
     13 import javax.swing.InputMap;
     14 import javax.swing.JButton;
     15 import javax.swing.JComponent;
     16 import javax.swing.JFrame;
     17 import javax.swing.JLabel;
     18 import javax.swing.JPanel;
     19 import javax.swing.JScrollPane;
     20 import javax.swing.JTextArea;
     21 import javax.swing.KeyStroke;
     22 import javax.swing.text.DefaultCaret;
     23 import java.awt.BorderLayout;
     24 import java.awt.Color;
     25 import java.awt.Dimension;
     26 import java.awt.Font;
     27 import java.awt.event.ActionEvent;
     28 import java.util.Collections;
     29 import java.util.List;
     30 import java.util.concurrent.atomic.AtomicInteger;
     31 
     32 public class WordTester {
     33 
     34     private final WordRepository wordRepository;
     35     private final DictionaryApi dictionaryApi;
     36     private final InputMap inputMap;
     37     private static final String PREVIOUS = "Previous";
     38     private static final String SHOW = "Show";
     39     private static final String NEXT = "Next";
     40 
     41     public WordTester(WordRepository wordRepository,
     42                       DictionaryApi dictionaryApi) {
     43         this.wordRepository = wordRepository;
     44         this.dictionaryApi = dictionaryApi;
     45         this.inputMap = initiateInputMap();
     46     }
     47 
     48     public void startTest(List<String> words) {
     49         Collections.shuffle(words);
     50         showUI(words);
     51     }
     52 
     53     public void saveNew(List<String> words) {
     54         List<String> savedWordList = wordRepository.findAllWords();
     55         System.out.printf("Words in database: %s%n", savedWordList.size());
     56         AtomicInteger count = new AtomicInteger(0);
     57         words.stream()
     58                 .filter(csvWord -> !savedWordList.contains(csvWord))
     59                 .forEach(newWord -> {
     60                     var response = dictionaryApi.getDictionary(newWord);
     61                     if (response.isEmpty()) {
     62                         System.out.printf("No results found for '%s', no data saved%n", newWord);
     63                         count.get();
     64                     } else {
     65                         wordRepository.save(response.get());
     66                         System.out.printf("Saved new word %s%n", response.get());
     67                         count.getAndIncrement();
     68                     }
     69                 });
     70 
     71         if (count.get() > 0)
     72             System.out.printf("Saved %s words%n", count.get());
     73     }
     74 
     75     private InputMap initiateInputMap() {
     76         var inputMap = new InputMap();
     77         inputMap.put(KeyStroke.getKeyStroke("LEFT"), PREVIOUS);
     78         inputMap.put(KeyStroke.getKeyStroke("H"), PREVIOUS);
     79         inputMap.put(KeyStroke.getKeyStroke("L"), NEXT);
     80         inputMap.put(KeyStroke.getKeyStroke("RIGHT"), NEXT);
     81         inputMap.put(KeyStroke.getKeyStroke("DOWN"), SHOW);
     82         inputMap.put(KeyStroke.getKeyStroke("SPACE"), SHOW);
     83         inputMap.put(KeyStroke.getKeyStroke("J"), SHOW);
     84         return inputMap;
     85     }
     86 
     87     private void showUI(List<String> words) {
     88         AtomicInteger index = new AtomicInteger(0);
     89         JFrame jFrame = new JFrame();
     90         jFrame.setLayout(new BorderLayout());
     91         var wordPanel = new JPanel();
     92         wordPanel.setFocusable(false);
     93         wordPanel.setLayout(new BoxLayout(wordPanel, BoxLayout.Y_AXIS));
     94         var wordField = new JLabel(words.get(index.get()));
     95         wordPanel.add(Box.createRigidArea(new Dimension(20, 20)));
     96         wordPanel.add(wordField);
     97         wordField.setFont(new Font(Font.SERIF, Font.BOLD, 30));
     98         wordPanel.add(Box.createRigidArea(new Dimension(20, 20)));
     99         var showPanel = createShowPanel(index, wordField, words);
    100         wordPanel.add(new JScrollPane(showPanel));
    101         jFrame.add(wordPanel, BorderLayout.CENTER);
    102         jFrame.add(createButtonPanel(showPanel), BorderLayout.SOUTH);
    103         jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    104         jFrame.pack();
    105         jFrame.setVisible(true);
    106     }
    107 
    108     private JTextArea createShowPanel(AtomicInteger index, JLabel wordField, List<String> words) {
    109         var dictionaryPanel = new JTextArea();
    110         dictionaryPanel.setLineWrap(true);
    111         dictionaryPanel.setEditable(false);
    112         dictionaryPanel.setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
    113         dictionaryPanel.setBackground(new Color(0, 0, 51));
    114         dictionaryPanel.setForeground(new Color(150, 250, 250));
    115         dictionaryPanel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
    116         ((DefaultCaret) dictionaryPanel.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    117         var actionMap = new ActionMap();
    118         actionMap.put(PREVIOUS, previous(index, wordField, words, dictionaryPanel));
    119         actionMap.put(SHOW, show(index, words, dictionaryPanel));
    120         actionMap.put(NEXT, next(index, wordField, words, dictionaryPanel));
    121         dictionaryPanel.setActionMap(actionMap);
    122         return dictionaryPanel;
    123     }
    124 
    125     private JPanel createButtonPanel(JTextArea showPanel) {
    126         JButton previousButton = new JButton(PREVIOUS);
    127         previousButton.addActionListener(showPanel.getActionMap().get(PREVIOUS));
    128         previousButton.setFocusable(false);
    129         JButton showButton = new JButton(SHOW);
    130         showButton.setFocusable(false);
    131         showButton.addActionListener(showPanel.getActionMap().get(SHOW));
    132         JButton nextButton = new JButton(NEXT);
    133         nextButton.setFocusable(false);
    134         nextButton.addActionListener(showPanel.getActionMap().get(NEXT));
    135 
    136         var btnPanel = new JPanel();
    137         btnPanel.add(previousButton);
    138         btnPanel.add(showButton);
    139         btnPanel.add(nextButton);
    140 
    141         return btnPanel;
    142     }
    143 
    144     private AbstractAction previous(AtomicInteger index, JLabel wordField, List<String> words, JTextArea showPanel) {
    145         return toActionListener(() -> {
    146             if (index.get() > 0) {
    147                 wordField.setText(words.get(index.decrementAndGet()));
    148                 showPanel.setText(null);
    149             }
    150         });
    151     }
    152 
    153     private AbstractAction show(AtomicInteger index, List<String> words, JTextArea showPanel) {
    154         return toActionListener(() -> {
    155             var word = wordRepository.findByWord(words.get(index.get()));
    156             word.ifPresent(wordDto -> showPanel.setText(toMeaning(wordDto)));
    157             showPanel.setVisible(true);
    158         });
    159     }
    160 
    161     private AbstractAction next(AtomicInteger index, JLabel wordField, List<String> words, JTextArea showPanel) {
    162         return toActionListener(() -> {
    163             if (index.get() < words.size()) {
    164                 wordField.setText(words.get(index.incrementAndGet()));
    165                 showPanel.setText(null);
    166             }
    167         });
    168     }
    169 
    170     private AbstractAction toActionListener(Runnable runnable) {
    171         return new AbstractAction() {
    172 
    173             @Override
    174             public void actionPerformed(ActionEvent actionEvent) {
    175                 runnable.run();
    176             }
    177         };
    178 
    179     }
    180 
    181     private String toMeaning(WordDto wordDto) {
    182         try {
    183             return Client.getObjectMapper()
    184                     .writerWithDefaultPrettyPrinter()
    185                     .writeValueAsString(wordDto.dictionaryResults());
    186         } catch (JsonProcessingException e) {
    187             throw new RuntimeException(e);
    188         }
    189     }
    190 
    191 }