无法从其他班级呼叫 JPanel



我试图为我的Java类创建一个Hangman游戏,并且正在努力使每个类一起工作。在这种情况下,我试图将我的短语从 selectPhrase 方法写入主面板。我对编程非常陌生,所以任何帮助将不胜感激。谢谢

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
 * Created by Alex on 4/22/2016.
 */
``public class HangmanGame extends JFrame implements ActionListener {
    public HangmanGame() {
        JPanel lettersPanel = new JPanel(new GridLayout(5,8,5,5));
        JButton jbtA = new JButton("A");
        JButton jbtB = new JButton("B");
        JButton jbtC = new JButton("C");
        JButton jbtD = new JButton("D");
        JButton jbtE = new JButton("E");
        JButton jbtF = new JButton("F");
        JButton jbtG = new JButton("G");
        JButton jbtH = new JButton("H");
        JButton jbtI = new JButton("I");
        JButton jbtJ = new JButton("J");
        JButton jbtK = new JButton("K");
        JButton jbtL = new JButton("L");
        JButton jbtM = new JButton("M");
        JButton jbtN = new JButton("N");
        JButton jbtO = new JButton("O");
        JButton jbtP = new JButton("P");
        JButton jbtQ = new JButton("Q");
        JButton jbtR = new JButton("R");
        JButton jbtS = new JButton("S");
        JButton jbtT = new JButton("T");
        JButton jbtU = new JButton("U");
        JButton jbtV = new JButton("V");
        JButton jbtW = new JButton("W");
        JButton jbtX = new JButton("X");
        JButton jbtY = new JButton("Y");
        JButton jbtZ = new JButton("Z");
        lettersPanel.add(jbtA);
        lettersPanel.add(jbtB);
        lettersPanel.add(jbtC);
        lettersPanel.add(jbtD);
        lettersPanel.add(jbtE);
        lettersPanel.add(jbtF);
        lettersPanel.add(jbtG);
        lettersPanel.add(jbtH);
        lettersPanel.add(jbtI);
        lettersPanel.add(jbtJ);
        lettersPanel.add(jbtK);
        lettersPanel.add(jbtL);
        lettersPanel.add(jbtM);
        lettersPanel.add(jbtN);
        lettersPanel.add(jbtO);
        lettersPanel.add(jbtP);
        lettersPanel.add(jbtQ);
        lettersPanel.add(jbtR);
        lettersPanel.add(jbtS);
        lettersPanel.add(jbtT);
        lettersPanel.add(jbtU);
        lettersPanel.add(jbtV);
        lettersPanel.add(jbtW);
        lettersPanel.add(jbtX);
        lettersPanel.add(jbtY);
        lettersPanel.add(jbtZ);
        JPanel mainPanel = new JPanel(new BorderLayout());
        setLayout(new GridLayout(2,2,5,5));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        mainPanel.add(lettersPanel, BorderLayout.EAST);
        mainPanel.setBackground(Color.BLACK);
        //mainPanel.add()

        add(mainPanel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        JFrame frame = new HangmanGame();
        frame.add(new HangmanGraphics());
        frame.setTitle("Hangman");
        frame.setSize(1020, 800);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setResizable(false);

    }
     static String selectPhrase()
    {
        String currentGuess = "*";
        int[] previousValues = new int[5];
        int totalRounds = 0;
        //set isValid equal to false and creates a random number between 1 and 6
        //(between 1 and 6 because previousValues is used to store the old numbers,
        //and if between 0 and 5 were used, 0 would trip every time because an uninitialized
        //array has 0's (null) in every position)
        boolean isValid = false;
        int index = (int)(Math.random() * 5 + 1);
        //enters loop because isValid is false, so !isValid is true
        while(!isValid)
        {
            //sets isValid equal to true, so if it never gets changed during the loop, it will exit next time around
            isValid = true;
            for(int i = 0; i < totalRounds; i++)
            {
                //if the randomly generated value is one of the previous ones, make isValid false
                if(index == previousValues[i])
                {
                    isValid = false;
                }
            }
            //if isValid is false, create a new random number between 1 and 6
            if(!isValid)
            {
                index = (int)(Math.random() * 5 + 1);
            }
        }
        //once a value that's never been used before is created, save it in previousValues
        //so that it is not used again
        previousValues[totalRounds] = index;
        totalRounds++;
        //return phrase at the index of the random number
        String[] phrase = {"NULL", "Go Team", "Hello World" , "Java Rocks", "Bread Bowl" , "Soup"};
        return phrase[index];

        for( int i=0; i<phrase.length; i++) {
            currentGuess = currentGuess.concat("?");
        }
        .setText( currentGuess );
    }
    @Override
    public void actionPerformed(ActionEvent e) {
    }
}
class HangmanGraphics extends JPanel {
    JPanel graphicsPanel = new JPanel();
    int incorrectGuesses =0;
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g;
        BasicStroke aStroke = new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2D.setStroke(aStroke);
        g2D.setColor(Color.BLUE);
        switch (incorrectGuesses) {
            case 10:
                g2D.drawLine(200, 200, 150, 250); // Left leg
            case 9:
                g2D.drawLine(200, 200, 250, 250); // Right leg
            case 8:
                g2D.drawLine(150, 150, 200, 175); // Left arm
            case 7:
                g2D.drawLine(250, 150, 200, 175); // Right arm
            case 6:
                g2D.drawLine(200, 200, 200, 150); // Torso
            case 5:
                g2D.drawOval(175, 100, 50, 50); // Head
            case 4:
                g2D.drawLine(200, 100, 200, 50);// Noose
            case 3:
                g2D.drawLine(200, 50, 100, 50);//Plank
            case 2:
                g2D.drawLine(100, 300, 100, 50); //Post
            case 1:
                g2D.drawLine(20, 300, 300, 300); //Stage
        }
        repaint();
        graphicsPanel.add(new HangmanGraphics());
    }

}

