Java Observer 模式实现文本编辑器统计功能
首先,我们需要定义观察者接口和主题接口。
// 观察者接口
public interface Observer {
void update();
}
// 主题接口
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
接下来,我们定义可编辑文本区类和三个文本信息统计区类。
// 可编辑文本区类
public class EditableText implements Subject {
private String text;
private List<Observer> observers;
public EditableText() {
this.text = "";
this.observers = new ArrayList<>();
}
public void setText(String text) {
this.text = text;
notifyObservers();
}
public String getText() {
return text;
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
// 单词总数和字符总数统计区类
public class WordAndCharCountObserver implements Observer {
private EditableText editableText;
private JLabel wordCountLabel;
private JLabel charCountLabel;
public WordAndCharCountObserver(EditableText editableText, JLabel wordCountLabel, JLabel charCountLabel) {
this.editableText = editableText;
this.wordCountLabel = wordCountLabel;
this.charCountLabel = charCountLabel;
editableText.registerObserver(this);
}
@Override
public void update() {
String text = editableText.getText();
int wordCount = text.split("\\s+").length;
int charCount = text.length();
wordCountLabel.setText("单词总数:" + wordCount);
charCountLabel.setText("字符总数:" + charCount);
}
}
// 去重后按照字典序排序的单词统计区类
public class DistinctWordObserver implements Observer {
private EditableText editableText;
private JTextArea distinctWordArea;
public DistinctWordObserver(EditableText editableText, JTextArea distinctWordArea) {
this.editableText = editableText;
this.distinctWordArea = distinctWordArea;
editableText.registerObserver(this);
}
@Override
public void update() {
String text = editableText.getText();
Set<String> distinctWords = new TreeSet<>(Arrays.asList(text.split("\\s+")));
StringBuilder sb = new StringBuilder();
for (String word : distinctWords) {
sb.append(word).append("\n");
}
distinctWordArea.setText(sb.toString());
}
}
// 按照出现频次降序排序的单词统计区类
public class FrequencyCountObserver implements Observer {
private EditableText editableText;
private JTextArea frequencyCountArea;
public FrequencyCountObserver(EditableText editableText, JTextArea frequencyCountArea) {
this.editableText = editableText;
this.frequencyCountArea = frequencyCountArea;
editableText.registerObserver(this);
}
@Override
public void update() {
String text = editableText.getText();
Map<String, Integer> frequencyMap = new HashMap<>();
for (String word : text.split("\\s+")) {
frequencyMap.put(word, frequencyMap.getOrDefault(word, 0) + 1);
}
List<Map.Entry<String, Integer>> frequencyList = new ArrayList<>(frequencyMap.entrySet());
Collections.sort(frequencyList, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Integer> entry : frequencyList) {
sb.append(entry.getKey()).append(",").append(entry.getValue()).append(")\n");
}
frequencyCountArea.setText(sb.toString());
}
}
最后,我们在主函数中创建可编辑文本区和三个文本信息统计区,将它们关联起来。
public static void main(String[] args) {
EditableText editableText = new EditableText();
JLabel wordCountLabel = new JLabel("单词总数:0");
JLabel charCountLabel = new JLabel("字符总数:0");
JTextArea distinctWordArea = new JTextArea();
JTextArea frequencyCountArea = new JTextArea();
WordAndCharCountObserver wordAndCharCountObserver = new WordAndCharCountObserver(editableText, wordCountLabel, charCountLabel);
DistinctWordObserver distinctWordObserver = new DistinctWordObserver(editableText, distinctWordArea);
FrequencyCountObserver frequencyCountObserver = new FrequencyCountObserver(editableText, frequencyCountArea);
// 省略界面布局代码
editableText.setText("Hello world! This is a sample text.");
}
原文地址: https://www.cveoy.top/t/topic/nz2x 著作权归作者所有。请勿转载和采集!