如何在按钮点击时打开一个框架

时间:2014-03-12 06:05:35

标签: java jframe jbutton desktop-application

我知道问题的确切位置。当我在Steganography_Controller构造函数中调用FileTransfer方法时,窗口会挂起。当我评论方法调用时,代码运行正常。这是一个有效的代码。

这是我的Steganography_Controller类

public class Steganography_Controller {
// Program Variables
private Steganography_View view;

// Panel Displays
private JPanel decode_panel;
private JPanel encode_panel;

// Panel Variables
private JTextArea input;
private JButton encodeButton, decodeButton;
private JLabel image_input;

// Menu Variables
private JMenuItem encode;
private JMenuItem decode;
private JMenuItem sendfile;
private JMenuItem calculatepsnr;
private JMenuItem exit;

// action event classes
private Encode enc;
private Decode dec;
/*private SendFile send;
private CalculatePSNR psnr;*/
private EncodeButton encButton;
private DecodeButton decButton;

// decode variable
private String stat_path = "";
private String stat_name = "";

// encode variable
private String stegan = "";
private String path = "";

/*
 * Constructor to initialize view, model and environment variables
 * 
 * @param aView A GUI class, to be saved as view
 * 
 * @param aModel A model class, to be saved as model
 */


public  Steganography_Controller(Steganography_View aView) {

    // program variables
    view = aView;
    //model = aModel;

    // assign View Variables
    // 2 views
    encode_panel = view.getTextPanel();
    decode_panel = view.getImagePanel();

    // 2 data options
    input = view.getText();
    image_input = view.getImageInput();

    // 2 buttons
    encodeButton = view.getEButton();
    decodeButton = view.getDButton();

    // menu
    encode = view.getEncode();
    decode = view.getDecode();
    sendfile = view.getSendFile();
    calculatepsnr = view.getPSNR();
    exit = view.getExit();

    // assign action events
    enc = new Encode();
    encode.addActionListener(enc);
    dec = new Decode();
    decode.addActionListener(dec);
    /*send = new SendFile();
    sendfile.addActionListener(send);
    psnr = new CalculatePSNR();
    calculatepsnr.addActionListener(psnr);*/
    exit.addActionListener(new Exit());
    encButton = new EncodeButton();
    encodeButton.addActionListener(encButton);
    decButton = new DecodeButton();
    decodeButton.addActionListener(decButton);

    // encode view as default
    encode_view();

    FileTransfer();  /* <----- Here's what hangs the code.Maybe because i am using socket connection but would like to know the exact problem and solutions if any.*/
}


/*
 * Updates the single panel to display the Encode View.
 */
private void encode_view() {
    update();
    view.setContentPane(encode_panel);
    view.setVisible(true);
}


/*
 * Updates the single panel to display the Decode View.
 */
private void decode_view() {
    update();
    view.setContentPane(decode_panel);
    view.setVisible(true);
}


/*
 * Encode Class - handles the Encode menu item
 */
private class Encode implements ActionListener {
    /*
     * handles the click event
     * 
     * @param e The ActionEvent Object
     */
    public void actionPerformed(ActionEvent e) {
        encode_view(); // show the encode view
    }
}


/*
 * Decode Class - handles the Decode menu item
 */
private class Decode implements ActionListener {
    /*
     * handles the click event
     * 
     * @param e The ActionEvent Object
     */
    public void actionPerformed(ActionEvent e) {
        decode_view(); // show the decode view

        // start path of displayed File Chooser


    }
}


/*
 * Exit Class - handles the Exit menu item
 */
private class Exit implements ActionListener {
    /*
     * handles the click event
     * 
     * @param e The ActionEvent Object
     */
    public void actionPerformed(ActionEvent e) {
        System.exit(0); // exit the program
    }
}


/*
 * Encode Button Class - handles the Encode Button item
 */
private class EncodeButton implements ActionListener {
    /*
     * handles the click event
     * 
     * @param e The ActionEvent Object
     */
    public void actionPerformed(ActionEvent e) {


    }

}


/*
 * Decode Button Class - handles the Decode Button item
 */
private class DecodeButton implements ActionListener {
    /*
     * handles the click event
     * 
     * @param e The ActionEvent Object
     */
    public void actionPerformed(ActionEvent e) {


    }
}

/*
 * Listens to incoming socket connections and receives file
 */
public  void FileTransfer() {

    try {
        System.out.println("Server running...");

        /* Listen on port 1111 */

        ServerSocket server = new ServerSocket(1111);

        /* Accept the sk */

        while (true) {

            Socket sk = server.accept();
            System.out.println("Server accepted client");

            InputStream input = sk.getInputStream();

            BufferedReader inBuf = new BufferedReader(
                    new InputStreamReader(sk.getInputStream()));
            BufferedWriter outBuf = new BufferedWriter(
                    new OutputStreamWriter(sk.getOutputStream()));

            /* Read the filename */

            String filename = inBuf.readLine();

            if (!filename.equals("")) {
                /* Reply back to client with READY status */
                outBuf.write("READY\n");
                outBuf.flush();
            }
            // System.out.println("\nfilename:"+filename);
            /* Create a new file in the tmp directory using the filename */
            String workingDir = System.getProperty("user.dir");
            // System.out.println("Working Dir:"+workingDir);
            String path = workingDir + "\\images\\" + filename;
            System.out.println("serverpath:" + path);


            int filesize = 2022386;
            int bytesRead;
            int currentTot = 0;

            byte[] bytearray = new byte[filesize];
            FileOutputStream fos = new FileOutputStream(new File(path));
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bytesRead = input.read(bytearray, 0, bytearray.length);
            currentTot = bytesRead;

            do {
                bytesRead = input.read(bytearray, currentTot,
                        (bytearray.length - currentTot));
                if (bytesRead >= 0)
                    currentTot += bytesRead;
            } while (bytesRead > -1);

            bos.write(bytearray, 0, currentTot);

            // System.out.println("BYteRECEive:"+bytesReceived);
            input.close();
            fos.close();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void update() {
    input.setText(""); // clear textarea
    image_input.setIcon(null); // clear image
    stat_path = ""; // clear path
    stat_name = ""; // clear name
}

/*
 * Main Method for testing
 */
/*public static void main(String args[]) {
    new Steganography_Controller(new Steganography_View("Steganography"),
            new Steganography());

}*/

}

这是登录类

public class Login extends JDialog {
private JTextField tfUsername;
private JPasswordField tfPassword;
private JLabel lbUsername;
private JLabel lbPassword;
private JButton btnLogin;
private JButton btnCancel;
private JButton btnRegister;
private boolean succeeded;
// Steganography_Controller controller;
final static JFrame frame = new JFrame("JDialog Demo");

public Login(Frame parent) {
    super(parent, "Login", true);

    JDialog dialog = new JDialog();

    JPanel panel = new JPanel(new GridBagLayout());
    GridBagConstraints cs = new GridBagConstraints();

    cs.fill = GridBagConstraints.HORIZONTAL;

    lbUsername = new JLabel("Username: ");
    cs.gridx = 0;
    cs.gridy = 0;
    cs.gridwidth = 1;
    panel.add(lbUsername, cs);

    tfUsername = new JTextField(20);
    cs.gridx = 1;
    cs.gridy = 0;
    cs.gridwidth = 2;
    panel.add(tfUsername, cs);

    lbPassword = new JLabel("Password: ");
    cs.gridx = 0;
    cs.gridy = 1;
    cs.gridwidth = 1;
    panel.add(lbPassword, cs);

    tfPassword = new JPasswordField(20);
    cs.gridx = 1;
    cs.gridy = 1;
    cs.gridwidth = 2;
    panel.add(tfPassword, cs);
    panel.setBorder(new LineBorder(Color.GRAY));

    btnLogin = new JButton("Login");
    btnLogin.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {


                    JOptionPane.showMessageDialog(Login.this,
                            "Hi  ! You have successfully logged in.",
                            "Login", JOptionPane.INFORMATION_MESSAGE);


                    dispose();

                    //Here i need to open my new frame


                     new Steganography_Controller(new
                     Steganography_View("Steganography")
                    );


        }
    });



    JPanel bp = new JPanel();
    bp.add(btnLogin);


    getContentPane().add(panel, BorderLayout.CENTER);
    getContentPane().add(bp, BorderLayout.PAGE_END);

    pack();
    setResizable(false);
    setLocationRelativeTo(parent);

    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

    // setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
}

public String getUsername() {
    return tfUsername.getText().trim();
}

public String getPassword() {
    return new String(tfPassword.getPassword());
}

public boolean isSucceeded() {
    return succeeded;
}

public static void main(String args[]) {

    Login l = new Login(frame);
    l.setVisible(true);
}

}

这是Steganography_View

public class Steganography_View extends JFrame
{
//size variables for window
private static int WIDTH  = 500;
private static int HEIGHT = 400;

//elements for JPanel
private JTextArea   input;
//private JScrollBar    scroll,scroll2;
private JButton     encodeButton,decodeButton;
private JLabel      image_input;

//elements for Menu
private JMenu       file;
private JMenuItem   encode;
private JMenuItem   decode;
private JMenuItem   sendfile;
private JMenuItem calculatepsnr;
private JMenuItem   exit;


/*
 *Constructor for Steganography_View class
 *@param name Used to set the title on the JFrame
 */
public Steganography_View(String name)
{
    //set the title of the JFrame
    super(name);



    //Menubar
    JMenuBar menu = new JMenuBar();

    file = new JMenu("File");   file.setMnemonic('F');
    encode = new JMenuItem("Encode"); encode.setMnemonic('E'); file.add(encode);
    decode = new JMenuItem("Decode"); decode.setMnemonic('D'); file.add(decode);
    sendfile = new JMenuItem("Send File"); sendfile.setMnemonic('S'); file.add(sendfile);
    calculatepsnr = new JMenuItem("Calculate PSNR"); calculatepsnr.setMnemonic('P'); file.add(calculatepsnr);
    file.addSeparator();
    exit = new JMenuItem("Exit"); exit.setMnemonic('x'); file.add(exit);

    menu.add(file);
    setJMenuBar(menu);

    // display rules
    setResizable(true);                     //allow window to be resized: true?false
    setBackground(Color.lightGray);         //background color of window: Color(int,int,int) or Color.name
setLocation(100,100);                   //location on the screen to display window
    setDefaultCloseOperation(EXIT_ON_CLOSE);//what to do on close operation: exit, do_nothing, etc
    setSize(WIDTH,HEIGHT);                  //set the size of the window
    setVisible(true);                       //show the window: true?false
System.out.println("inside steganography_view");

}

/*
 *@return The menu item 'Encode'
 */
public JMenuItem    getEncode()     { return encode;            }
/*
 *@return The menu item 'Send File'
 */
public JMenuItem    getSendFile()       { return sendfile;          }

/*
 *@return The menu item 'Decode'
 */
public JMenuItem    getDecode()     { return decode;            }

/*
 *@return The menu item 'Calculate PSNR'
 */
public JMenuItem    getPSNR()       { return calculatepsnr;         }
/*
 *@return The menu item 'Exit'
 */
public JMenuItem    getExit()       { return exit;              }
/*
 *@return The TextArea containing the text to encode
 */
public JTextArea    getText()       { return input;             }
/*
 *@return The JLabel containing the image to decode text from
 */
public JLabel       getImageInput() { return image_input;       }
/*
 *@return The JPanel displaying the Encode View
 */
public JPanel       getTextPanel()  { return new Text_Panel();  }
/*
 *@return The JPanel displaying the Decode View
 */
public JPanel       getImagePanel() { return new Image_Panel(); }
/*
 *@return The Encode button
 */
public JButton      getEButton()    { return encodeButton;      }
/*
 *@return The Decode button
 */
public JButton      getDButton()    { return decodeButton;      }

private class Text_Panel extends JPanel
{
    /*
     *Constructor to enter text to be encoded
     */
    public Text_Panel()
    {
        //setup GridBagLayout
        GridBagLayout layout = new GridBagLayout(); 
        GridBagConstraints layoutConstraints = new GridBagConstraints(); 
        setLayout(layout);

        input = new JTextArea();
        layoutConstraints.gridx     = 0; layoutConstraints.gridy = 0; 
        layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1; 
        layoutConstraints.fill      = GridBagConstraints.BOTH; 
        layoutConstraints.insets    = new Insets(0,0,0,0); 
        layoutConstraints.anchor    = GridBagConstraints.CENTER; 
        layoutConstraints.weightx   = 1.0; layoutConstraints.weighty = 50.0;
        JScrollPane scroll = new JScrollPane(input,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
        layout.setConstraints(scroll,layoutConstraints);
        scroll.setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
        add(scroll);

        encodeButton = new JButton("Encode Now");
        layoutConstraints.gridx     = 0; layoutConstraints.gridy = 1; 
        layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1; 
        layoutConstraints.fill      = GridBagConstraints.BOTH; 
        layoutConstraints.insets    = new Insets(0,-5,-5,-5); 
        layoutConstraints.anchor    = GridBagConstraints.CENTER; 
        layoutConstraints.weightx   = 1.0; layoutConstraints.weighty = 1.0;
        layout.setConstraints(encodeButton,layoutConstraints);
        add(encodeButton);

        //set basic display
        setBackground(Color.lightGray);
        setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
    }
}

/*
 *Class Image_Panel
 */
private class Image_Panel extends JPanel
{
    /*
     *Constructor for displaying an image to be decoded
     */
    public Image_Panel()
    {
        //setup GridBagLayout
        GridBagLayout layout = new GridBagLayout(); 
        GridBagConstraints layoutConstraints = new GridBagConstraints(); 
        setLayout(layout);

        image_input = new JLabel();
        layoutConstraints.gridx     = 0; layoutConstraints.gridy = 0; 
        layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1; 
        layoutConstraints.fill      = GridBagConstraints.BOTH; 
        layoutConstraints.insets    = new Insets(0,0,0,0); 
        layoutConstraints.anchor    = GridBagConstraints.CENTER; 
        layoutConstraints.weightx   = 1.0; layoutConstraints.weighty = 50.0;
        JScrollPane scroll2 = new JScrollPane(image_input,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
        layout.setConstraints(scroll2,layoutConstraints);
        scroll2.setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
        image_input.setHorizontalAlignment(JLabel.CENTER);
        add(scroll2);

        decodeButton = new JButton("Decode Now");
        layoutConstraints.gridx     = 0; layoutConstraints.gridy = 1; 
        layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1; 
        layoutConstraints.fill      = GridBagConstraints.BOTH; 
        layoutConstraints.insets    = new Insets(0,-5,-5,-5); 
        layoutConstraints.anchor    = GridBagConstraints.CENTER; 
        layoutConstraints.weightx   = 1.0; layoutConstraints.weighty = 1.0;
        layout.setConstraints(decodeButton,layoutConstraints);
        add(decodeButton);

        //set basic display
        setBackground(Color.lightGray);
        setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
    }
 }

1 个答案:

答案 0 :(得分:2)

它挂起的原因是因为当前线程正在侦听传入连接(在事件调度线程中完成),从而阻塞。它不会立即返回,而是等待连接。因此,用于侦听连接的代码应该在它自己的线程中:

而不是FileTransfer(); /* <----- Here's....*/

在自己的主题中运行它:

Thread fileTransferThread = new Thread(new Runnable(){
   public void run(){
        FileTransfer();
   }
});
fileTransferThread.start();