首先,我们需要定义观察者接口和主题接口。

// 观察者接口
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.");
}
Java Observer 模式实现文本编辑器统计功能

原文地址: https://www.cveoy.top/t/topic/nz2x 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录