graphics2D drawImage无法与timer.schedule一起使用

问题描述 投票:1回答:1

我正在尝试用Java模拟Gameboy游戏。我试图每半秒左右将一个字母打印到一个文本框,但是当我运行代码时,该框被正确绘制,但是其中没有文本。

文本框:

package components;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

public class Textbox extends Entity { //Only create one instance
private static String[] lines;
private static final int x = 1;
private static final int y = 97;
private Graphics2D graphics2D;
int lineNo = 0; //Used to count the line number when printing
int charNo = 0; //Used to count the character number when printing
int cx; //Used for the coordinates of each character printed
int cy; //Used for the coordinates of each character printed
boolean timerInitialized = false; //Used to indicate end of line when printing
java.util.Timer timer = new Timer(); //Used to control text speed
//java.util.TimerTask task;

private static volatile Textbox textbox = new Textbox();

public Textbox() {
    super(x, y);
    addLines();
}

public void draw(Graphics2D graphics2D) {
    this.graphics2D = graphics2D;
    this.graphics2D.drawImage(getImage(), x, y, null);
    if (!timerInitialized) {
        System.out.println("Scheduled..."); //For testing
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!"); //For testing
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 1000);
        timerInitialized = true;
    }
}

/*public void drawText(Image image, Point coordinates) {
    this.graphics2D.drawImage(image, coordinates.x, coordinates.y, null);
}*/

public Image getImage() {
    //graphics2D.drawString("Hello World", 100, 100); //Draws  a string
    ImageIcon imageIcon = new ImageIcon(
            "enterDirectoryHere"
                    + "\\src\\components\\Display\\Textbox.png");
    return imageIcon.getImage();
}

public void keyReleased(KeyEvent event) {
    int key = event.getKeyCode();

    if (key == KeyEvent.VK_ENTER) {
        if (GameFrame.screenPaused == true) {
            GameFrame.screenPaused = false;
        } else {
            GameFrame.screenPaused = true;
        }

    }
}

//FOR TESTING ONLY
public static void addLines() {
    lines = new String[] {"Hello", "World"};

}


/*
Make a boolean to indicate that line1 is full, and to continue on line 2 if
more text remains
Show cursor to indicate more text in lines
When pressing 'A' to continue text, translate text upward
If text exceeds boundaries, begin to cut off, starting from top, until gone

 */
/*public void printText(Graphics2D graphics2D) {
    if (lines != null) {
        //Assume that you already know the arrangement of words in the box
        //Starting point is 8, 112
        lineNo = 0;
        //endLine = false;
        while (lineNo < lines.length) {
            String line = lines[lineNo];
            if (line != null) {
                charNo = 0;
                for (int i = 0; i < line.length(); i++) {
                    printChars(graphics2D, line);
                }
            }
            lineNo++; //Move to the next line
            //line takes new line into account
            cx = 8;
        }
    }

}*/

public void printChars(Graphics2D graphics2D, String line) {
    if (charNo < line.length()) {
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        if (line.charAt(charNo) >= 'A' && line.charAt(charNo) <= 'Z') {
            Image image = getCharImage(line.charAt(charNo));
            graphics2D.drawImage(image, cx, cy, null);
            cx += image.getWidth(null);
        } else if (line.charAt(charNo) >= 'a' && line.charAt(charNo) <= 'z') {
            if (line.charAt(charNo) == 'b' || line.charAt(charNo) == 'd'
                    || line.charAt(charNo) == 'f' || line.charAt(charNo) == 'h'
                    || line.charAt(charNo) == 'k' || line.charAt(charNo) == 'l') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == 'i' || line.charAt(charNo) == 'j'
                    || line.charAt(charNo) == 't') {
                cy += 1;
                //Add extra spaces for i, j, and l
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else {
                cy += 2;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        } else if (line.charAt(charNo) >= 32 && line.charAt(charNo) <= 95) {
            //Check for symbols and spaces
            if (line.charAt(charNo) == '_') {
                cx += 7;
            } else if (line.charAt(charNo) == '.') {
                cy += 5;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == ',') {

            } else if (line.charAt(charNo) == '/') {

            } else if (line.charAt(charNo) == '?') {

            } else if (line.charAt(charNo) == '!') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null) + 8;
            } else if (line.charAt(charNo) == ']') {

            } else if (line.charAt(charNo) == '[') {

            } else if (line.charAt(charNo) == ':') {

            } else if (line.charAt(charNo) == ';') {

            } else if (line.charAt(charNo) == '-') {

            } else if (line.charAt(charNo) == '(') {

            } else if (line.charAt(charNo) == ')') {

            } else if (line.charAt(charNo) == '\'') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        }
        cx += 2; //move two pixels to the right
        //Writes on the second half of the box if there is
        //more than 1 line
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        charNo++;
    } else {
        //charNo = 0;
        //lineNo++;
    }
    //Schedule the next letter here if there are more letters
    if (lineNo < lines.length || charNo < line.length()) {
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 200);
    }
}

