import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.DefaultFormatter;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
public class CipherGUI{
public static void main(String args[]){
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {}
JFrame cipherGUIFrame = new CipherGUIFrame();
cipherGUIFrame.setVisible(true);
}
}
class CipherGUIFrame extends JFrame {
public boolean decrypt=true;
public CipherGUIFrame() {
super("Caesar Cipher GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 600);
JTextArea area1 = new JTextArea();
JTextArea area2 = new JTextArea();
JSpinner myspinner=new JSpinner();
JPanel mainframe = new JPanel();
JToggleButton mybutton=new JToggleButton("ENCRYPT");
mainframe.setLayout(new BoxLayout(mainframe, BoxLayout.Y_AXIS));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
p1.setBorder(BorderFactory.createTitledBorder("Cleartext"));
p2.setBorder(BorderFactory.createTitledBorder("KEY"));
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
p3.setBorder(BorderFactory.createTitledBorder("Ciphertext"));
p1.add(area1);
p2.add(myspinner);
p2.add(mybutton);
p3.add(area2);
mainframe.add(p1);
mainframe.add(p2);
mainframe.add(p3);
this.add(mainframe);
ActionListener togglelistener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
boolean selected = abstractButton.getModel().isSelected();
decrypt=selected;
System.out.println("Selected (True or False?): " + selected + "\n");
}
};
mybutton.addActionListener(togglelistener);
//the following chunk of code modifies the component to update when spinner is changed automatically
JComponent comp = myspinner.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
myspinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println("Key spinner changed to: " + myspinner.getValue());
}
});
DocumentListener documentListener = new DocumentListener() {
public void changedUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
public void insertUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
public void removeUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
private void printIt(DocumentEvent documentEvent) {
DocumentEvent.EventType type = documentEvent.getType();
String typeString = null;
if (type.equals(DocumentEvent.EventType.CHANGE)) {
typeString = "(CHANGED KEY) ";
} else if (type.equals(DocumentEvent.EventType.INSERT)) {
typeString = "(PRESSED KEY) ";
} else if (type.equals(DocumentEvent.EventType.REMOVE)) {
typeString = "(DELETED KEY) ";
}
System.out.print("Type : " + typeString);
Document source = documentEvent.getDocument();
int length = source.getLength();
System.out.println("Current size: " + length);
String contents=source.getText(0, length);
System.out.println(contents);
}
};
area1.getDocument().addDocumentListener(documentListener);
area2.getDocument().addDocumentListener(documentListener);
}
public String decipher(String istring, int key){
String decrypted = "";
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;
}
decrypted += (char) c;
}
return(decrypted);
}
public String encipher(String istring, int key){
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);
}
}
这是我目前的代码。如您所见,我使用两个文本区域 - 一个用于加密,另一个用于解密。我希望一个人在其他人的更新后立即更新,反之亦然。
是我遇到问题(并在此处调试)的行 String contents=source.getText(0, length);
线。我试图这样做,以便我可以读取文本区域的内容,只要它被更改为能够通过加密(或解密)方法发送它并将其输出到其他文本区域(我知道如何做) )。 我遇到问题的是它在更改时获取TextArea的内容。有任何想法吗? (忽略KEY CHANGED输出,那些用于测试...)
答案 0 :(得分:0)
Document
s不喜欢在更新时被修改,如果他们抓住你这样做就会抛出异常。
您应该使用的是DocumentFilter
,它可以在将文本应用于Document
之前更改文本,这是引入加密过程的好方法。
我会考虑稍微改变你的过程。而不是允许用户编辑JTextArea
,只允许他们编辑第一个并使用JCheckBox
来表示他们想要去哪个方向(加密/解密),这将大大简化过程...
以下示例使用DocumentFilter
加密输入的文本,但使用DocumentListener
,应用于area1
更新Document
area2
,因为我们没有修改触发事件的Document
,这应该是合理安全的......
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import javax.swing.text.html.HTML;
public class CipherGUI {
public static void main(String[] args) {
new CipherGUI();
}
public CipherGUI() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame cipherGUIFrame = new CipherGUIFrame();
cipherGUIFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cipherGUIFrame.pack();
cipherGUIFrame.setLocationRelativeTo(null);
cipherGUIFrame.setVisible(true);
}
});
}
class CipherGUIFrame extends JFrame {
public boolean decrypt = true;
public CipherGUIFrame() {
super("Caesar Cipher GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 600);
JTextArea area1 = new JTextArea();
JTextArea area2 = new JTextArea();
JSpinner myspinner = new JSpinner();
JPanel mainframe = new JPanel();
JToggleButton mybutton = new JToggleButton("ENCRYPT");
mainframe.setLayout(new BoxLayout(mainframe, BoxLayout.Y_AXIS));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
p1.setBorder(BorderFactory.createTitledBorder("Cleartext"));
p2.setBorder(BorderFactory.createTitledBorder("KEY"));
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
p3.setBorder(BorderFactory.createTitledBorder("Ciphertext"));
p1.add(area1);
p2.add(myspinner);
p2.add(mybutton);
p3.add(area2);
mainframe.add(p1);
mainframe.add(p2);
mainframe.add(p3);
this.add(mainframe);
ActionListener togglelistener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
boolean selected = abstractButton.getModel().isSelected();
decrypt = selected;
System.out.println("Selected (True or False?): " + selected + "\n");
}
};
mybutton.addActionListener(togglelistener);
//the following chunk of code modifies the component to update when spinner is changed automatically
JComponent comp = myspinner.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
myspinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println("Key spinner changed to: " + myspinner.getValue());
EncryptFilter filter = (EncryptFilter) ((AbstractDocument) area2.getDocument()).getDocumentFilter();
filter.setKey((int)myspinner.getValue());
area2.setText(area1.getText());
}
});
((AbstractDocument) area2.getDocument()).setDocumentFilter(new EncryptFilter(0));
area1.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
try {
Document doc = e.getDocument();
String text = doc.getText(e.getOffset(), e.getLength());
Document encryptDoc = area2.getDocument();
encryptDoc.insertString(e.getOffset(), text, null);
} catch (BadLocationException exp) {
exp.printStackTrace();
}
}
@Override
public void removeUpdate(DocumentEvent e) {
try {
Document doc = e.getDocument();
Document encryptDoc = area2.getDocument();
encryptDoc.remove(e.getOffset(), e.getLength());
} catch (BadLocationException exp) {
exp.printStackTrace();
}
}
@Override
public void changedUpdate(DocumentEvent e) {
System.out.println("Changed");
}
});
}
}
public static String decipher(String istring, int key) {
String decrypted = "";
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;
}
}
decrypted += (char) c;
}
return (decrypted);
}
public static String encipher(String istring, int key) {
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 class EncryptFilter extends DocumentFilter {
private int key;
public EncryptFilter(int key) {
this.key = key;
}
public void setKey(int key) {
this.key = key;
}
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
System.out.println("Insert");
text = encipher(text, key);
super.insertString(fb, offset, text, attr);
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
System.out.println("Remove");
super.remove(fb, offset, length);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
text = encipher(text, key);
super.replace(fb, offset, length, text, attrs);
}
}
}
详细了解Implementing a Document Filter和DocumentFilter Examples了解详情