cuốn sách gpt4 ai đã làm

使用invokelater重新绘制时不会调用Java PaintComponent

In lại Tác giả: Vũ trụ không gian 更新时间:2023-11-04 07:02:19 hai mươi bốn 4
mua khóa gpt4 Nike

我稍后在我的主方法中使用这样的调用:

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Ghi đè
công khai void run() {
Game bird = new Game();
bird.initialize();
}
});
}

然后当我尝试重新绘制时,它不会调用我的 JPanel 中的paintComponent(Graphics g)。但如果我稍后删除调用,然后执行新游戏,它会正常工作吗?

Đây là những gì tôi làm:

private void gameLoop() {
while(this.game) {
this.update();
this.render();
}
}

private void update() {
// TODO UPDATRES
}

private void render() {
super.repaint();
}

Trước khi chương trình đặt gui hiển thị, tôi thêm thành phần bằng cách sử dụng super.add(Màn hình màn hình) và sau đó đặt nó hiển thị, đây là lớp màn hình của tôi:

@SuppressWarnings("nối tiếp")
lớp công khai Màn hình mở rộng JPanel {

trò chơi trò chơi riêng tư;

Màn hình công khai(Trò chơi chim) {
this.game = chim;
}

public void PaintComponent(Graphics g) {
System.out.println("hey");
}
}

Tại sao PaintComponent không vẽ lại khi Invokelater đang chạy?

SRC:

trò chơi.java:

lớp công khai Trò chơi mở rộng Cửa sổ {

riêng tư cuối cùng dài serialVersionUID = 1L;

Màn hình trò chơi riêngMàn hình;
trò chơi boolean riêng tư = sai;

Trò chơi công khai() {
this.gameScreen = Màn hình mới(cái này);
}

khoảng trống công khai khởi tạo() {
super.setGameScreen(this.gameScreen);
this.game = true;
this.gameLoop();
}

private void gameLoop() {
while(this.game) {
this.update();
this.render();
}
}

private void update() {
// TODO UPDATRES
}

private void render() {
super.repaint();
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Ghi đè
công khai void run() {
Game bird = new Game();
bird.initialize();
}
});
}

}

cửa sổ.java:

Lớp công khai Cửa sổ mở rộng JFrame {

protectedWindow() {
super.setTitle("test");
super.setSize(this.getPerfectSize());
}

protected void setGameScreen(Màn hình JPanel) {
super.add(màn hình);
super.setVisible(true);
System.out.println("đã thêm");
}

Kích thước riêng tư getPerfectSize() {
trả về Kích thước mới (350, 500);
}
}

màn hình.java:

@SuppressWarnings("nối tiếp")
lớp công khai Màn hình mở rộng JPanel {

trò chơi trò chơi riêng tư;

Màn hình công khai(Trò chơi chim) {
this.game = chim;
}

public void PaintComponent(Graphics g) {
System.out.println("hey");
}
}

câu trả lời hay nhất

Lý do điều này xảy ra là do vòng lặp vô hạn trong gameLoop().

Khi bạn thực thi hàm khởi tạo trò chơi và phương thức khởi tạo() trực tiếp từ phương thức main(), bạn đang ở trên luồng chính. Vòng lặp vô hạn được thực thi trên luồng chính. Khi bạn gọi repaint(), EDT có quyền gọi phương thức PaintComponent().

Khi bạn thực thi hàm tạo Trò chơi và phương thức khởi tạo() từ SwingUtilities.invokeLater(), bạn đặt mã này vào EDT. Sau đó thực hiện một vòng lặp vô hạn trên EDT.

Vì bạn đang chặn EDT bên trong một vòng lặp vô hạn bằng phương thức của mình, điều này có nghĩa là EDT không được phép gọi phương thức PaintComponent(). Nó bị mắc kẹt trong một vòng lặp vô hạn.

Giải pháp cho vấn đề này là đặt gameLoop của bạn trên một chuỗi khác. Một cái gì đó như thế này:

khoảng trống công khai khởi tạo() {
super.setGameScreen(this.gameScreen);
this.game = true;
this.startGameLoop();
}

khoảng trống riêng tư startGameLoop() {
Chủ đề mới(){
công khai void run(){
trong khi(trò chơi) {
cập nhật();
kết xuất();
}
}
}.bắt đầu();
}

Chỉ cần đảm bảo mọi thay đổi đối với gui đều được thực hiện trên EDT. hãy nhìn xemsự đồng thờiXoay đồng thờiHướng dẫn để biết thêm chi tiết.

Về việc Java PaintComponent không được gọi khi sơn lại bằng Invokelat, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/21914497/

hai mươi bốn 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress