2013-12-09 2 views
-3

У меня возникло несколько различных проблем с моим кодом, большинство из них основаны на графическом интерфейсе, но у меня есть одна проблема с действием. Сначала я отправлю свой код в разделах, а затем укажу, какая проблема конкретно связана с каждым разделом. * Заметьте, что весь мой код будет в порядке, как на самом деле в моей среде IDE.Java Hangman GUI не отображается должным образом

Если вы хотите скопировать мой код, не все другие вещи, то здесь на Pastebin: 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 

My 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 (ГЛАВНАЯ ПРОБЛЕМА).

Проблемы у меня с моим Init код, который влияет на мою GUI заключается в том, что фактическая область словесного уклона и область палача немного перепутаны. Трудно объяснить, поэтому я покажу вам изображение. Фон для почти всей формы полностью прозрачен. Поэтому он просто использует изображение того, что было на вершине, поскольку это задняя поверхность.

Задача 3: Есть другие проблемы с изображением, которые вы можете видеть. Однако код для этих частей ниже. Но, как вы можете сказать, сообщения не очищаются и просто пишут друг над другом, даже если я их укажу (что вы увидите ниже).

Задача 4: Теперь, прежде чем вы догадываетесь любые буквы, слово скрыт с «», но когда вы угадать правильную букву для слова он должен заменить «» с нужной буквой догадывались. Однако он просто положил его поверх него (вы также увидите код для этого ниже).

Messed up Graphics

Это игра Initializer

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) Я задал все эти вопросы, многие из которых были связаны (потому что все, кроме одного, основаны на графическом интерфейсе). 3) Я попробовал это, и это дало мне ошибку, когда я добавил super.paintCompenents. Я пришел сюда, чтобы попросить о помощи, чтобы мне не сказали, что мне нужно обратиться за помощью по-другому, когда я сделал это правильно, отформатирован и любезно. –

ответ

2

Это связано с тем, что вы нарушили цепь paint.

Картина в AWT/Swing выполнена из цепочки вызовов метода. Если вы пренебрегаете поддержанием этой цепочки, вы начинаете заканчивать артефактами краски в форме, которую видите.

Контекст - это общий ресурс, то есть каждый компонент, окрашенный в течение любого заданного цикла рисования, будет иметь тот же ресурс Graphics. Каждый компонент, как ожидается, подготовить Graphics контекст перед покраской к нему ...

Чтобы устранить эту проблему, во всех ваших paint методов, вы должны называть super.paint(g), чтобы гарантировать, что краска цепи поддерживается и что Graphics контекст Предназначен для индивидуальных потребностей живописи.

Сказав это. Не рекомендуется переопределять paint контейнеров верхнего уровня. Вместо этого рекомендуется выполнить пользовательскую картину, используя что-то вроде JPanel и переопределить это paintComponent метод вместо (гарантируя, что вы называете super.paintComponent, как хорошо!)

Это имеет минимум два основных преимущества.Во-первых, вы можете знать, где будет отображаться панель, например, вы можете добавить ее в JApplet или JFrame или другой контейнер, как вы сочтете нужным. По умолчанию используется двойной буфер. Это означает, что при обновлении живописи вы не увидите мерцания.

Вы должны рассмотреть возможность разбивать приложение на небольшие панели, уделяя особое внимание каждому компоненту отдельно. Это поможет снизить сложность вашего приложения и упростить управление индивидуальными потребностями каждого раздела вашего приложения.

Взгляните на Performing Custom Painting и Painting in AWT and Swing для получения более подробной информации

+0

+1 для детализации оригинальной проблемы сломанной цепочки. – tenorsax

+0

@Aqua Если вы уточните, что ответите, не назвав 'super.paint', я был бы более склонен предлагать голосование;) - Потому что остальные вы отвечаете за отличный совет ... – MadProgrammer

+0

@MadProgrammer Можете ли вы посмотрите на мой код? Я пересмотрел его много. pastebin.com/66Q70f5X Я создал публичный конструктор для моего класса Hangman, и я также создал еще один класс, чтобы держать почти все. И он предоставляет нижнюю панель (текстовое поле и кнопки и т. Д.), Но остальная часть пуста (что хорошо, потому что она была прозрачной перед рукой), но теперь она ничего не рисует :( –

1

Проблема в том, что вы рисуете прямо на JApplet. Не следует рисовать непосредственно на контейнере верхнего уровня, таком как JFrame или JApplet. Вместо этого используйте JComponent или JPanel. Переопределить paintComponent() для окраски, а не paint() и не забудьте позвонить в super.paintComponent(g).

Посмотрите на Performing Custom Painting учебник для получения дополнительной информации.

Рассмотрите возможность реорганизации кода, переместив всю текущую логику и рисунок в новый JPanel, который будет использоваться в качестве содержимого апплета. Затем добавьте эту панель в апплет.

EDIT:

Источник проблемы не называет super.paint() в вас картина реализации. Переопределение paint() не требуется и обычно не рекомендуется во многих приложениях Swing. JComponent.paint() (суперкласс для всех компонентов Swing) обрабатывает содержимое, границы и дочерние элементы Swing. И, пренебрегая призывом к super.paint(), вы нарушаете картину всех этих деталей.

Взгляните на A Closer Look at the Paint Mechanism для получения более подробной информации о цикле окраски.

+0

Хорошо, так какой код и где мне нужно точно изменить, чтобы реализовать это? –

+1

Это отличный совет, но (с моей точки зрения) проблема заключается не в том, что они переопределили «краску» контейнера верхнего уровня (хотя, конечно, не рекомендуется, это не причина проблемы), - но вы close;) – MadProgrammer

+0

+1 Очень приятно;) – MadProgrammer

 Смежные вопросы

  • Нет связанных вопросов^_^