简体   繁体   中英

Gui program stops after main method executes even if thread is non-daemon

I am a beginner in Java and I appreciate any tips. I was making a simple program that opens a very simple login window and when you enter the correct password (Hello.123), it is supposed to execute a second class that opens another window with a square that can be moved with the arrow keys. I tried executing the second class independently and it worked fine, but when I tried executing it as a part of the main program, it didn´t work. I thought that it was because the second class was executing as a Daemon Thread, so I tried making it a subclass of another class that sets the thread to non-daemon, but that didn´t work either. Is there something I am missing or did I do something wrong? (The code here has the thing to make it non-daemon) Login.java package main;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.Color;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
import main.PostFrameThr.PostFrame;
import main.PostFrameThr;

    public class Login {

public static void main(String[] args) throws IOException {
    
    System.out.println("Initializing main Method");
    
    Border border = BorderFactory.createLineBorder(Color.black,5);
    
    JFrame login = new JFrame();
    login.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    login.setTitle("Login");
    login.setResizable(false);
    login.setSize(600, 500);
    login.setLocation(350, 100);
    login.setVisible(true);
    
    URL url1 = Login.class.getResource("/resources/WindowLogo.png");
    URL url2 = Login.class.getResource("/resources/LoginLogo.png");
    
    ImageIcon logo = new ImageIcon(url1);
    ImageIcon loginico = new ImageIcon(url2);
    login.setIconImage(logo.getImage());
    login.getContentPane().setBackground(Color.gray);
    
    JButton loginButton = new JButton("Login");
    loginButton.setBounds(255, 210, 70, 60);
    login.add(loginButton);
    
    
    JTextField password = new JTextField();
    password.setBounds(190, 180, 200, 20);
    login.add(password);
    
    JLabel logintxt = new JLabel();
    logintxt.setText("Please Enter Your Password");
    logintxt.setIcon(loginico);
    logintxt.setForeground(Color.BLACK);
    logintxt.setSize(10, 10);
    logintxt.setHorizontalTextPosition(JLabel.CENTER);
    logintxt.setVerticalTextPosition(JLabel.TOP);
    logintxt.setFont(new Font("Plain",Font.PLAIN,20));
    logintxt.setBackground(Color.gray);
    logintxt.setOpaque(true);
    logintxt.setBorder(border);
    logintxt.setVerticalAlignment(JLabel.TOP);
    logintxt.setHorizontalAlignment(JLabel.CENTER);
    login.add(logintxt);
    
    SwingUtilities.updateComponentTreeUI(login);
    
    int lock = 1;
    
    if(lock==1) {
        System.out.println("Finished Loading Login Window Components");
        System.out.println("Initializing Login Method");
    }
    
    while(lock==1) {
    
    lock = lock + 1;
    lock = lock - 1;
        
    String passwordtext = password.getText();
    loginButton.addActionListener(new ActionListener() {
        @Override
         public void actionPerformed(ActionEvent e) {
         if(passwordtext.equals("Hello.123")) {
             System.out.println("Login Successfull!");
            // try {
            //Runtime.getRuntime().exec("calc.exe");
            //} catch (IOException e1) {
                // TODO Auto-generated catch block
                //e1.printStackTrace();
            //}
             new PostFrameThr();
             new PostFrame();
             login.dispatchEvent(new WindowEvent(login, WindowEvent.WINDOW_CLOSING));
            }
         }      
       });
      }
    }
  }

PostFrame.java

    package main;

    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import javax.swing.*;
    import java.lang.Thread;

    class PostFrameThr extends Thread {

static void thr() {
    PostFrameThr Thread = new PostFrameThr();
    Thread.setDaemon(false);
    Thread.start();
    new PostFrame();
}
    @SuppressWarnings("serial")
    public static class PostFrame extends JFrame implements KeyListener {
   
    int X = 155;
    int Y = 130;
    int size = 70;
    JLabel label;

PostFrame(){

    this.setTitle("Snake");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.setSize(400, 400);
    this.setLayout(null);
    this.addKeyListener(this);
    this.setLocationRelativeTo(null);
    
    label = new JLabel();
    label.setBounds(X, Y, size, size);
    label.setBackground(Color.black);
    label.setOpaque(true);
    label.setVisible(true);
    
    this.add(label);
    this.setVisible(true);
    
    SwingUtilities.updateComponentTreeUI(this);
    
}



@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    switch(e.getKeyChar()) {
    case 'w' : label.setLocation(label.getX(), label.getY()-5);
      break;
    case 'a' : label.setLocation(label.getX()-5, label.getY());
      break;
    case 's' : label.setLocation(label.getX(), label.getY()+5);
      break;
    case 'd' : label.setLocation(label.getX()+5, label.getY());
    
    
    }
    
}

@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub
    
}

@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
    
}


     }
    }

Swing, like most GUI frameworks, is event driven.

Doing something like...

while (lock == 1) {

    lock = lock + 1;
    lock = lock - 1;

    String passwordtext = password.getText();

is not only incorrect, it's also CPU intensive (not to mention that on each iteration, you're adding a new ActionListener to the button

Instead, just get rid of the loop and when the ActionListener is triggered, get the value from the JTextField

loginButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        String passwordtext = password.getText();
        if (passwordtext.equals("Hello.123")) {
            System.out.println("Login Successfull!");
            new PostFrameThr();
            new PostFrame();
            login.dispose();
        }
    }
});

You'll probably want to take the time to look at:

Oh, and SwingUtilities.updateComponentTreeUI(login); isn't doing what you think is. Instead, move login.setVisible(true); to the end of the main method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM