问题

当我从PetUI类中的actionPerformed函数启动StartGUI主类时,PetUI对话框没有从屏幕上的任何内容开始,但似乎在后台运行。为了进行调试,宠物会在几秒钟内死亡。宠物死亡后,屏幕将更新,您可以看到正确的屏幕,直到您按OK(确定)为止,它将再次加载StartGUI类,以便您可以制作新的宠物并重新开始。

笔记

当我直接从IDE中运行PetUI main时,它将正确加载并执行所有功能,而不会出现错误。

图片:

StartGUI类开始时:

java - GUI未加载,但似乎正在运行-LMLPHP

左边的对话框是StartGUI类,然后右边的对话框是从StartGUI类开始的PetUI类。

宠物死亡后:

java - GUI未加载,但似乎正在运行-LMLPHP

现在宠物已经死了,您可以简单地看到PetUI类已经更新了其对话框,并且可以看到正确显示的内容。

直接从IDE(IntelliJ Idea)运行PetUI
java - GUI未加载,但似乎正在运行-LMLPHP

现在您可以看到它可以正常工作。

代码
PetUI类别:

package vps.main.gui;

import vps.main.Pet;
import vps.util.io;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Created by XXXX on 3/23/2016.
 */
public class PetUI extends JFrame implements ActionListener {
    public static Pet mainPet = new Pet("Unknown Pet", 100, 100, 100, 100);
    static JProgressBar healthBar = new JProgressBar(0, 100);
    static JProgressBar hungerBar = new JProgressBar(0, 100);
    static JProgressBar happinessBar = new JProgressBar(0, 100);
    static JLabel foodCount = new JLabel();
    static JLabel medpackCount = new JLabel();
    static int medpacks = 10;
    static int food = 25;
    static JMenuBar menuBar = new JMenuBar();
    JLabel petInfo = new JLabel("Name:" + mainPet.getName() + " | Age: "+mainPet.getAge());
    JMenu file = new JMenu("File");
    JMenuItem save = new JMenu("Save");
    JButton healButton = new JButton("", new ImageIcon("src\\vps\\files\\ambulanceIcon.png"));
    JButton feedButton = new JButton("", new ImageIcon("src\\vps\\files\\feedIcon.png"));
    JButton playButton = new JButton("", new ImageIcon("src\\vps\\files\\playIcon.png"));
    JButton quitButton = new JButton("", new ImageIcon("src\\vps\\files\\quitIcon.png"));
    JPanel buttons = new JPanel();
    JPanel bars = new JPanel();

    public PetUI() {
        super("Pet UI");
        setLayout(new FlowLayout());
        buttons.add(healButton);
        buttons.add(feedButton);
        buttons.add(playButton);
        buttons.add(quitButton);
        bars.add(healthBar);
        bars.add(hungerBar);
        bars.add(happinessBar);
        happinessBar.setStringPainted(true);
        hungerBar.setStringPainted(true);
        healthBar.setStringPainted(true);
        happinessBar.setString("Happiness");
        hungerBar.setString("Hunger");
        healthBar.setString("Health");
        healButton.setBorderPainted(false);
        healButton.setContentAreaFilled(false);
        healButton.setFocusPainted(false);
        feedButton.setBorderPainted(false);
        feedButton.setContentAreaFilled(false);
        feedButton.setFocusPainted(false);
        playButton.setBorderPainted(false);
        playButton.setContentAreaFilled(false);
        playButton.setFocusPainted(false);
        quitButton.setBorderPainted(false);
        quitButton.setContentAreaFilled(false);
        quitButton.setFocusPainted(false);
        playButton.addActionListener(this);
        healButton.addActionListener(this);
        feedButton.addActionListener(this);
        quitButton.addActionListener(this);
        save.addActionListener(this);
        add(petInfo);
        add(medpackCount);
        add(buttons);
        add(foodCount);
        add(bars);
        menuBar.add(file);
        file.add(save);


    }

    public static int getMedpacks() {
        return medpacks;
    }

    public static void setMedpacks(int medpacks) {
        PetUI.medpacks = medpacks;
    }

