Я все еще изучаю пакет Java Swing, и я делаю приложение, которое отслеживает, сколько frappucinos было куплено/съедено. Я пришел к огромной ошибке.
Там есть кнопка в приложении, которая при щелчке откроет другой JFrame, который действует как команда JavaScript prompt()
. Я знаю, что это работает само по себе, прежде чем добавить основной JFrame, это отлично сработало при вызове кода.
Но когда я пытаюсь нажать кнопку, чтобы сделать второй JFrame, все приложение зависает и переходит к использованию 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 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% моей ОЗУ.
Если какие-либо дополнительные подробности или пояснения необходимы, не стесняйтесь публиковать их, и я отвечу, как только увижу их.
Да, я проводил исследования во многих местах, включая Stack Overflow, но ничего, что я видел, помогает, и я не хочу JInternalFrame.
Вот:
// 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. Вызывающий код возобновится после того, как диалог больше не будет виден.
Другие вопросы:
ask()
?
null
макетов, пиксельные макеты являются иллюзией в современном дизайне пользовательского интерфейса. Есть слишком много факторов, которые влияют на индивидуальный размер компонентов, ни один из которых вы не можете контролировать. Swing был разработан для работы с менеджерами компоновки в ядре, отказ от которых не приведет к концу проблем и проблем, которые вы будете тратить все больше и больше времени, пытаясь исправить