您的问题对于许多(如果不是大多数)新开发人员来说很常见,是过度使用static,对面向对象编程以及如何使用对象缺乏了解。在您的情况下,您尝试在JFrame类型对象 ( HangmanGame ) 内创建一个 main 方法,然后您有一个要调用的静态方法,通常是因为您试图弄清楚如何从 static main 方法调用它。您最好为 HangManGame 创建一个单独的"驱动程序"类,其中包含 main 方法。然后,HangManGame类创建一个HangManFrame实例(调用new HangManFrame())。

要记住的 2 个要点是:

1) 在 main 方法中,创建定义 main 的类的实例,然后对该对象调用方法。通过这样做,你不需要声明一堆静态方法,并且可以避免像你现在所经历的很多痛苦。例如,下面是 HangManGame 类的定义:

package hangman;
public class HangManGame {
    HangManFrame frame;
    public HangManGame(){
        frame = new HangManFrame();
    }
    public void play() {
        frame.setVisible(true);
        String selectedPhrase = selectPhrase();
        System.out.println("Selected phrase: " + selectedPhrase);
    }
    public String selectPhrase() {
        String currentGuess = "*";
        int[] previousValues = new int[5];
        int totalRounds = 0;
        //set isValid equal to false and creates a random number between 1 and 6
        //(between 1 and 6 because previousValues is used to store the old numbers,
        //and if between 0 and 5 were used, 0 would trip every time because an uninitialized
        //array has 0's (null) in every position)
        boolean isValid = false;
        int index = (int)(Math.random() * 5 + 1);
        //enters loop because isValid is false, so !isValid is true
        while(!isValid)
        {
            //sets isValid equal to true, so if it never gets changed during the loop, it will exit next time around
            isValid = true;
            for(int i = 0; i < totalRounds; i++)
            {
                //if the randomly generated value is one of the previous ones, make isValid false
                if(index == previousValues[i])
                {
                    isValid = false;
                }
            }
            //if isValid is false, create a new random number between 1 and 6
            if(!isValid)
            {
                index = (int)(Math.random() * 5 + 1);
            }
        }
        //once a value that's never been used before is created, save it in previousValues
        //so that it is not used again
        previousValues[totalRounds] = index;
        totalRounds++;
        //return phrase at the index of the random number
        String[] phrase = {"NULL", "Go Team", "Hello World" , "Java Rocks", "Bread Bowl" , "Soup"};
        return phrase[index];
    }
    public static void main(String[] args) {
        HangManGame game = new HangManGame();
        game.play();
    }
}

请注意,main 方法执行的唯一任务是创建 HangManGame 类的实例,并在该对象上调用 play() 方法。就是这样!

另请注意,selectPhrase() 方法未声明为静态方法,因为它不是必需的。

2)对于所有类,需要访问并需要能够调用方法的对象应在方法外部声明为"类范围的实例变量"。例如,请注意HangManFrame是如何在 HangManGame 类内部声明的,但在方法外部声明的。然后在"HangManGame"的构造函数中创建并分配框架

 public class HangManGame {
    HangManFrame frame;
    public HangManGame(){
        frame = new HangManFrame();
    }
 ...
}