    public static void main(String[] args) {
        PetUI p = new PetUI();
        p.setJMenuBar(menuBar);
        p.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        p.setSize(640, 480);
        p.setVisible(true);
        while (true) {
            happinessBar.setValue((int) Math.round(mainPet.getHappiness()));
            healthBar.setValue((int) Math.round(mainPet.getHealth()));
            hungerBar.setValue((int) Math.round(mainPet.getHunger()));
            mainPet.setHappiness(mainPet.getHappiness() - 0.1);
            mainPet.setHunger(mainPet.getHunger() - 0.5);
            //color set
            /**
             * if val greater than 75 = great
             * if val less than 75 = good
             * if val less than 50 = OK
             * if val less than 25 = bad
             * if val less than or equ 0 = dead/horrible
             */

            if (mainPet.getHappiness() > 75) {
                happinessBar.setString("Ecstatic");
                happinessBar.setForeground(Color.green);
            }
            if (mainPet.getHappiness() <= 75) {
                happinessBar.setString("Happy");
                happinessBar.setForeground(Color.magenta);
            }
            if (mainPet.getHappiness() <= 50) {
                happinessBar.setString("OK");
                happinessBar.setForeground(Color.orange);
            }
            if (mainPet.getHappiness() <= 25) {
                happinessBar.setString("Sad");
                happinessBar.setForeground(Color.red);
            }
            if (mainPet.getHappiness() <= 0) {
                happinessBar.setString("Horrible");
                happinessBar.setForeground(Color.black);

            }

            if (mainPet.getHealth() > 75) {
                healthBar.setString("Great");
                healthBar.setForeground(Color.green);
            }
            if (mainPet.getHealth() <= 75) {
                healthBar.setString("Good");
                healthBar.setForeground(Color.magenta);
            }
            if (mainPet.getHealth() <= 50) {
                healthBar.setString("OK");
                healthBar.setForeground(Color.orange);
            }
            if (mainPet.getHealth() <= 25) {
                healthBar.setString("Requires attention");
                healthBar.setForeground(Color.red);
            }
            if (mainPet.getHealth() <= 0) {
                    healthBar.setString("Death");
                    healthBar.setForeground(Color.black);
                    JOptionPane.showMessageDialog(null, "Your pet: " + mainPet.getName() + " has died.");
                p.dispose();
                StartGUI.main(null);
                break;



            }

            if (mainPet.getHunger() > 75) {
                hungerBar.setString("Full");
                hungerBar.setForeground(Color.green);
            }
            if (mainPet.getHunger() <= 75) {
                hungerBar.setString("Great");
                hungerBar.setForeground(Color.magenta);
            }
            if (mainPet.getHunger() <= 50) {
                hungerBar.setString("Hungry");
                hungerBar.setForeground(Color.orange);
            }
            if (mainPet.getHunger() <= 25) {
                hungerBar.setString("Empty");
                hungerBar.setForeground(Color.red);
            }
            if (mainPet.getHunger() <= 0) {
                hungerBar.setString("Starving");
                hungerBar.setForeground(Color.black);
            }


            //death values
            if (mainPet.getHunger() <= 5) {
                mainPet.setHealth(mainPet.getHealth() - 1);
            }
            if (mainPet.getHealth() <= 45) {
                mainPet.setHappiness(mainPet.getHappiness() - 1);
            }

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static int getFood() {
        return food;
    }

    public static void setFood(int food) {
        PetUI.food = food;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == quitButton) {
            int quit = JOptionPane.showConfirmDialog(null, "Are you sure you want to quit?");
            if (quit == 0) {
                System.exit(0);
            } else {
                //do nothing, just stay
            }
        } else if (e.getSource() == feedButton) {
            if (getFood() <= 0) {
                JOptionPane.showMessageDialog(null, "You are out of food.");
            } else if (mainPet.getHunger() > 100) {
                JOptionPane.showMessageDialog(null, "You do not need food right now.");
            } else {
                mainPet.setHunger(mainPet.getHunger() + 20);
                setFood(getFood() - 1);

            }
        } else if (e.getSource() == healButton) {
            if (getMedpacks() <= 0) {
                JOptionPane.showMessageDialog(null, "You are out of medpacks.");
            } else if (mainPet.getHealth() > 100) {
                JOptionPane.showMessageDialog(null, "You do not need a medpack right now.");
            } else {

               if(mainPet.getHealth() + 20 >= 100) {
                   JOptionPane.showMessageDialog(null, "You do not need a medpack right now.");
               }
                else {
                   setMedpacks(getMedpacks() - 1);
               }
            }

        }
        else if(e.getSource() == save) {
            io.replaceMainPet("");
        }

    }
}
StartGUI类别:
package vps.main.gui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import vps.util.io;
import vps.util.io.*;
/**
 * Created by XXX on 3/25/2016.
 */
public class StartGUI extends JFrame implements ActionListener {
    public static String readPath = "";
    static JMenuBar menuBar = new JMenuBar();
    JLabel vpstitle = new JLabel("VPS Alpha 1.2",JLabel.CENTER);
    JMenu fileMenu = new JMenu("File");
    JMenuItem newSave = new JMenuItem("New Save");
    JMenuItem openSave = new JMenuItem("Open Save");
    JButton play = new JButton("Play");
    JButton help = new JButton("Help");

