使用带有键监听器的图形

时间:2016-03-31 22:04:03

标签: java graphics keylistener repaint

因此,对于作业,我应该使用图形和keylistener制作刽子手。用户直接从键盘输入字母。我有这个问题,在我做任何关键监听器后,图形停止工作。

当我在checkHangman()方法中调用fillLetters()方法(最终将调用paint()方法)时,会绘制该字母。但是,如果我从keylistener的checkHangman()方法调用keyPressed()方法,图形就会停止工作。

我在draw命令之后将print语句放在fillLetters()方法中,所以我知道方法和命令都被调用,但是当checkHangman()keyPressed()调用时,屏幕上没有显示任何内容}。我已经尝试使用repaint()并检查以确保keyPressed()方法传递的图形对象作为参数与其他方法使用的参数相同。在这一点上,我已经工作了几个小时,但仍然卡住了。任何帮助表示赞赏。

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;

public class Hangman {
    public static void main(String args[]) {
        GfxApp gfx = new GfxApp();
        gfx.setSize(1000,750);
        gfx.addWindowListener(new WindowAdapter() {public void
        windowClosing(WindowEvent e) {System.exit(0);}});
        gfx.show();
    }
}
class GfxApp extends Frame implements KeyListener {
    boolean added = false;
    private int tries = 0;
    String word;
    ArrayList<blanks> blank = new ArrayList<blanks>();
    HashSet<Character> used = new HashSet<Character>();
    HashSet<Character> notused = new HashSet<Character>();
    Graphics g;

    class blanks {
        private int x;
        private int y;
        private int x2;
        private int y2;
        private Graphics g;
        public blanks(int x, int y, int x2, int y2,  Graphics g) {
            this.x = x;
            this.y = y;
            this.x2 = x2;
            this.y2 = y2;
            this.g = g;
            drawBlank();
        }
        private void drawBlank() {
            g.setColor(Color.white);
            g.drawLine(x,y,x2,y2);
        }
        public void fillLetters(Graphics g, char lett) {
            g.setFont(new Font("COURIER NEW", Font.BOLD, x2-x));
            g.drawString(String.valueOf(lett), x, y);
            System.out.println("WE GOT HERE");   //this prints everytime I type something
        }
    }
    public void getWord() throws IOException
    {
        Scanner scanner = new Scanner(new File("Hangman.txt"));
        word = scanner.next();
    }

    public void paint(Graphics g){
        if(added == false)
        {
            addKeyListener(this);
            added = true;
        }
        g.setColor(Color.black);
        g.fillRect(0,0,1000,750);
        try{
            getWord();
        } catch (IOException e){
            System.out.println("Completed!");
        }
        drawHangman(g);
        drawBlanks(g, word);
    }
    private void drawHangman(Graphics g){
        g.setColor(Color.white);
        g.drawLine(50, 700, 200, 700);
        g.drawLine(125,75 , 125, 700);
        g.drawLine(125, 75, 300, 75);
        g.drawLine(300, 75, 300,150); 
        this.g = g;
    }
    public void checkHangman(Graphics g, char letter, String word) {
        char lett = Character.toLowerCase(letter);
        boolean check = false;
        g.setColor(Color.white);
        for(int i = 0; i < word.length(); i++) {
            char filler =  Character.toLowerCase(word.charAt(i));
            if(filler == lett) {
                check = true;
                break;
            } else {
                continue;
            }
        }
        if(check) {
            fillInLetters(g, letter, word);
        } else {
            tries++;
            switch(tries) {
                case 1: g.drawOval(250,150, 100,100); break;
                case 2: g.drawLine(300, 250, 300, 450); break; 
                case 3: g.drawLine(225, 625,300, 450); break; 
                case 4: g.drawLine(375, 625,300, 450); break;
                case 5: g.drawLine(300, 300, 200, 388); break;
                case 6: g.drawLine(300, 300, 400, 388); break;
                case 7: g.drawOval(270, 170, 20, 20); break;
                case 8: g.drawOval(310, 170, 20, 20); break;
                case 9: g.drawArc(275, 215, 50, 40, 0, 180); break;
            }
        }
    }
    public void fillInLetters(Graphics g, char letter, String word) {
        char check = Character.toLowerCase(letter);
        for(int i = 0; i < word.length(); i++) {
            char lett = Character.toLowerCase(word.charAt(i));
            if(check == lett) {
                blank.get(i).fillLetters(g, lett);
            }
        }
    }
    public void drawBlanks(Graphics g, String word) {
        int num = word.length();
        double sections = (double)(950-350)/num;
        int line = 350;
        for(int i = 1; i <= num; i++) {
            blank.add(new blanks(line, 150, line + (int)(sections) - 10, 150, g));
            line  += sections;
        }
    }

    public void keyPressed(KeyEvent e){
        char letter = (char) e.getKeyCode();
        used.add(new Character(letter));

        if(!notused.contains(new Character(letter)))
        {
            notused.add(new Character(letter));
            System.out.println(letter);
            checkHangman(g, letter, word);
        }
    }

    public void keyReleased(KeyEvent e){
        System.out.println("Key Released!!!");

    }

    public void keyTyped(KeyEvent e){
        System.out.println("Key Typed!!!");
    }
}

单词“APPLE”的示例输出。

1 个答案:

答案 0 :(得分:1)

首先看看Performing Custom PaintingPainting in AWT and Swing

绘画由Swing绘画子系统以定义的方式控制。

您应该首先覆盖组件的paintComponent方法,并在调用它时,绘制组件的当前状态。

您应该使用repaint请求系统安排绘制事件来更新您的UI

我也不鼓励你覆盖像Frame这样的顶级容器的油漆,除了没有经过双重缓冲,你还冒着在框架装饰下绘画的风险

作为一般经验法则,请勿保留对您自己未创建的Graphics背景的引用