这样做将允许您从任何HangManGame方法中调用框架上的方法。

我稍微重构了您的HangManFrameHangManGraphics类,遵循类似的状态,如下所示。

最后,您应该开始在 HangManGame 类上创建其他方法,例如 nextMove()updateBoard() 或其他方法,这些方法由 play() 方法驱动并从中调用。

刽子手框架类:

包装刽子手;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HangManFrame extends JFrame implements ActionListener {
    JPanel lettersPanel;
    public HangManFrame() {
        lettersPanel = new JPanel(new GridLayout(5, 8, 5, 5));
        JButton jbtA = new JButton("A");
        JButton jbtB = new JButton("B");
        JButton jbtC = new JButton("C");
        JButton jbtD = new JButton("D");
        JButton jbtE = new JButton("E");
        JButton jbtF = new JButton("F");
        JButton jbtG = new JButton("G");
        JButton jbtH = new JButton("H");
        JButton jbtI = new JButton("I");
        JButton jbtJ = new JButton("J");
        JButton jbtK = new JButton("K");
        JButton jbtL = new JButton("L");
        JButton jbtM = new JButton("M");
        JButton jbtN = new JButton("N");
        JButton jbtO = new JButton("O");
        JButton jbtP = new JButton("P");
        JButton jbtQ = new JButton("Q");
        JButton jbtR = new JButton("R");
        JButton jbtS = new JButton("S");
        JButton jbtT = new JButton("T");
        JButton jbtU = new JButton("U");
        JButton jbtV = new JButton("V");
        JButton jbtW = new JButton("W");
        JButton jbtX = new JButton("X");
        JButton jbtY = new JButton("Y");
        JButton jbtZ = new JButton("Z");
        lettersPanel.add(jbtA);
        lettersPanel.add(jbtB);
        lettersPanel.add(jbtC);
        lettersPanel.add(jbtD);
        lettersPanel.add(jbtE);
        lettersPanel.add(jbtF);
        lettersPanel.add(jbtG);
        lettersPanel.add(jbtH);
        lettersPanel.add(jbtI);
        lettersPanel.add(jbtJ);
        lettersPanel.add(jbtK);
        lettersPanel.add(jbtL);
        lettersPanel.add(jbtM);
        lettersPanel.add(jbtN);
        lettersPanel.add(jbtO);
        lettersPanel.add(jbtP);
        lettersPanel.add(jbtQ);
        lettersPanel.add(jbtR);
        lettersPanel.add(jbtS);
        lettersPanel.add(jbtT);
        lettersPanel.add(jbtU);
        lettersPanel.add(jbtV);
        lettersPanel.add(jbtW);
        lettersPanel.add(jbtX);
        lettersPanel.add(jbtY);
        lettersPanel.add(jbtZ);
        JPanel mainPanel = new JPanel(new BorderLayout());
        setLayout(new GridLayout(2, 2, 5, 5));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        mainPanel.add(lettersPanel, BorderLayout.EAST);
        mainPanel.setBackground(Color.BLACK);
        add(mainPanel, BorderLayout.CENTER);
        add(new HangmanGraphics());
        setTitle("Hangman");
        setSize(1020, 800);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Received actionPerformed event: " + e.getActionCommand());
    }
}

刽子手图形类:

包装刽子手;

导入 javax.swing。;导入java.awt.;

类 HangmanGraphics 扩展了 JPanel {

JPanel graphicsPanel = new JPanel();
int incorrectGuesses =0;
@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D) g;
    BasicStroke aStroke = new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    g2D.setStroke(aStroke);
    g2D.setColor(Color.BLUE);
    switch (incorrectGuesses) {
        case 10:
            g2D.drawLine(200, 200, 150, 250); // Left leg
        case 9:
            g2D.drawLine(200, 200, 250, 250); // Right leg
        case 8:
            g2D.drawLine(150, 150, 200, 175); // Left arm
        case 7:
            g2D.drawLine(250, 150, 200, 175); // Right arm
        case 6:
            g2D.drawLine(200, 200, 200, 150); // Torso
        case 5:
            g2D.drawOval(175, 100, 50, 50); // Head
        case 4:
            g2D.drawLine(200, 100, 200, 50);// Noose
        case 3:
            g2D.drawLine(200, 50, 100, 50);//Plank
        case 2:
            g2D.drawLine(100, 300, 100, 50); //Post
        case 1:
            g2D.drawLine(20, 300, 300, 300); //Stage
    }
    repaint();
    graphicsPanel.add(new HangmanGraphics());
}

}

最新更新