![](/img/trans.png)
[英]Demon threads continue to run after main exited and there is some non-daemon thread still running?
[英]Gui program stops after main method executes even if thread is non-daemon
我是 Java 的初学者,我很感激任何提示。 我正在制作一个简单的程序,它打开一个非常简单的登录 window 并且当您输入正确的密码(Hello.123)时,它应该执行第二个 class 打开另一个 window 可以用箭头键移动。 我尝试独立执行第二个 class 并且工作正常,但是当我尝试将它作为主程序的一部分执行时,它没有工作。 我认为这是因为第二个 class 作为守护线程执行,所以我尝试将其设为另一个 class 的子类,将线程设置为非守护线程,但这也不起作用。 有什么我遗漏的还是我做错了什么? (这里的代码使它成为非守护进程)
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 与大多数 GUI 框架一样,是事件驱动的。
做类似...
while (lock == 1) {
lock = lock + 1;
lock = lock - 1;
String passwordtext = password.getText();
不仅不正确,而且占用大量 CPU(更不用说在每次迭代中,您都在向按钮添加一个新的ActionListener
相反,只需摆脱循环,当触发ActionListener
时,从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();
}
}
});
您可能需要花时间看看:
哦,还有SwingUtilities.updateComponentTreeUI(login);
没有按照你的想法做。 相反,移动login.setVisible(true);
到main
方法结束
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.