Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一个应用程序中有多个JFrame_Java_Swing_Jframe - Fatal编程技术网

Java 一个应用程序中有多个JFrame

Java 一个应用程序中有多个JFrame,java,swing,jframe,Java,Swing,Jframe,我还在学习Java的Swing软件包,我正在制作一个应用程序来跟踪购买/食用了多少frappucinos。我犯了一个很大的错误 应用程序中有一个按钮,单击该按钮将打开另一个JFrame,其行为类似于JavaScript的prompt()命令。我知道这是独立工作的,在添加主JFrame之前,当在代码中调用时,它工作得非常好 但当我试图点击按钮制作第二个JFrame时,整个应用程序冻结,并继续使用我50%的RAM。发生这种情况时,我无法关闭程序,必须使用任务管理器结束它 这是我的密码 import

我还在学习Java的Swing软件包,我正在制作一个应用程序来跟踪购买/食用了多少frappucinos。我犯了一个很大的错误

应用程序中有一个按钮,单击该按钮将打开另一个JFrame,其行为类似于JavaScript的
prompt()
命令。我知道这是独立工作的,在添加主JFrame之前,当在代码中调用时,它工作得非常好

但当我试图点击按钮制作第二个JFrame时,整个应用程序冻结,并继续使用我50%的RAM。发生这种情况时,我无法关闭程序,必须使用任务管理器结束它

这是我的密码

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%的内存

如果需要任何额外的细节或澄清,请随时发布,我会尽快回复

是的,我在很多地方做过研究,包括堆栈溢出,但我所看到的都没有帮助,我不想要JInternalFrame。

这里:

    // suspend program until button is pushed
    // i know, **this is not a very good way of doing it...** (emphasis mine)
    while(!askPush){}
正如您已经知道的,这种
“不是一种很好的方法……”
。这不仅是一种非常好的方式,而且是一种可怕的方式,它会冻结Swing事件线程,而不是事件驱动编程的方式。不要这样做

您想要使用的是一个模态对话框,比如JOptionPane或模态JDialog。这将在请求时冻结调用代码,而不会冻结Swing事件线程。一旦对话框不再可见,调用代码将恢复

其他问题:

  • 您的程序只不过是一大群静态字段和方法,没有具有状态和行为的真正类。这就好像你想把一个控制台程序塞进一个事件驱动的程序。不要这样做。相反,首先提取出需要的非GUI对象,并为它们创建类。然后使用真正的非静态方法和字段创建GUI,并将非GUI对象用作其“模型”
  • 模态对话框示例:
    • 此处:

      正如您已经知道的,这种
      “不是一种很好的方法……”
      。这不仅是一种非常好的方式,而且是一种可怕的方式,它会冻结Swing事件线程,而不是事件驱动编程的方式。不要这样做

      您想要使用的是一个模态对话框,比如JOptionPane或模态JDialog。这将在请求时冻结调用代码,而不会冻结Swing事件线程。一旦对话框不再可见,调用代码将恢复

      其他问题:

      • 您的程序只不过是一大群静态字段和方法,没有具有状态和行为的真正类。这就好像你想把一个控制台程序塞进一个事件驱动的程序。不要这样做。相反,首先提取出需要的非GUI对象,并为它们创建类。然后使用真正的非静态方法和字段创建GUI,并将非GUI对象用作其“模型”
      • 模态对话框示例:

      避免使用
      null
      布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局经理一起工作,丢弃它们将导致无止境的问题,您将花费越来越多的时间来纠正这些问题-这基本上就是HovercraftFullOfEels所说的“我知道这是独立工作的”-这实际上是一个侥幸,可能是因为您在事件调度线程上下文之外调用了此方法。另一方面,按钮在EDT中运行,这就是它不再工作的原因,我要指出为什么它在您之前似乎工作。避免使用
      null
      layouts,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局经理一起工作,丢弃它们将导致无止境的问题,您将花费越来越多的时间来纠正这些问题-这基本上就是HovercraftFullOfEels所说的“我知道这是独立工作的”-这实际上是一个侥幸,可能是因为您在事件调度线程上下文之外调用了此方法。另一方面,按钮在EDT中运行,这就是它不再工作的原因,我要指出为什么它在您之前似乎工作。通过使用JDialog,我是否能够摆脱整个
      ask()
      方法?@user3928546:它将取代它。@user3928546:请查看添加到答案的链接。谢谢,我使用了JInputDialog,程序运行良好!我会升级投票,但我需要达到15级。通过使用JDialog,我是否能够摆脱整个
      ask()
      方法?@user3928546:它将取代它。@user3928546:请查看添加到答案的链接。谢谢,我使用了JInputDialog,程序运行良好!我会投票,但我需要达到15级。