I've revised the code in the light of comments (the initial post was here). I've initially just redone the logic to get a random word for the category chosen by the player. I'd appreciate any feedback on that, then I'll revise the rest of it. Main points addressed: separate out GUI code and use streams. I'm sure there's still lots to be done to improve it. You can run it at replit.com.
Game.java
public class Game {
public static void main (String[] args){
Word word = new Word();
String randomWord = word.getWord();
System.out.println(randomWord);
}
}
Word.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class Word {
private static final String WORD_LIST_DIRECTORY = "wordLists/";
private static final int MAX_WORD_LENGTH = 20;
private static final int MIN_WORD_LENGTH = 3;
String getWord(){
String category = category();
List<String> words = wordsInCategory(category);
Random generateRandom = new Random();
int randomIndex = generateRandom.nextInt(words.size());
String word = words.get(randomIndex);
return word.trim();
}
private String category() {
List<String> filenames = null;
Path path = Paths.get(WORD_LIST_DIRECTORY);
try {
Stream<Path> stream = Files.list(path);
filenames = stream.filter(Files::isRegularFile)
.map(Path::getFileName)
.map(Path::toString)
.collect(toList());
} catch (IOException e) {
ErrorReporter.missingCategories();
}
CategoryChooser chooser = new CategoryChooser();
String choice = chooser.chooseCategory(filenames);
return choice;
}
private List<String> wordsInCategory(String category){
List<String> words;
Path path = Paths.get(WORD_LIST_DIRECTORY +category);
try {
Stream<String> stream = Files.lines(path);
words = stream.map(String::toUpperCase)
.filter(str -> (str.length() <= MAX_WORD_LENGTH))
.filter(str -> (str.length() >= MIN_WORD_LENGTH))
.collect(toList());
} catch (IOException e) {
ErrorReporter.missingCategory();
words=loadDefaultWords();
}
if (words.size()<1){
ErrorReporter.missingWords();
words=loadDefaultWords();
}
return words;
}
private List<String> loadDefaultWords(){
return List.of("FOXGLOVE", "MICROWAVE","ZOMBIE","PUPPY","RHUBARB","DWARF","BICYCLE",
"BUZZARD","OWL","CHAFFINCH","KIRIBATI","LIECHTENSTEIN","MOZAMBIQUE");
}
}
CategoryChooser.java
import javax.swing.*;
import java.util.List;
import java.util.Objects;
public class CategoryChooser {
private String category;
String chooseCategory(List<String> categoryNames){
String[] categories = categoryNames.toArray(new String[0]);
category = categories[0];
JComboBox<String> jComboBox = new JComboBox<>(categories);
jComboBox.addActionListener(e -> category = Objects.requireNonNull(jComboBox.getSelectedItem()).toString());
JOptionPane.showMessageDialog(null, jComboBox, "Word list",
JOptionPane.QUESTION_MESSAGE);
return category;
}
}
ErrorReporter.java
import javax.swing.*;
public class ErrorReporter {
static void missingCategories(){
JOptionPane.showMessageDialog(null, "No word lists found, using default words instead");
}
static void missingCategory(){
JOptionPane.showMessageDialog(null, "Word list missing, using default words instead");
}
static void missingWords(){
JOptionPane.showMessageDialog(null, "No words found, using default words instead");
}
}