Несколько JFrames в одном приложении

1

Я все еще изучаю пакет 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.

  • 3
    Избегайте использования null макетов, пиксельные макеты являются иллюзией в современном дизайне пользовательского интерфейса. Есть слишком много факторов, которые влияют на индивидуальный размер компонентов, ни один из которых вы не можете контролировать. Swing был разработан для работы с менеджерами компоновки в ядре, отказ от которых не приведет к концу проблем и проблем, которые вы будете тратить все больше и больше времени, пытаясь исправить
Показать ещё 5 комментариев
Теги:
swing
jframe

1 ответ

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. Вызывающий код возобновится после того, как диалог больше не будет виден.

Другие вопросы:

  • Ваша программа - это не более чем одна большая группа статических полей и методов без истинных классов, которые имеют состояние и поведение. Как будто вы пытаетесь запустить консольную программу в программу, управляемую событиями. Не делай этого. Вместо этого сначала извлеките ненужные объекты GUI, которые понадобятся, и сделайте для них классы. Затем создайте графический интерфейс с истинными нестатистическими методами и полями и в качестве "модели" используйте объекты, не являющиеся GUI.
  • Примеры модальных диалогов:
  • 0
    Используя JDialog, смогу ли я избавиться от всего метода ask() ?
  • 0
    @ user3928546: Это заменит его.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню