2015-10-10 3 views
0

Моя проблема заключается в моем документеListListerListener. Я не могу понять, как передать текст, который пользователь вводит в один из JTextAreas для моих преобразований и возвращает его другому JTextArea.Проблема с передачей ввода от одного JTextArea в другой JTextArea

Цель программы - ввести введенное пользователем римское или арабское число в одном из полей, преобразовать его и вернуть значение преобразования в другое поле в реальном времени.

Мои графические интерфейсы и методы преобразования работают, я просто не могу обернуть голову вокруг получения этой строки от пользователя и печати ее в режиме реального времени.

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

Вы не должны пытаться сделать преобразование внутри DocumentListener, но должны быть используя DocumentFilter, у меня есть решение для этого, на моей работе ПК: P – MadProgrammer

+0

Это тоже очень сложно, потому что вы хотите, чтобы оба поля могли обновлять каждый из них, заставить его работать, чтобы оставшиеся поля могли обновлять право, T купите, что нужно сделать, чтобы оба обновили друг друга. – MadProgrammer

+0

К сожалению, вы были правы, и я ошибся - пойдите с тем, что рекомендует @MadProgrammer, поверьте мне. –

ответ

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, чтобы получать уведомления об изменениях к Документу просто из-за метода getter/setter для DocumentFilter make легко удалить и восстановить фильтр.

+0

спасибо, что помогли мне очистить что-то. У меня есть другой вопрос, подсказка для этой проблемы говорит мне, что мне нужно использовать JTextAreas, а не JTextFields. как это повлияет на код в приведенном вами примере? – user3712626

+0

@ user3712626, если проблема решена, не забудьте «принять» ответ, чтобы люди знали, что он был решен. 'Я должен использовать JTextAreas, а не JTextFields.' - просто опечатка с моей стороны. Все текстовые компоненты поддерживают DocumentFilter. – camickr

+0

все, кажется, отлично работает с этой методологией, за исключением строки String text = fb.getDocument(). GetText(); который дает мне ошибку «he method getText (int, int) в типе Docutment не применим для аргументов()« – user3712626

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 (имя + ": Заменить:" + ((MirrorDocument) fb.getDocument()) isIgnoreUpdates()). if (encode) { текст = шифровать (текст); } 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); 
    } 

} 

И работоспособный пример, реализованное с использованием предыдущего кода ...

Convert

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

    } 
} 
Смежные вопросы