GameFrame:

package components;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class GameFrame extends JPanel implements ActionListener{

javax.swing.Timer mainTimer;
Player player;
Textbox textbox;
Trainer trainer;
//static boolean showDialogueBox = true;
static boolean screenPaused = true;

static ArrayList<Trainer> trainerList = new ArrayList<>();

//Each setting has its own trainers

public GameFrame() {
    setFocusable(true);

    player = new Player();
    //player = new Player(138, 98); The bottom right corner
    //trainerList.add(trainer);
    textbox = new Textbox();
    addKeyListener(new KeyAdapt(player, textbox));
    mainTimer = new Timer(10, this); //Resets the screen every 10 millisecs
    mainTimer.start();
}

public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D graphics2D = (Graphics2D) graphics;
    //player.draw(graphics2D);
    if (screenPaused) {
        textbox.draw(graphics2D);
        //textbox.printText(graphics2D);
    }

}

@Override
public void actionPerformed(ActionEvent event) {
    player.update();
    repaint();
}

public static ArrayList<Trainer> getTrainerList() {
    return trainerList;
}

}

但是我最后看到一个空盒子:See result here

当我注释掉设置计时器的部分时,如下所示:

GameFrame:

package components;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class GameFrame extends JPanel implements ActionListener{

javax.swing.Timer mainTimer;
Player player;
Textbox textbox;
Trainer trainer;
//static boolean showDialogueBox = true;
static boolean screenPaused = true;

static ArrayList<Trainer> trainerList = new ArrayList<>();

//Each setting has its own trainers

public GameFrame() {
    setFocusable(true);

    player = new Player();
    //player = new Player(138, 98); The bottom right corner
    //trainerList.add(trainer);
    textbox = new Textbox();
    addKeyListener(new KeyAdapt(player, textbox));
    mainTimer = new Timer(10, this); //Resets the screen every 10 millisecs
    mainTimer.start();
}

public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D graphics2D = (Graphics2D) graphics;
    if (screenPaused) {
        textbox.draw(graphics2D);
        textbox.printText(graphics2D);
    }

}

@Override
public void actionPerformed(ActionEvent event) {
    player.update();
    repaint();
}

public static ArrayList<Trainer> getTrainerList() {
    return trainerList;
}

}

文本框:

import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

