我还在学习Java的Swing软件包,而且我正在创建一个应用程序,用于跟踪已购买/吃过多少frappucinos。我遇到了一个巨大的错误。
应用程序中有一个按钮,当单击该按钮时,将打开另一个充当JavaScript prompt()
命令的JFrame。我知道这是有效的,在添加主JFrame之前,这在代码中调用时非常有效。
但是当我尝试点击按钮制作第二个JFrame时,整个应用程序冻结并继续占用我的RAM的50%。发生这种情况时,我无法关闭程序,必须使用任务管理器结束它。
这是我的代码......
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.nio.file.*;
class Frappucinos{
//initialize the main window
public static JFrame window;
// initializing values for ask()
private static String inValue;
private static boolean askPush = false;
// popup asking box, like JavaScript's prompt()
private static String ask(String message){
// setup frame
JFrame askPane = new JFrame("Frappucinos");
askPane.setLayout(null);
askPane.setBounds(150, 100, 300, 200);
// setup question label
JLabel askText = new JLabel(
message,
SwingConstants.CENTER
);
askText.setBounds(0, 25, 300, 25);
// setup input field
JTextField askType = new JTextField(25);
askType.setBounds(50, 75, 200, 25);
// setup button
JButton askButn = new JButton("Submit");
askButn.setBounds(100, 125, 100, 25);
// add elements to frame
askPane.add(askText);
askPane.add(askType);
askPane.add(askButn);
// make buttons click event
askButn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
// set variable to content of the textfield
inValue = askType.getText();
// tell program button has been pushed
askPush = true;
//hide window
askPane.setVisible(false);
}
});
// set size of window and make it visible
askPane.setMinimumSize(new Dimension(300, 200));
askPane.setPreferredSize(new Dimension(300, 200));
askPane.setMaximumSize(new Dimension(300, 200));
askPane.setLocationRelativeTo(null);
askPane.setVisible(true);
// tell program button hasn't been pushed yet
askPush = false;
// suspend program until button is pushed
// i know, this is not a very good way of doing it...
while(!askPush){}
// return the value
return inValue;
}
// initializing frapp eating variables
public static String obtaining;
public static String eating;
public static Integer obtained;
public static Float eaten;
public static String buyAmount;
public static String eatAmount;
public static Integer eatInt;
// writing to files
public static void fileWrite(String fPath, String fContent){
FileOutputStream fileOut;
try{
fileOut = new FileOutputStream(fPath);
new PrintStream(fileOut).println(fContent);
fileOut.close();
}catch(IOException e){
System.out.println(" Unable to write to file " + fPath);
System.exit(0);
}
}
public static void main(String[] args){
// set file path
Path file = Paths.get("bought.txt");
try{
// create the file
Files.createFile(file);
// if it already exists
}catch(FileAlreadyExistsException x){
System.out.println(" File bought.txt already exists");
}catch(IOException x){
// if theres an error
System.out.println(" Error making file bought.txt:");
System.out.println(x);
}
// make an input stream
FileInputStream fileIn;
try{
// the input file stream ready
fileIn = new FileInputStream("bought.txt");
// read a line
obtaining = new DataInputStream(fileIn).readLine();
// if line is blank
if(obtaining == null){
// make variable 0
obtaining = "0";
}
// close the file
fileIn.close();
// errors
}catch(IOException e){
System.out.println(" Unable to read from file bought.txt");
// make variable 0
obtaining = "0";
}
// set file path
file = Paths.get("eaten.txt");
try{
// make the file
Files.createFile(file);
// if already there
}catch(FileAlreadyExistsException x){
System.out.println(" File eaten.txt already exists.");
// if errors
}catch(IOException x){
System.out.println(" Error making file eaten.txt:");
System.out.println(x);
}
try{
// set file input stream to new file
fileIn = new FileInputStream("eaten.txt");
// set variable to line in file
eating = new DataInputStream(fileIn).readLine();
// if blank then make it 0.0
if(eating == null){
eating = "0.0";
}
// close that file
fileIn.close();
// if theres an error
}catch(IOException e){
// do the same stuff as all the other ones did...
System.out.println(" Unable to read from file eaten.txt");
eating = "0";
}
obtained = Integer.valueOf(obtaining);
eaten = Float.parseFloat(eating);
window = new JFrame("Frappucinos");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton buyFrapp = new JButton("Bought a Frapp");
JButton eatFrapp = new JButton("Drank some Frapp");
JLabel frappDet = new JLabel("Loading...", SwingConstants.CENTER);
window.setLayout(null);
window.setBounds( 0, 0, 600, 500);
buyFrapp.setBounds( 25, 25, 100, 25);
eatFrapp.setBounds(475, 25, 100, 25);
frappDet.setBounds( 0, 75, 600, 425);
buyFrapp.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
buyAmount = ask("How many frappucinos have you bought?");
obtained = obtained + Integer.parseInt(buyAmount);
fileWrite("bought.txt", "" + obtained);
}
});
eatFrapp.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
eatAmount = ask("What percentage of a frappucino have you eaten (without % sign)");
eatInt = Integer.parseInt(eatAmount);
if(eatInt > 99){
eaten = eaten + Float.parseFloat("" + eatInt / 100 + "." + (eatInt - ((eatInt / 100) * 100)));
}else if(eatInt > 9){
eaten = eaten + Float.parseFloat("0.0" + eatAmount);
}else{
eaten = eaten + Float.parseFloat("0." + eatAmount);
}
fileWrite("eaten.txt", "" + eaten);
}
});
window.add(buyFrapp);
window.add(eatFrapp);
window.add(frappDet);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
}
我添加了整个代码,因为我知道添加一小部分代码有时候不会包含它的重要功能。
为了澄清,我需要做的是在点击按钮时出现新的JFrame。但真正发生的是应用冻结并开始使用50%的RAM。
如果需要任何额外的细节或说明,请随时发布,我会尽快回答。
是的,我已经在许多地方进行了研究,包括Stack Overflow,但我见过的任何内容都没有帮助,而且我也不想要JInternalFrame。
答案 0 :(得分:6)
下面:
// suspend program until button is pushed
// i know, **this is not a very good way of doing it...** (emphasis mine)
while(!askPush){}
正如您所知,这是"is not a very good way of doing it..."
。它不仅是不是一种非常好的方式,它是一种可怕的方式,并且会冻结你的Swing事件线程,而不是事件驱动编程应该如何完成。根本不要这样做。
您想要使用的是模态对话框,例如JOptionPane或模态JDialog。这将在请求时冻结您的调用代码,同时不冻结Swing事件线程。一旦对话框不再可见,调用代码将恢复。
其他问题: