Introduction
I went ahead and created the following GUI.

The GUI consists of a JFrame
with one main JPanel
. The JPanel
uses a GridBagLayout
and consists of a JLabel
, JTextArea
, JLabel
, JTextArea
.
The GUI processes the sentence as it's typed by using a DocumentListener. The code in the DocumentListener
is simple since I do the work of processing the sentence in a separate class.
Here's the GUI after I've typed a few characters.

A few more characters

The final result

Explanation
When I create a Swing GUI, I use the model / view / controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one part of the application at a time.
I created one model class, one view class, and one controller class. The PangramModel
model class produces a result String
for any input sentence String
. The PangramGUI
view class creates the GUI. The SentenceDocumentListener
controller class updates the result JTextArea
.
The most complicated code can be found in the model class. There are probably many ways to process a sentence String
. This was the way I coded.
Code
Here's the complete runnable code. I made the classes inner classes so I could post this code as one block.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class PangramGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new PangramGUI());
}
private JTextArea sentenceArea;
private JTextArea resultArea;
@Override
public void run() {
JFrame frame = new JFrame("Pangram Analysis");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.weightx = 1.0;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 0;
JLabel label = new JLabel("Type the sentence to analyze");
panel.add(label, gbc);
gbc.gridy++;
sentenceArea = new JTextArea(3, 40);
sentenceArea.setLineWrap(true);
sentenceArea.setWrapStyleWord(true);
sentenceArea.getDocument().addDocumentListener(
new SentenceDocumentListener());
panel.add(sentenceArea, gbc);
gbc.gridy++;
label = new JLabel("Pangram result");
panel.add(label, gbc);
gbc.gridy++;
resultArea = new JTextArea(4, 40);
resultArea.setEditable(false);
resultArea.setLineWrap(true);
resultArea.setWrapStyleWord(true);
panel.add(resultArea, gbc);
return panel;
}
public class SentenceDocumentListener implements DocumentListener {
private PangramModel model;
public SentenceDocumentListener() {
this.model = new PangramModel();
}
@Override
public void insertUpdate(DocumentEvent event) {
processSentence(sentenceArea.getText());
}
@Override
public void removeUpdate(DocumentEvent event) {
processSentence(sentenceArea.getText());
}
@Override
public void changedUpdate(DocumentEvent event) {
processSentence(sentenceArea.getText());
}
private void processSentence(String text) {
String result = model.processSentence(text);
resultArea.setText(result);
}
}
public class PangramModel {
private String alphabet;
public PangramModel() {
this.alphabet = "abcdefghijklmnopqrstuvwxyz";
}
public String processSentence(String sentence) {
int[] count = new int[alphabet.length()];
for (int index = 0; index < sentence.length(); index++) {
char c = Character.toLowerCase(sentence.charAt(index));
int charIndex = alphabet.indexOf(c);
if (charIndex >= 0) {
count[charIndex]++;
}
}
if (isEmpty(count)) {
return "Not a pangram";
} else {
List<Character> missingCharacters = getUnusedCharacters(count);
if (missingCharacters.size() <= 0) {
return "A pangram";
} else {
StringBuilder builder = new StringBuilder();
builder.append("Not a complete pangram");
builder.append(System.lineSeparator());
builder.append(System.lineSeparator());
builder.append("Missing characters: ");
for (int index = 0; index < missingCharacters.size(); index++) {
builder.append(missingCharacters.get(index));
if (index < (missingCharacters.size() - 1)) {
builder.append(", ");
}
}
return builder.toString();
}
}
}
private boolean isEmpty(int[] count) {
for (int index = 0; index < count.length; index++) {
if (count[index] > 0) {
return false;
}
}
return true;
}
private List<Character> getUnusedCharacters(int[] count) {
List<Character> output = new ArrayList<>();
for (int index = 0; index < count.length; index++) {
if (count[index] <= 0) {
output.add(alphabet.charAt(index));
}
}
return output;
}
}
}