    public StartGUI() {
        super("Startup");
        setLayout(new GridLayout(3,3));
        add(vpstitle);
        add(play);
        add(help);
        play.addActionListener(this);
        menuBar.add(fileMenu);
        fileMenu.add(newSave);
        fileMenu.add(openSave);
        newSave.addActionListener(this);
        openSave.addActionListener(this);
        vpstitle.setFont(new Font ("Segoe Print", Font.BOLD , 72));

    }
    public static void main(String[] args) {
        StartGUI s = new StartGUI();
        s.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        s.setSize(720,480);
        s.setJMenuBar(menuBar);
        s.setVisible(true);
    }

    public static String getReadPath() {
        return readPath;
    }

    public static void setReadPath(String readPath) {
        StartGUI.readPath = readPath;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == play) {
            try {
                if (readPath.equalsIgnoreCase("")) {
                    JOptionPane.showMessageDialog(null, "Please select a save file.\nFile --> Open Save / New Save");

                }
                else {
                    PetUI.main(null);
                }
            }
                catch(NullPointerException n) {
                    JOptionPane.showMessageDialog(null,"You didn't choose a file.");
                }
            }
        else if(e.getSource() == newSave) {
            String saveName = JOptionPane.showInputDialog(null,"Please name this save file:");
            JOptionPane.showMessageDialog(null,"Select your new save directory.");
            JFileChooser jf = new JFileChooser();
            jf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            jf.showOpenDialog(null);
            readPath = jf.getSelectedFile().getAbsolutePath()+"\\"+ saveName+".bin";
            io.write(readPath);
            io.replaceMainPet(readPath);
        } else if (e.getSource() == openSave) {
            JOptionPane.showMessageDialog(null,"Press OK to select your previous save file.");
            JFileChooser jf = new JFileChooser();
            jf.showOpenDialog(null);
            readPath = jf.getSelectedFile().getAbsolutePath();
            io.replaceMainPet(readPath);
        }
        }
    }

最佳答案

将您的游戏循环放入线程中。它正在执行您的游戏逻辑,而不是更新swing gui,这就是为什么您需要将它们拆分的原因。我还建议向Pet.java中添加一个boolean方法作为isAlive(),以便在您的宠物死亡或游戏结束时线程死亡。例如在PetUI.java中:

public static void main(String[] args) {
    PetUI p = new PetUI();
    p.setJMenuBar(menuBar);
    p.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    p.setSize(640, 480);
    p.setVisible(true);
    Thread game = new Thread(new Runnable(){
        public void run() {
            while (true) { // while(mainPet.isAlive())
                happinessBar.setValue((int) Math.round(mainPet.getHappiness()));
                healthBar.setValue((int) Math.round(mainPet.getHealth()));
                hungerBar.setValue((int) Math.round(mainPet.getHunger()));
                mainPet.setHappiness(mainPet.getHappiness() - 0.1);
                mainPet.setHunger(mainPet.getHunger() - 0.5);
                // the rest of your game method
            }
        }
    }
    game.start();
}

09-28 06:03