2013-12-09 110 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