我的问题在于我的DocumentLister AreaListener。我似乎无法弄清楚如何传入用户为我的转换输入JTextAreas之一的文本并将其返回到其他JTextArea。
该计划的目标是在其中一个字段中输入用户输入的罗马字母或阿拉伯数字,转换它并实时将转换的值返回到另一个字段。
我的GUI和转换方法有效,我似乎无法绕过从用户那里获取该字符串并实时打印它。
public class ArabicToRomanGUI_Hard extends JFrame
{
private static final long serialVersionUID = 1L;
JPanel panel = new JPanel();
//constructor to add text fields to frame
public ArabicToRomanGUI_Hard()
{
JTextArea left = new JTextArea(10, 20);
JTextArea right = new JTextArea(10, 20);
setLayout(new GridLayout(1, 2));
add(new JScrollPane(left));
add(new JScrollPane(right));
MirrorDocument leftDoc = new MirrorDocument();
MirrorDocument rightDoc = new MirrorDocument();
left.setDocument(leftDoc);
right.setDocument(rightDoc);
leftDoc.addDocumentListener(new DocumentHandler(rightDoc));
rightDoc.addDocumentListener(new DocumentHandler(leftDoc));
leftDoc.getDocument().addDocumentListener(AreaListener);
rightDoc.getDocument().addDocumentListener(AreaListener);
}
DocumentListener listener = new DocumentListener()
public class AreaListener implements DocumentListener
{
//DocumentListener listener = new DocumentListener()
@Override
public void changedUpdate(DocumentEvent e)
{
convertInput();
}
@Override
public void insertUpdate(DocumentEvent e)
{
convertInput();
}
@Override
public void removeUpdate(DocumentEvent e)
{
convertInput();
}
private void convertInput(DocumentEvent e)
{
boolean arabicEntered = false;
boolean romanEntered = false;
for (char ch : userInputtedText.toCharArray())
{
if(Character.isLetter(ch))
{
romanEntered = true;
}
if(Character.isDigit(ch))
{
arabicEntered = true;
}
}
if(romanEntered = true)
{
if(ConversionLogic_Hard.getCheckFail() == false)
{
ConversionLogic_Hard.ConvertFromRomanToArabic(userInputtedText); //converts String of RomanNumerals to an arabic int
String arabicNumberAsString = ConversionLogic_Hard.getConvertedRomanNumeral(); //converts number from int to string
}
}
if(arabicEntered == true)
{
if(ConversionLogic_Hard.getCheckFail() == false)
{
ConversionLogic_Hard.ConvertFromArabicToRoman(userInputtedText); //converts String arabicNumberal to String roman numberal
String romanNumberalAsString = ConversionLogic_Hard.getConvertedRomanNumeral(); //gets romanNumberal as String
}
}
}//end convertInput
}//end AreaListener
//creates a flag to test the state of the TextArea
public class MirrorDocument extends PlainDocument
{
private boolean ignoreUpdatedText;
public void setIgnoreUpdates(boolean ignoreUpdatesText)
{
this.ignoreUpdatedText = ignoreUpdatesText;
}
public boolean isIgnoreUpdates()
{
return ignoreUpdatedText;
}
}
//when an event occurs checks the ignoreUpdatedText flag of the document to check if it is false.
//then sets the flag in the checkdocument to true to prevent the document listener from processing any new events.
//then updates the checkdocument.
public static class DocumentHandler implements DocumentListener
{
private MirrorDocument checkDocument;
private boolean ignoreUpdatedText = false;
private JTextArea leftdoc, rightdoc;
boolean arabicEntered = false;
boolean romanEntered = false;
public DocumentHandler(MirrorDocument checkDocument)
{
this.checkDocument = checkDocument;
}
@Override
public void removeUpdate(DocumentEvent e)
{
Document doc = e.getDocument();
if (doc instanceof MirrorDocument)
{
MirrorDocument mirrordoc = (MirrorDocument) doc;
if (!mirrordoc.isIgnoreUpdates())
{
try
{
checkDocument.setIgnoreUpdates(true);
checkDocument.remove(e.getOffset(), e.getLength());
}
catch (BadLocationException exc)
{
exc.printStackTrace();
}
finally
{
checkDocument.setIgnoreUpdates(false);
}
}
}
}//End removeUpdate
@Override
public void changedUpdate(DocumentEvent e)
{
//NOT USED
}
@Override
public void insertUpdate(DocumentEvent e)
{
Document doc = e.getDocument();
if (doc instanceof MirrorDocument)
{
MirrorDocument mirrordoc = (MirrorDocument) doc;
if( !mirrordoc.isIgnoreUpdates())
{
try
{
String textInput = e.getDocument().getText(e.getOffset(), e.getLength());
checkDocument.setIgnoreUpdates(true);
checkDocument.insertString(e.getOffset(), textInput, null);
}
catch(BadLocationException exc)
{
exc.printStackTrace();
}
finally
{
checkDocument.setIgnoreUpdates(false);
}
}
}
}//End insertUpdate
}
}//class
答案 0 :(得分:1)
您可以使用DocumentFilter
来监听更改。
创建DocumentFilter
时,您可以指定要使用转换后的文本进行更新的文本字段。
使用此方法,您可以在设置文本之前从文本字段中删除DocumentFilter
,以避免两个文本字段的递归尝试相互更新。
过滤器可能类似于:
import javax.swing.*;
import javax.swing.text.*;
import java.awt.Toolkit;
public class ConversionFilter extends DocumentFilter
{
private boolean arabic;
private JTextField converted;
public ConversionFilter(boolean arabic, JTextField converted)
{
this.arabic = arabic;
this.converted = converted;
}
@Override
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
throws BadLocationException
{
super.insertString(fb, offs, str, a);
convertInput(fb);
}
@Override
public void replace(final FilterBypass fb, final int offs, final int length, final String str, final AttributeSet a)
throws BadLocationException
{
super.replace(fb, offs, length, str, a);
convertInput(fb);
}
@Override
public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
throws BadLocationException
{
super.remove(fb, offset, length);
convertInput(fb);
}
private void convertInput(DocumentFilter.FilterBypass fb)
{
// Remove the DocumentFilter from the text field to be converted
AbstractDocument document = (AbstractDocument)converted.getDocument();
DocumentFilter df = document.getDocumentFilter();
document.setDocumentFilter( null );
// Do the conversion and update the text field
String text = fb.getDocument().getText();
String convertedText = arabic ? convertToRoman(text) : convertToArabic(text);
converted.setText( convertedText );
// Restore the DocumentFilter on the converted text field
document.setDocumentFilter( df );
}
}
然后使用过滤器代码可能类似于:
JTextField arabicTextField = new JTextField(...);
JTextField romanTextField = new JTextField(...);
AbstractDocument arabicDocument = (AbstractDocument)arabicTextField.getDocument();
arabicDocument.setDocumentFilter( new ConversonFilter(true, romanTextField) );
AbstractDocument romanDocument = (AbstractDocument)romanTextField.getDocument();
romanDocument.setDocumentFilter( new ConversonFilter(false, arabicTextField) );
我使用DocumentFilter而不是DocumentListener来通知Document的更改只是因为DocumentFilter make的getter / setter方法很容易删除和恢复过滤器。
答案 1 :(得分:0)
根据您之前提出的问题https://stackoverflow.com/questions/33091530/why-doesnt-my-java-program-print-this-out,这是我提出的用于处理双向编辑要求的DocumentFilter
。
此代码只是对文本进行编码/解码,但通常无论你在哪个字段
public class EncodeFilter extends DocumentFilter {
private String name;
private boolean encode;
public EncodeFilter(String name, boolean encode) {
this.name = name;
this.encode = encode;
}
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
System.out.println(name + ": Insert: " + ((MirrorDocument)fb.getDocument()).isIgnoreUpdates());
if (((MirrorDocument)fb.getDocument()).isIgnoreUpdates()) {
System.out.println("Encode = " + encode + " " + text);
text = encode ? encipher(text) : decipher(text);
}
super.insertString(fb, offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
// System.out.println(name + ": Replace: " + ((MirrorDocument)fb.getDocument()).isIgnoreUpdates());
if (encode) {
text = encipher(text);
}
super.replace(fb, offset, length, text, attrs);
}
public String encipher(String istring) {
int key = 1;
String encrypted = "";
for (int i = 0; i < istring.length(); i++) {
int c = istring.charAt(i);
if (Character.isUpperCase(c)) {
c = c - (key % 26);
if (c < 'A') {
c = c + 26;
}
} else if (Character.isLowerCase(c)) {
c = c - (key % 26);
if (c < 'a') {
c = c + 26;
}
}
encrypted += (char) c;
}
return (encrypted);
}
public String decipher(String istring) {
String decrypted = "";
int key = 1;
for (int i = 0; i < istring.length(); i++) {
int c = istring.charAt(i);
if (Character.isUpperCase(c)) {
c = c + (key % 26);
if (c > 'Z') {
c = c - 26;
}
} else if (Character.isLowerCase(c)) {
c = c + (key % 26);
if (c > 'z') {
c = c - 26;
}
}
decrypted += (char) c;
}
return (decrypted);
}
}
一个可运行的例子,使用前面的代码实现...
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;
public class MirrorTextAreas {
public static void main(String[] args) {
new MirrorTextAreas();
}
public MirrorTextAreas() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTextArea left = new JTextArea(10, 20);
JTextArea right = new JTextArea(10, 20);
setLayout(new GridLayout(1, 2));
add(new JScrollPane(left));
add(new JScrollPane(right));
MirrorDocument leftDoc = new MirrorDocument();
MirrorDocument rightDoc = new MirrorDocument();
rightDoc.setDocumentFilter(new EncodeFilter("Right", true));
leftDoc.setDocumentFilter(new EncodeFilter("Left", false));
left.setDocument(leftDoc);
right.setDocument(rightDoc);
leftDoc.addDocumentListener(new DocumentHandler(rightDoc));
rightDoc.addDocumentListener(new DocumentHandler(leftDoc));
}
}
public class MirrorDocument extends PlainDocument {
private boolean ignoreUpdates;
public void setIgnoreUpdates(boolean ignoreUpdates) {
this.ignoreUpdates = ignoreUpdates;
}
public boolean isIgnoreUpdates() {
return ignoreUpdates;
}
}
public static class DocumentHandler implements DocumentListener {
private MirrorDocument slaveDocument;
private boolean ignoreUpdates = false;
public DocumentHandler(MirrorDocument slaveDocument) {
this.slaveDocument = slaveDocument;
}
@Override
public void insertUpdate(DocumentEvent e) {
Document doc = e.getDocument();
if (doc instanceof MirrorDocument) {
MirrorDocument md = (MirrorDocument) doc;
if (!md.isIgnoreUpdates()) {
try {
String text = e.getDocument().getText(e.getOffset(), e.getLength());
slaveDocument.setIgnoreUpdates(true);
slaveDocument.insertString(e.getOffset(), text, null);
} catch (BadLocationException ex) {
ex.printStackTrace();
} finally {
slaveDocument.setIgnoreUpdates(false);
}
}
}
}
@Override
public void removeUpdate(DocumentEvent e) {
Document doc = e.getDocument();
if (doc instanceof MirrorDocument) {
MirrorDocument md = (MirrorDocument) doc;
if (!md.isIgnoreUpdates()) {
try {
slaveDocument.setIgnoreUpdates(true);
slaveDocument.remove(e.getOffset(), e.getLength());
} catch (BadLocationException ex) {
ex.printStackTrace();
} finally {
slaveDocument.setIgnoreUpdates(false);
}
}
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
}
public class EncodeFilter extends DocumentFilter {
private String name;
private boolean encode;
public EncodeFilter(String name, boolean encode) {
this.name = name;
this.encode = encode;
}
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
System.out.println(name + ": Insert: " + ((MirrorDocument)fb.getDocument()).isIgnoreUpdates());
if (((MirrorDocument)fb.getDocument()).isIgnoreUpdates()) {
System.out.println("Encode = " + encode + " " + text);
text = encode ? encipher(text) : decipher(text);
}
super.insertString(fb, offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
// System.out.println(name + ": Replace: " + ((MirrorDocument)fb.getDocument()).isIgnoreUpdates());
if (encode) {
text = encipher(text);
}
super.replace(fb, offset, length, text, attrs);
}
public String encipher(String istring) {
int key = 1;
String encrypted = "";
for (int i = 0; i < istring.length(); i++) {
int c = istring.charAt(i);
if (Character.isUpperCase(c)) {
c = c - (key % 26);
if (c < 'A') {
c = c + 26;
}
} else if (Character.isLowerCase(c)) {
c = c - (key % 26);
if (c < 'a') {
c = c + 26;
}
}
encrypted += (char) c;
}
return (encrypted);
}
public String decipher(String istring) {
String decrypted = "";
int key = 1;
for (int i = 0; i < istring.length(); i++) {
int c = istring.charAt(i);
if (Character.isUpperCase(c)) {
c = c + (key % 26);
if (c > 'Z') {
c = c - 26;
}
} else if (Character.isLowerCase(c)) {
c = c + (key % 26);
if (c > 'z') {
c = c - 26;
}
}
decrypted += (char) c;
}
return (decrypted);
}
}
}