首页 > 解决方案 > Java Swing TextArea:如何使 JTextArea DocumentListener DocumentEvent 触发两个或多个组合代码/键?

问题描述

我的文本编辑器包含两个 textAreas (TA)。TA1 用于输入梵文 Unicode 文本,TA2 用于以 ASCII 输出为音译文本,当输入文本使用 DocumentListener 逐个键键入时,这些文本会同时打印。我使用一对一的音译方案来做到这一点。但是,在某些情况下,我需要将多个/两个梵文 UCode 输入映射到单个 ASCII 字符中。例如。क्=k (क्=क+्)。这里的问题是通过单个标准键输入 k 生成单个两个包含字符的 UCode。例如。क् 实际上由两个 UCode 表示。然后文档侦听器算作两个 DocumentEvent。因此音译器不能触发也不能生成相应的单个 ASCII 字符。音译类:

import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class MyWindow extends JPanel {

    private static final int ROWS = 10, COLS = 50;

    private final JTextArea outputTextArea;

    public MyWindow() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        JTextArea inputTextArea = new JTextArea(ROWS, COLS);
        inputTextArea.getDocument().addDocumentListener(new TransliterateDocumentListener());
        add(putInTitledScrollPane(inputTextArea, "Input"));

        outputTextArea = new JTextArea(ROWS, COLS);
        outputTextArea.setFocusable(false);
        outputTextArea.setEditable(false);

        add(putInTitledScrollPane(outputTextArea, "Output"));
    }


    private JPanel putInTitledScrollPane(JComponent component, String title) {
        JPanel wrapperPanel = new JPanel(new BorderLayout());
        wrapperPanel.setBorder(BorderFactory.createTitledBorder(title));
        wrapperPanel.add(new JScrollPane(component));
        return wrapperPanel;
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Document Listener Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(new MyWindow());
        frame.pack();
        frame.setVisible(true);
    }


    private void insert(String text, int from) {
        text = Transliterate(text);
        try {
            outputTextArea.getDocument().insertString(from, text, null);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }

    /*================================================================
     *================================================================
     */
    private void remove(int from, int length) {
        try {
            outputTextArea.getDocument().remove(from, length);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }

    //the Transliterator method
    private String Transliterate(String DevanagariText) {
        String asciiText = "";
        //devanagari text is assigned to ascciiText which must be returned
        asciiText = DevanagariText;

        if (asciiText.length() >= 0) {

            for (int i = 0; i <= asciiText.length() - 1; i++) {
                //if input key is Devanagari अ, then it must be replaced by ascii lower a
                if(asciiText.charAt(i)=='अ'){
                    asciiText=asciiText.replace(asciiText.charAt(i),'a');
                }
                //if input key is Devanagari आ or its diacritics ा, then it must be replaced by ascii capital A
                else if(asciiText.charAt(i)=='आ'||asciiText.charAt(i)=='ा'){
                    asciiText=asciiText.replace(asciiText.charAt(i),'A');
                }
                //if input key is Devanagari इ or its diacritics ि, then it must be replaced by ascii lower i
                else if(asciiText.charAt(i)=='इ'||asciiText.charAt(i)=='ि'){
                    asciiText=asciiText.replace(asciiText.charAt(i),'i');
                }
                //All of these above ⇪ codes are producing the target characters
                //===============================================================================
                //if input key is Devanagari क्, then it must be replaced by ascii lower k
                else if(asciiText.equals("क्")){
                    asciiText.replace("क्", "k");
                    // ↓ this is not producing the target/desired character
                    //Because, No. 1. क् has two unicodes क + ्. The ् (halanta) is a diacritic added to 25 such Devanagari...
                    //...consonant letters to represent as a consonant phone. They are ख् ग् घ् ङ् च् छ् ज् झ् etc.
                    //No. 2. क् (क  ्) is produced by only one single standard keyboard key 'k'
                    //however the document listerner counts two keys as it contains two UCodes. And it cannot capture
                    //the moment of the each code since both of the क  ् codes entered through a single key typed.
                }
            }
        }
        return asciiText;
    }
//-----------------------------------document listener
//-------------------------------------------------------

    class TransliterateDocumentListener implements DocumentListener {

        @Override
        public void insertUpdate(DocumentEvent e) {
            Document doc = e.getDocument();
            int from = e.getOffset(), length = e.getLength();
            try {
                insert(doc.getText(from, length), from);
            } catch (BadLocationException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            remove(e.getOffset(), e.getLength());
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            //Plain text components don't fire these events.
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

标签: javaswingunicodekeyboard-shortcutstext-editor

解决方案


推荐阅读