public class Textbox extends Entity {

private static String[] lines;

private static final int x = 1;
private static final int y = 97;
private Graphics2D graphics2D;
int lineNo = 0; //Used to count the line number when printing
int charNo = 0; //Used to count the character number when printing
int cx; //Used for the coordinates of each character printed
int cy; //Used for the coordinates of each character printed
boolean timerInitialized = false; //Used to indicate end of line when printing
java.util.Timer timer = new Timer();

private static volatile Textbox textbox = new Textbox();

public Textbox() {
    super(x, y);
    addLines();
}

public void draw(Graphics2D graphics2D) {
    this.graphics2D = graphics2D;
    this.graphics2D.drawImage(getImage(), x, y, null);
    if (!timerInitialized) {
        /*System.out.println("Scheduled..."); //For testing
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!"); //For testing
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 1000);*/
        timerInitialized = true;
    }
}

/*public void drawText(Image image, Point coordinates) {
    this.graphics2D.drawImage(image, coordinates.x, coordinates.y, null);
}*/

public Image getImage() {
    //graphics2D.drawString("Hello World", 100, 100); //Draws  a string
    ImageIcon imageIcon = new ImageIcon(
            "C:\\EnterDirectoryHere"
                    + "\\src\\components\\Display\\Textbox.png");
    return imageIcon.getImage();

public void keyReleased(KeyEvent event) {

    int key = event.getKeyCode();

    if (key == KeyEvent.VK_ENTER) {
        if (GameFrame.screenPaused == true) {
            GameFrame.screenPaused = false;
        } else {
            GameFrame.screenPaused = true;
        }

    }
}

//FOR TESTING ONLY
public static void addLines() {
    lines = new String[] {"Hello", "World"};

}


/*
Make a boolean to indicate that line1 is full, and to continue on line 2 if
more text remains
Show cursor to indicate more text in lines
When pressing 'A' to continue text, translate text upward
If text exceeds boundaries, begin to cut off, starting from top, until gone

 */
public void printText(Graphics2D graphics2D) {
    if (lines != null) {
        //Assume that you already know the arrangement of words in the box
        //Starting point is 8, 112
        lineNo = 0;
        //endLine = false;
        while (lineNo < lines.length) {
            String line = lines[lineNo];
            if (line != null) {
                charNo = 0;
                for (int i = 0; i < line.length(); i++) {
                    printChars(graphics2D, line);
                }
            }
            lineNo++; //Move to the next line
            //line takes new line into account
            cx = 8;
        }
    }

}

public void printChars(Graphics2D graphics2D, String line) {
    if (charNo < line.length()) {
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        if (line.charAt(charNo) >= 'A' && line.charAt(charNo) <= 'Z') {
            Image image = getCharImage(line.charAt(charNo));
            graphics2D.drawImage(image, cx, cy, null);
            cx += image.getWidth(null);
        } else if (line.charAt(charNo) >= 'a' && line.charAt(charNo) <= 'z') {
            if (line.charAt(charNo) == 'b' || line.charAt(charNo) == 'd'
                    || line.charAt(charNo) == 'f' || line.charAt(charNo) == 'h'
                    || line.charAt(charNo) == 'k' || line.charAt(charNo) == 'l') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == 'i' || line.charAt(charNo) == 'j'
                    || line.charAt(charNo) == 't') {
                cy += 1;
                //Add extra spaces for i, j, and l
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else {
                cy += 2;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        } else if (line.charAt(charNo) >= 32 && line.charAt(charNo) <= 95) {
            //Check for symbols and spaces
            if (line.charAt(charNo) == '_') {
                cx += 7;
            } else if (line.charAt(charNo) == '.') {
                cy += 5;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == ',') {

            } else if (line.charAt(charNo) == '/') {

            } else if (line.charAt(charNo) == '?') {

            } else if (line.charAt(charNo) == '!') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null) + 8;
            } else if (line.charAt(charNo) == ']') {

            } else if (line.charAt(charNo) == '[') {

            } else if (line.charAt(charNo) == ':') {

            } else if (line.charAt(charNo) == ';') {

            } else if (line.charAt(charNo) == '-') {

            } else if (line.charAt(charNo) == '(') {

            } else if (line.charAt(charNo) == ')') {

            } else if (line.charAt(charNo) == '\'') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        }
        cx += 2; //move two pixels to the right
        //Writes on the second half of the box if there is
        //more than 1 line
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        charNo++;
    } else {
        //charNo = 0;
        //lineNo++;
    }
    //Schedule the next letter here if there are more letters
    if (lineNo < lines.length || charNo < line.length()) {
        /*timer.schedule(new TimerTask() {
            @Override
            public void run() {
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 200);*/
    }
}

文本显示的很好,但是它一次显示了所有,这不是我想要的。See result here我忘了做什么吗?

java swing intellij-idea drawimage
1个回答
0
投票

我意识到问题出在哪里。每次调用draw()时,我都不会更新要显示的文本。通过执行此操作,我可以获得所需的结果:

public void draw(Graphics2D graphics2D) {
    graphics2D.drawImage(getImage(), x, y, null);
    //Every time draw is called, ensure that the coordinates are the same
    //each time text is redrawn
    if (!display.isEmpty()) { //This will only print when characters have
        //been added every second
        for (int i = 0; i < display.size(); i++) {
            drawText(graphics2D, display.get(i).charAt(0), coordinates.get(i));
        }
    }
    if (!timerInitialized && line1 != null) { //This only allows the timer to be set once
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                addTextToDisplay(lines[0]);
            }
        }, 100);
        timerInitialized = true;
    }
}

我使用了两个数组列表,显示和坐标。显示列出要打印的字母,并在屏幕上坐标标记该字符的坐标。

© www.soinside.com 2019 - 2024. All rights reserved.