2013-12-09 200 views
-3

我的代码有几个不同的问题,其中大部分都是基于GUI的问题,但我确实有一个actionevent问题。我将在第一部分中发布我的代码,然后我将指出每个部分专门针对的问题。 *注意我的所有代码将按照我在IDE中的实际情况排列。Java Hangman GUI没有正确显示

如果你希望不都在这里其他的东西来复制我的代码是在引擎收录:http://pastebin.com/HHjRRtGZ

我进口:

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; //Makes it a Japplet 

import java.util.Random; 

我计划从这里开始:

public class Hangman extends JApplet implements ActionListener { 

    // How many times you can guess the wrong letter till you lose 
    static final int DEAD = 7; 

    private int errors;  // amount of errors 
    private String message; // Message displaying either Error or Victory 
    private String information; // Secondary Message 
    private String RealWord;  // The Real word 
    private StringBuffer GuessWord;// The Guessed word 
    private Button StartBtn;  // The Restart Button 
    private Button GoBtn;   // The Go Button 
    private TextField LetterBox; // The LetterBox 

我的ActionEvent:

public void actionPerformed(ActionEvent e){ 

     if (e.getSource() == StartBtn){ 
      initGame(); 
     } 

     if (e.getSource() == GoBtn){ 

      processTurn(); 

      LetterBox.setText(""); 
      repaint(); 
     } 
    } 

问题一:

,我用我的行动事件时遇到的问题是,当我打的StartBtn它不会重新初始化一切。没有东西被清除。没有事情做完。它什么都不做。所以这是那个问题。

我的init()函数(这是我的问题之一在于

public void init() { 

     // Create a "Textbox" for the letter guessing 
     LetterBox = new TextField(); 

     //Create my buttons and labels 
     StartBtn = new Button("Restart"); 
     GoBtn = new Button("Go"); 

     //Add the elements to the applet 

     JPanel p = new JPanel(); 
     p.setLayout(new FlowLayout()); 

     p.add(StartBtn); 
     p.add(new Label("Guess a letter")); 
     p.add(LetterBox); 
     p.add(GoBtn); 

     add(p, BorderLayout.SOUTH); 

     //Make buttons event listeners 
     StartBtn.addActionListener(this); 
     GoBtn.addActionListener(this); 

     //Startup the Game 
     initGame(); 

    } 

问题2(主要的问题):

我有会影响我的初始化代码的问题,我图形用户界面是,实际的字猜测区域和hang子手区域有点混乱,很难解释,所以我会告诉你一个图像。几乎所有形式的背景都是完全透明的,所以它只是使用静止不管它在什么地方,它的背景图像。

问题3: 您可以看到图像还有其他一些问题。但是,这些代码的代码更进一步。但是,正如你所看到的那样,即使我将它们指定为(你将会看到更多的信息),这些信息并不清楚,只是互相写下来。

问题4: 现在你猜的信之前,这个词是隐藏着一个“”,但是当你猜一个正确的字母的单词,它应该与猜到了正确的字母来代替“”。然而它只是把它放在它之上(你也会看到下面的代码)。

Messed up Graphics

这是游戏初始化

public void initGame() { 
     //Set the errors to 0 
     errors = 0; 

     //Enter the wordslist, separated by a | here 
     String str = "write|program|receive|positive|variables|temporary|good|bad|test";   
     String[] temp; 


     //delimiter 
     String delimiter = "\\|"; 

     // given string will be split by the argument delimiter provided. 
     temp = str.split(delimiter); 

     //Create the Random Seed Generator 
     Random RandGenerator = new Random(); 

     //Generate my Random Number 
     int randomInt = RandGenerator.nextInt(temp.length); 

     RealWord = new String(temp[randomInt]); 

     char positions[] = new char[RealWord.length()]; 

就在这里,它以 “*” 代替屏幕上的字符unguessed。

 for (int i = 0; i < RealWord.length(); i++) { 
      positions[i] = '*'; 
     } 


     String s = new String(positions); 
     GuessWord = new StringBuffer(s); 

     LetterBox.setText(""); 

     //Delete Messages 
     message = ""; 
     information = ""; 
     repaint(); 
    } 

我的绘画功能

@Override 
    public void paint(Graphics g) { 

     int BaseY = 250; 

     //THE HANGING STAND 
     if (errors > 0) { //1 Error 
      g.drawLine(90, BaseY, 200, BaseY); //The ground 
      g.drawLine(125, BaseY, 125, BaseY-100); //The bar going up 
      g.drawLine(125, BaseY-100, 175, BaseY-100); //The sidebar 
      g.drawLine(175, BaseY-100, 175, BaseY-75); //The Rope 
     } 

     //THE PERSON 
     if (errors > 1) { 
      g.drawOval(170, BaseY-75, 10, 12); // The Head  
     } 

     if (errors > 2) { 
      g.drawLine(175, BaseY-62, 175, BaseY-45); // The Body  
     } 

     if (errors > 3) { 
      g.drawLine(165, BaseY-65, 175, BaseY-55); // Left Arm 
     } 

     if (errors > 4) { 
      g.drawLine(185, BaseY-65, 175, BaseY-55); // Right Arm 
     } 

     if (errors > 5) { 
      g.drawLine(170, BaseY-30, 175, BaseY-45); //Left Leg  
     } 

     if (errors > 6) { //7 Errors 
      g.drawLine(175, BaseY-45, 180, BaseY-30); // Right Left 
     } 


     //Show Messages/Errors 
     g.drawString(message, 40, BaseY+25); 
     g.drawString(information, 25, BaseY+45); 
     g.drawString(new String (GuessWord), 140, BaseY-120); 

     g.drawString(new String("WELCOME TO HANGMAN!"), 75, 40); 
    } 

这是神奇的很多情况。这是processTurn功能

private void processTurn() { 

     String s, t; 
     char a; 

     s = LetterBox.getText(); 
     a = s.charAt(0); 

     if (!Character.isLetter(a)) { 
      message = "Only enter letters please."; 
      return; 
     } 

     if (s.length() > 1) { 
      message = "One letter at a time please."; 
      return; 
     } 

     //Check if letter has been used already 
     t = new String(GuessWord); 
     if (t.indexOf(s) != -1) { 
      message = "You have already guessed with that letter!"; 
      return; 
     } 

     //If the letter you guessed does not occur in the Real Word 
     if (RealWord.indexOf(s) == -1) { 

      message = ""; 
      errors++; 

      if (errors==DEAD) { 
       message = "Sorry, you lose"; 
       information = "Click restart to try again!"; 

       //INSERT MOVING HANGMAN HERE. 
      } 

      return; 
     } 

这就是“*”应该与correctl猜字母代替,但它不能正常工作!

 //Replace stars in the Guessed Word with the found letter 
     for (int i = 0; i < RealWord.length(); i++) { 
      if (RealWord.charAt(i) == a) { 
       GuessWord.setCharAt(i, a); 
      } 
     } 

     t = new String(GuessWord); 

     //If all of the stars have been filled, then you win! 
     if (t.indexOf('*') == -1) { 
      message = "You have won!"; 
      return; 
     } 

     //Delete the Message 
     message = ""; 
     repaint(); 
    } 

主要功能

public static void main(String[] args) { 

     JFrame frame = new JFrame(); 
     JApplet applet = new Hangman(); 

     applet.init(); 
     applet.start(); 
     frame.add(applet); 

     frame.setSize(300, 400); 
     frame.setLocationRelativeTo(null); // Center the frame 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 


    } 
} 

任何和所有帮助将不胜感激:)在此先感谢!

