【问题标题】:Troubleshooting Vignere Cipher using JFileChooser and JPasswordField使用 JFileChooser 和 JPasswordField 对 Vignere 密码进行故障排除
【发布时间】:2015-11-19 00:50:17
【问题描述】:

我正在尝试编写一个代码,该代码将使用 JFileChooser 和 JPassword 来获取加密代码或要加密的代码的输入。

这里是要加密的代码“一定要喝你的阿华田!”保存在 .rtf 或 .txt 文件中。关键是“安妮”。输出应该是

"Fv '$zi (# pzm"| (wy& `%ip(zzm%".

我在“密码”项目下有两个不同的类文件。一类称为“文件打开器”。它调用类“Password1”。

这里是 Password1.java。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;

/* PasswordDemo.java requires no other files. */

public class Password1 extends JPanel
                          implements ActionListener {
    private String key;
    private static String OK = "ok";

    private JFrame controllingFrame; //needed for dialogs
    private JPasswordField passwordField;

    public Password1(JFrame f) {
        //Use the default FlowLayout.
        controllingFrame = f;

        //Create everything.
        passwordField = new JPasswordField(10);
        passwordField.setActionCommand(OK);
        passwordField.addActionListener(this);

        JLabel label = new JLabel("Enter the key: ");
        label.setLabelFor(passwordField);

        JComponent buttonPane = createButtonPanel();

        //Lay out everything.
        JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        textPane.add(label);
        textPane.add(passwordField);

        add(textPane);
        add(buttonPane);
    }

    protected JComponent createButtonPanel() {
        JPanel p = new JPanel(new GridLayout(0,1));
        JButton okButton = new JButton("OK");
        okButton.setActionCommand(OK); 
        okButton.addActionListener(this);
        p.add(okButton);
        return p;
    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        controllingFrame.dispose();

        if (OK.equals(cmd)) { //Process the password.
            char[] input = passwordField.getPassword();

            key = new String(input);
            //Zero out the possible password, for security.
            Arrays.fill(input,'0');
            passwordField.selectAll();
            resetFocus();
        } else {
            System.out.println("Please enter a key.");
        }
    }

    public String getKey(){
        return key;
    }

    //Must be called from the event dispatch thread.
    protected void resetFocus() {
        passwordField.requestFocusInWindow();
    }

    public static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("Key");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        final Password1 newContentPane = new Password1(frame);
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Make sure the focus goes to the right component
        //whenever the frame is initially given the focus.
        frame.addWindowListener(new WindowAdapter() {
            public void windowActivated(WindowEvent e) {
                newContentPane.resetFocus();
            }
        });

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                //Turn off metal's use of bold fonts
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        createAndShowGUI();
            }
        });
    }
}

这里是 FileOpener.java。

   import javax.swing.*;
import java.io.*;

import javax.swing.filechooser.*;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;


public class FileOpener extends JPanel implements ActionListener {
    static private final String newline = "\n";
    private Password1 p1;
    JButton decodeButton, encodeButton;
    JFileChooser fc;
    JTextArea log;
    Scanner in = new Scanner(System.in);
    JFrame frame;
    File file;
    int count;

    public FileOpener(){
        // create and set up the window.
        frame = new JFrame("Open Your File");


        // make the program close when the window closes
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create the box layout
        frame.getContentPane( ).setLayout(new BoxLayout(frame.getContentPane( ), BoxLayout.Y_AXIS));

        //label prompting user for input
        JLabel label1 = new JLabel ("Would you like to encode or decode your file?", JLabel.CENTER);
        frame.getContentPane().add(label1);

        //create a filer chooser
        fc = new JFileChooser();

        // add a button object
        decodeButton = new JButton("Decode");
        decodeButton.addActionListener(this);
        frame.getContentPane( ).add(decodeButton);

        encodeButton = new JButton("Encode");
        encodeButton.addActionListener(this);
        frame.getContentPane( ).add(encodeButton);


        // display the window.
        frame.pack( );
        frame.setVisible(true);
    }
    public void actionPerformed(ActionEvent e) {

        //Handle open button action.
        if (e.getSource() == encodeButton) {
             frame.dispose();
            int returnVal = fc.showOpenDialog(FileOpener.this);

            if (returnVal == JFileChooser.APPROVE_OPTION ) {

                try {
                    file = fc.getSelectedFile();
                    p1 = new Password1(frame);
                    p1.createAndShowGUI();
                    //get length of key
                    String key = p1.getKey();
                    int length3 = key.length();
                    count = 0;
                    int keyAsciiValues[] = new int[length3];
                    String name1 ="";
                    //get ascii value of each letter in key
                    for (int k=0; k<length3; k++){
                        char a = key.charAt(k);
                        int ascii1 = (int)a;
                        //put ascii value of letter in key to array
                        keyAsciiValues[k]= ascii1;

                    }

                    FileInputStream file2= new FileInputStream(file);

                    //create a scanner for it
                    in = new Scanner(file2);
                    //read in message
                    String name;
                    name = in.nextLine();
                    for (int k=0; k<length3; k++){
                        char a = key.charAt(k);
                        int ascii1 = (int)a;
                        //put ascii value of letter in key to array
                        keyAsciiValues[k]= ascii1;
                    }
                    //measure length of code message array
                    int length1 = name.length();
                    //measures length of strings in code message array
                    for(int j=0;j<length1;j++){
                        char c = name.charAt(j);
                        int ascii = (int)c;
                        ascii += keyAsciiValues[count];
                        if(c != ' '){
                            count++;
                        }
                        if(count>length3-1){
                            count = 0;
                        }
                        while(ascii>126){
                            ascii-= 93;
                        }
                        char b=(char)ascii;
                        if(c == ' '){
                            b = ' ';
                        }
                        name1 += b;
                    }
                    System.out.println(name1);


                } catch (FileNotFoundException k){
                    //the file was not found!
                    System.out.println("File could not be opened!");
                }
            }

            //Handle save button action.
        } else if (e.getSource() == decodeButton) {
             frame.dispose();
            int returnVal = fc.showOpenDialog(FileOpener.this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {

                try {
                    file = fc.getSelectedFile();
                    p1 = new Password1(frame);
                    p1.createAndShowGUI();
                    //open the file

                    //get length of key 
                    String key = p1.getKey();
                    int length3 = key.length();
                    count = 0;
                    int keyAsciiValues[] = new int[length3];
                    String name1 ="";
                    //get ascii value of each letter in key
                    for (int k=0; k<length3; k++){
                        char a = key.charAt(k);
                        int ascii1 = (int)a;
                        //put ascii value of letter in key to array
                        keyAsciiValues[k]= ascii1;
                    }



                    //create a scanner for it
                    in = new Scanner(file);

                    //read in message
                    String name;
                    name = in.nextLine();
                    for (int k=0; k<length3; k++){
                        char a = key.charAt(k);
                        int ascii1 = (int)a;
                        //put ascii value of letter in key to array
                        keyAsciiValues[k]= ascii1;
                    }
                    //measure length of code message array
                    int length1 = name.length();
                    //measures length of strings in code message array
                    for(int j=0;j<length1;j++){
                        char c = name.charAt(j);
                        int ascii = (int)c;
                        ascii -= keyAsciiValues[count];
                        if(c != ' '){
                            count++;
                        }
                        if(count>length3-1){
                            count = 0;
                        }
                        while(ascii<33){
                            ascii+= 93;
                        }
                        char b=(char)ascii;
                        if(c == ' '){
                            b = ' ';
                        }
                        name1 += b;
                    }
                    System.out.print(name1);


                } catch (FileNotFoundException k){
                    //the file was not found!
                    System.out.println("File could not be opened!");
                }
            }

            in.close(); 

                log.append("Opening: " + file.getName() + "." + newline);
            }
    }


public static void main(String args[]) {
    //Schedule a job for the event dispatch thread:
    //creating and showing this application's GUI.
  FileOpener f = new FileOpener();
}    
}

在我添加 JFileChooser 和密码之前它工作正常,也就是代码的实际加密部分应该没有任何问题。

它在 FileOpener 的第 70 行给了我一个java.lang.NullPointerException

int length3 = key.length();

谢谢!

【问题讨论】:

    标签: java swing user-interface jfilechooser jpasswordfield


    【解决方案1】:

    createAndShowGUI() 方法中,您将Password1 实例显示在JFrame,而不是模态JDialog。因此,该显示指令是非阻塞的,即它不会停止代码执行,也不会等到您单击关闭窗口的按钮。

    因此,您在其actionPerformed() 方法可以执行和初始化key 属性之前检索Password1 实例key,因此key 仍然是null,您会得到一个NullPointerException当您在其上调用任何方法时。

    我的建议是在createAndShowGUI() 中使用模态JDialog 来管理您的Password1 界面(使用JPanel 进行初始化很像您已经在使用JFrame 进行的操作)。这样,当您调用 createAndShowGUI() 时,FileOpener.actionPerformed() 方法的执行将阻塞,直到您完成 Password1 对话框,因此您将确保 key 在您检索并在 FileOpener.actionPerformed() 中使用之前已正确初始化.

    最后一件事:小心frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);!在您的主窗口上使用它是可以的,但是在任何辅助窗口上使用它都会使整个程序在您关闭它后立即完全关闭。但无论如何,setDefaultCloseOperation()JDialog 版本不接受 EXIT_ON_CLOSE 作为有效参数,因此您将仅在您的主 FileOpener 窗口上使用它,这很好。

    【讨论】:

    • 我认为这是一个很好的答案,但是我还没有研究过 JDialog!不过我会做一些研究。非常感谢您回答我的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2011-02-07
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多