问题描述
我正在使用Java Swing创建用于加密和解密文本的GUI,每个组件/方法都可以正常工作,但是当我尝试用JComboBox替换JTextField时,出现以下错误:线程异常“ AWT-EventQueue-0” java.lang.NullPointerException 在Software.actionPerformed(Software.java:94)
我什至使用Integer数组创建JComboBox,但是当我尝试将ComboBox中选择的数字解析为方法的整数时,它仍然在第94行中给我一个错误。 (这是唯一的错误)
感谢您对此问题的解答!
这是我的代码:
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.util.ArrayList;
import java.awt.Font;
/**
* A class which allows a user to encode and decode caesar ciphers with a GUI
*
*/
/** A JFrame with label,textfield and a button */
public class Software extends JFrame implements ActionListener {
// attributes to store out widgets
private JLabel initial_text;
private JLabel final_text;
private JLabel key;
private JTextField text_field;
private JComboBox key_field;
private JButton encrypt_button;
private JButton decrypt_button;
//Class constructor which instantiates and positions each component
public Software() {
setLayout(null); // turn off the default layout manager
// create components instances
initial_text = new JLabel("Enter text to be encrypted/decrypted:");
final_text = new JLabel("Final text:");
key = new JLabel("Key:");
text_field = new JTextField(100);
//JComboBox Created
Integer[] numbers = new Integer[25];
int inc=1;
for(int i=0;i<25;i++){
numbers[i]= inc;
inc++;
}
JComboBox<Integer> key_field = new JComboBox<>(numbers);
encrypt_button = new JButton("Encrypt");
encrypt_button.setEnabled(true);
encrypt_button.addActionListener(this);
decrypt_button = new JButton("Decrypt");
decrypt_button.setEnabled(true);
decrypt_button.addActionListener(this);
//add the components to the frame
add(initial_text);
add(final_text);
add(key);
add(text_field);
add(key_field);
add(encrypt_button);
add(decrypt_button);
// position the components and size them
initial_text.setBounds(10,20,300,50);
final_text.setBounds(10,150,600,50);
key.setBounds(10,58,50);
text_field.setBounds(250,30,230,30);
key_field.setBounds(35,72,70,25);
encrypt_button.setBounds(320,110,35);
decrypt_button.setBounds(320,35);
}
// main method
public static void main(String[] args) {
Software frame = new Software();
frame.setTitle("Encryption/Decryption Software");
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(200,170,500,250);
frame.setVisible(true);
}
//Handles button press events to encode and decode
public void actionPerformed(ActionEvent e) {
try {
//Gets the text inputted to encrypt or decrypt
String text = this.text_field.getText();
//Converts all characters of string to lower case
text = text.toLowerCase();
//If the button encrypt is pressed
if(e.getActionCommand() == "Encrypt"){
// attempts to parse the user's key as an integer
Integer key = (Integer) key_field.getSelectedItem();
//Uses key to encypt text with method encypt
StringBuffer result = encrypt(text,key);
// Outputs on the GUI the encrypted text
this.final_text.setText("Final text: " + result);
}
else {
//Validate input to reject empty string when decrypt button is pressed
String text1 = text.replaceAll("\\s+","");
if (text1.equals("")) { // Empty string check
JOptionPane.showMessageDialog(this,"In order for the decryption to happen correctly,there HAS to be some text inputted");
}
// If the button decrypt is pressed
else {
// Use the method bruteforce along with text inputted to decrypt
bruteforce(text);
}
}
}
//Validate key input to only accept integers when encrypting
catch(NumberFormatException err) {
JOptionPane.showMessageDialog(this,"In order for the encryption to happen correctly,the key inputted must be an integer");
}
}
// Method that encrypt text using a shift of key (Caesar's Cipher)
public static StringBuffer encrypt(String text,int key) {
StringBuffer result= new StringBuffer();
// Encrypts text using a shift of key
for (int i=0; i<text.length(); i++) {
//Only encrypts letters of the alphabet,allowing all other type of characters to stay the same
if ( !(text.charat(i) >= 'a' && text.charat(i) <= 'z') ) {
result.append(text.charat(i));
}
//Shifts the letter
else {
char ch = (char)(((int)text.charat(i) + key - 97) % 26 + 97);
result.append(ch);
}
}
//returns the encrypted string
return result;
}
//Method that decrypts the text without kNowing the key used (By Brute Force Attack)
public void bruteforce(String text) {
//Converts String texts to an array of chars
char[] ch =text.tochararray();
//Goes through all possibilities (26 different keys Could have been used to encypt)
//Uses every key to decrypt
for(int j=1;j<26;j++) {
for(int i=0;i<ch.length;i++) {
if ( !(ch[i] >= 'a' && ch[i] <= 'z'))
continue;
else {
ch[i] = (char) (ch[i] - j);
if(ch[i] < 'a') {
ch[i] = (char) (ch[i] + 26);
}
}
}
//Outputs on the GUI every possible key used to decrypt and its correspondent original text
//So that the user can read every possibility and figure which was used to encrypt
JOptionPane.showMessageDialog(this,"Key = " + j + " Decrypted String : " + String.valueOf(ch));
ch = text.tochararray();
}
}
}
解决方法
text_field = new JTextField(100);
...
encrypt_button = new JButton("Encrypt");
...
decrypt_button = new JButton("Decrypt");
和:
JComboBox<Integer> key_field = new JComboBox<>(numbers);
建议不要为组合框定义局部变量。
组合框定义为局部变量。
所有其他变量都定义为实例变量。
组合框与上面代码中的所有其他变量有什么区别?
注意,代码:
- 在类顶部定义了一个变量,但该变量为null。
- 在构造函数中创建一个对象的实例,并将其分配给变量,以便可以在整个类中使用它。