问题
I am trying to write a text editor. I want two TextAreas: 1st one for typing/editing in unicode script and 2nd one for simultaneously printing output of the unicode script input in corresponding Roman Script (ASCII) set by myself on the basis of a transliteration scheme. I am not able to update and simultaneously print the input text in output textarea while I call the transliteration method. I can sense a little bit that there is something wrong while I set the output textArea to print simultaneously but I am unable to find out what exactly is that.
The Editor class------->
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();
}
}
});
}
}
And transliteration class method:
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;
}
}
回答1:
To reflect changes in one document onto another document you can use a DocumentListener
as suggested by camickr.
The following is an mre that demonstrates updating the "output" JTextArea
after processing the changes in the "input" JTextArea
.
The processing used for demonstration purposes is a simply converting the input to upper case. This should be changed to your specific needs :
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());
}
}
回答2:
When I used the setDocument() method I cannot handle the text input
All the setDocument()
method does is share the Document between multiple components. So whatever you type will be displayed in both components.
Instead you would use a DocumentListener
. The listener will generate an event whenever text is added or removed from the Document. Then you will need to read the text from the Document and do your translation and update the second text area.
See the section from the Swing tutorial on How to Write a DocumentListener for the basics to get you started.
来源:https://stackoverflow.com/questions/59454413/java-swing-textarea-how-to-simultaneously-print-transliterated-text-s-in-an-out