Gui 程序在 main 方法执行后停止,即使线程是非守护进程
Gui program stops after main method executes even if thread is non-daemon
我是 Java 的初学者,非常感谢任何提示。我正在制作一个简单的程序,它打开一个非常简单的登录 window,当你输入正确的密码 (Hello.123) 时,它应该执行第二个 class 打开另一个 window带有一个可以用箭头键移动的正方形。我尝试独立执行第二个 class 并且它工作正常,但是当我尝试将它作为主程序的一部分执行时,它不起作用。我认为这是因为第二个 class 作为守护线程执行,所以我尝试将其设为另一个 class 的子 class ,将线程设置为非守护进程,但是也没有用。有什么我想念的或者我做错了什么吗? (这里的代码使它成为非守护进程)
Login.java
主包;
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
}
}
}
与大多数 GUI 框架一样,Swing 是事件驱动的。
做类似...
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();
}
}
});
您可能想花时间看看:
- Laying Out Components Within a Container(你 UI 我的系统出了问题)
- Creating a GUI With Swing
- How to Write an Action Listener
哦,SwingUtilities.updateComponentTreeUI(login);
并没有按照您认为的那样去做。相反,将 login.setVisible(true);
移动到 main
方法的末尾
我是 Java 的初学者,非常感谢任何提示。我正在制作一个简单的程序,它打开一个非常简单的登录 window,当你输入正确的密码 (Hello.123) 时,它应该执行第二个 class 打开另一个 window带有一个可以用箭头键移动的正方形。我尝试独立执行第二个 class 并且它工作正常,但是当我尝试将它作为主程序的一部分执行时,它不起作用。我认为这是因为第二个 class 作为守护线程执行,所以我尝试将其设为另一个 class 的子 class ,将线程设置为非守护进程,但是也没有用。有什么我想念的或者我做错了什么吗? (这里的代码使它成为非守护进程) Login.java 主包;
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
}
}
}
与大多数 GUI 框架一样,Swing 是事件驱动的。
做类似...
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();
}
}
});
您可能想花时间看看:
- Laying Out Components Within a Container(你 UI 我的系统出了问题)
- Creating a GUI With Swing
- How to Write an Action Listener
哦,SwingUtilities.updateComponentTreeUI(login);
并没有按照您认为的那样去做。相反,将 login.setVisible(true);
移动到 main
方法的末尾