Reputation: 671
I am still learning Java's Swing package, and I'm making an application that tracks how many frappucinos one has purchased / eaten. I have come to a huge error.
There's a button in the application that, when clicked, will open another JFrame that acts like JavaScript's prompt()
command. I know that this works on its own, before adding the main JFrame this worked perfectly when called in the code.
But when I try to click the button to make the second JFrame, the entire app freezes and proceeds to use up 50% of my RAM. When this occurs, I cannot close the program and have to end it with Task Manager.
Here is my code...
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);
}
}
I added the entire code because I know that adding small bits of it can sometimes not include important features of it.
To clarify, what I need to happen is for the new JFrame to appear when the buttons are clicked. But what really happens is the app freezes and begins to use 50% of my RAM.
If any extra details or clarifications are needed, feel free to post them and I will answer as soon as I see them.
Yes, I have done research in many places, including Stack Overflow, but nothing that I have seen helps, and I don't want a JInternalFrame.
Upvotes: 1
Views: 2149
Reputation: 285430
Here:
// suspend program until button is pushed
// i know, **this is not a very good way of doing it...** (emphasis mine)
while(!askPush){}
as you already know, this "is not a very good way of doing it..."
. It's not only not a very good way, it's a terrible way and will freeze up your Swing event thread and is not how event driven programming should be done. Simply don't do this.
What you want to use instead is a modal dialog such as a JOptionPane or a modal JDialog. This will freeze your calling code at the time of the request while not freezing the Swing event thread. The calling code will resume once the dialog is no longer visible.
Other issues:
Upvotes: 6