【问题标题】:Java Swing TextArea: How to simultaneously print Transliterated text/s in an Output TextArea?Java Swing TextArea:如何在输出 TextArea 中同时打印音译文本?
【发布时间】:2019-12-23 11:18:28
【问题描述】:

我正在尝试编写一个文本编辑器。我想要两个 TextArea: 第一个 用于在 unicode 脚本中输入/编辑,第二个 用于同时打印我自己设置的相应罗马脚本 (ASCII) 中的 unicode 脚本输入的输出基于音译方案。 在调用音译方法时,我无法更新并同时打印输出文本区域中的输入文本。当我将输出 textArea 设置为同时打印时,我能感觉到有一点问题,但我无法找出究竟是什么。

编辑器类------->



import java.awt.*;
import java.beans.PropertyChangeSupport;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class editor extends JPanel {
    private static final int ROWS = 10;
    private static final int COLS = 50;
    private static final String[] BUTTON_NAMES = {"विविधाः", "द्वाराणि", "Setting", "Parse", "Compile"};
    private static final int GAP = 3;
    private JTextArea inputTextArea = new JTextArea(ROWS, COLS);
    private JTextArea outputTextArea = new JTextArea(ROWS, COLS);
    private JTextArea TA = new JTextArea(ROWS, COLS);

//calling the transliteration method
    transliterator tr = new transliterator();
    Document asciiDocument=tr.DevanagariTransliteration(inputTextArea.getDocument());

    public editor() throws BadLocationException {
        JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
        for (String btnName : BUTTON_NAMES) {
            buttonPanel.add(new JButton(btnName));
        }

        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(buttonPanel);

        add(putInTitledScrollPane(inputTextArea, "देवनागरी <<<<<<>>>>>> Devanagari"));

        inputTextArea.setFocusable(true);
        outputTextArea.setFocusable(false);
        outputTextArea.setEditable(false);

        //String inputCheck = inputTextArea.getText();
        //inputTextArea.setText("x");
        //if (inputTextArea.getText().length()>0) {


       outputTextArea.setDocument(asciiDocument);//printing input in 2nd textarea
        // outputTextArea.setDocument(inputTextArea.getDocument());//printing input in 2nd textarea


        add(putInTitledScrollPane(outputTextArea, "IndicASCII"));

    }

    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() throws BadLocationException {
        editor mainPanel = new editor();

        JFrame frame = new JFrame("Unicode Editor");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        ImageIcon imgicon = new ImageIcon("MyIcon.jpg");
        frame.setIconImage(imgicon.getImage());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    createAndShowGui();
                } catch (BadLocationException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

及音译类方法:


import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class transliterator {
    //method that returns a Document type
    // the method - importing devanagari text through the type 'Document' from input textArea by call
    public Document DevanagariTransliteration(Document devanagariTextDocument) throws BadLocationException {
        //extracting the devanagari text from the imported Document type
        String asciiText = devanagariTextDocument.getText(0, devanagariTextDocument.getLength());
        //devanagari unicode a replaced by ascii a
        String transliteratedText = asciiText.replace('\u0905', 'a');

        JTextArea jt = new JTextArea();
        //inserting the TRANSLITERATED text to a textArea to extract as a Document again
        jt.setText(transliteratedText);
        //extracting and creating as a document
        Document ASCIITextDocument = jt.getDocument();
        //returning the document
        return ASCIITextDocument;
    }
}

【问题讨论】:

  • 你忘了问问题。
  • 我上面的问题是如何翻译输入文本并同时在输出 textArea 中打印翻译后的文本。当我使用 setDocuement 方法时,我无法处理文本输入。然后只打印我在输入 textArea 中键入的内容。
  • 请edit 这个问题并补充一下,这是它的重要组成部分。无论如何,当然您需要编写一个音译方法,该方法接受一个文档并输出一个音译文档,您将在其他文本区域中设置它。如果您尝试编写这样的方法,请将其添加到问题中并解释您卡在哪里。
  • 点击JButton时是否要音译输入?
  • @c0der 否。我想在输入文本区域的同时打印音译文本。

标签: java swing jtextarea text-editor transliteration


【解决方案1】:

要将一个文档中的更改反映到另一个文档中,您可以按照camickr 的建议使用DocumentListener。
下面是一个mre,它演示了在处理“输入”JTextArea 中的更改后更新“输出”JTextArea。
用于演示目的的处理只是将输入转换为大写。这应该根据您的特定需求进行更改:

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 = process(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();
        }
    }

    private String process(String text) {
        //todo process text as needed
        //returns upper case text for demo
        return text.toUpperCase();
    }

    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());
    }
}

【讨论】:

  • 嗨@c0der,谢谢!有效。这就是我想做的。
  • 出现了问题。当我将每个字母从一个映射到一个时,这非常有效,例如अ = a,आ = A。但是,在某些情况下,我需要从两个 unicode 字符映射到一个 ASCII,例如 क्=k (क्=क+्),我无法处理。因为当我的单个键入键(标准键 k)生成 क् 这个字母实际上由两个 UCode 表示时,文档侦听器算作两个 DocumentEvents。因此,if 条件不能将双代码作为单个字符键来命中/计数。代码如下:
  • private String process(String text) { for(int i=0; i&lt;=asciiText.length()-1;i++){ if(text.charAt(i)=='अ'){ text=text.replace(text.charAt(i),'a'); } else if(text.equals("क")){ if(text.equals("्")) { text = text.replace(text.charAt(i), 'k'); } } } return text; } }
  • 这就是为什么我在评论“您想在单击 JButton 时音译输入”中问的原因。我认为一次处理一个字符可能会出现问题。无论如何,这里的政策是每个帖子一个问题,所以为了帮助处理输入,请发布一个新问题。当你这样做时,请在此处给我留言,我会尽力提供帮助。
【解决方案2】:

当我使用 setDocument() 方法时,我无法处理文本输入

setDocument() 方法所做的只是在多个组件之间共享文档。因此,您输入的任何内容都会显示在两个组件中。

改为使用DocumentListener。每当从 Document 中添加或删除文本时,侦听器都会生成一个事件。然后您需要从文档中读取文本并进行翻译并更新第二个文本区域。

请参阅 How to Write a DocumentListener 上的 Swing 教程部分,了解帮助您入门的基础知识。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多