+0

1)你贴了太多的代码2)你问太多的问题无关。尝试着重于当时的一个问题3)不要重写'paint',而是覆盖'paintComponents'而不是重写(并且在覆盖的方法中调用'super.paintComponents' – Robin

+0

1)我发布了所有的代码,因为它们都是相关的2 )我问了所有这些问题,其中许多与他们有关(因为除了其中一个都是基于GUI的)3)我尝试过,当我添加super.paintCompenents时,它给了我一个错误。我来到这里寻求帮助,不要被告知当我做得正确,格式化和善良时,我需要以不同的方式寻求帮助。 –

回答

2

这是由于您打破了paint链的基本事实造成的。

AWT/Swing中的绘画是由一系列方法调用组成的。如果你忽视维持这个链条,你会以你所看到的形式开始画画。

Graphics上下文是一个共享资源,也就是说,在任何给定的绘制周期中绘制的每个组件都将被赋予相同的Graphics资源。每个组件预计绘画到之前准备Graphics背景...

要解决该问题,在您的所有paint方法,你应该打电话super.paint(g),以确保油漆链维持,Graphics上下文为个别组件绘画需求而准备。

话虽如此。不建议覆盖顶级容器的paint。相反,它建议你使用像一个JPanel执行你的风俗画和覆盖它的paintComponent方法,而不是(确保你叫super.paintComponent以及!)

这有至少两个基本的好处。首先,您可以知道决定显示面板的位置,例如,您可以将其添加到JAppletJFrame或其他容器上,只要您认为合适。它默认是双缓冲。这意味着当绘画更新时你不会看到任何闪烁。

您应该考虑将应用程序分解为小面板,重点关注每个组件需求。这将有助于降低应用程序的复杂性,并更轻松地管理应用程序各个部分的个别需求。

看看Performing Custom PaintingPainting in AWT and Swing更多细节

+0

+1为详细描述破碎的油漆链的原始问题。 – tenorsax

+0

@Aqua如果你更新你的答案,提到不要调用'super.paint',我会更倾向于提供加票;) - 因为你们其余的回答是伟大的建议... – MadProgrammer

+0

@MadProgrammer你能看看我的代码?我修改了很多。 pastebin.com/66Q70f5X我为我的Hangman类创建了一个公共构造函数,并且我还创建了另一个类来容纳几乎所有东西。它提供了底部栏(文本框和按钮等),但它的其余部分是空白的(这是好的,因为它在手前是透明的),但它现在不绘制任何东西:( –

1

问题是你直接在JApplet上画。您不应直接在顶级容器上进行喷漆,如JFrameJApplet。请改用JComponentJPanel。覆盖paintComponent()绘画而不是paint(),不要忘记拨打super.paintComponent(g)

查看Performing Custom Painting教程了解更多信息。

考虑通过将所有当前逻辑和绘画移动到将用作小程序内容的新JPanel来重构代码。然后,将此面板添加到小程序。

编辑:

问题的根源并没有叫super.paint()在你画的实现。覆盖paint()不是必需的,通常不建议在许多Swing应用程序中使用。 JComponent.paint()(用于所有Swing组件的超类)处理绘制Swing组件的内容,边框和子项。通过忽略对super.paint()的呼叫,您正在破坏所有这些细节的绘画。

看看A Closer Look at the Paint Mechanism关于绘画循环的更多细节。

+0

好的,那么为了实现这个目标,我需要哪些代码以及哪些地方需要完全更改? –

+1

这是很好的建议,但是(从我的角度来看),问题不在于他们已经重写了顶层容器的“paint”(虽然肯定不适合,它不是问题的原因) - 但是关闭;) – MadProgrammer

+0

+1非常好;) – MadProgrammer