我正在尝试写一个单人纸牌游戏
我希望在比赛开始时给repaint()
打电话并画上完整的牌组
曾经只有第一次调用重绘,但是当我添加if-statement
它时
不再画画了
以下是带有if语句的代码:
private void paintInitialDeck(Graphics g, Card card){
card.paintCard(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (initialDrawing) {
Card card;
for (int i = 0; i < deck.size(); i++) {
card = deck.get(i);
card.setY((int) (50 + 0.2 * i));
card.setX((int) (250 + 0.2 * i));
paintInitialDeck(g, card);
}
initialDrawing = false;
}
}
它不起作用,但如果我删除if语句和initialDrawing = false
然后它起作用。
问题是,我需要if语句
谁能帮助我更好地理解这一点?
ps。:beginDrawing设置为true以开始。此外,它确实是 initialDrawing = false
这使得整个事情都没有油漆。
答案 0 :(得分:2)
正在发生的事情是,使用paintComponent
方法对该类进行初始实例化时,paintComponent
方法被调用一次。因此,绘制将出现一次,但之后不再出现,因为在初始实例化中第一次调用initiaDrawing
后paintComponent
被设置为false。因此,在程序中调用repaint()
将无效,因为initialDrawing
在首次启动绘制过程后将为false。
我不确定你是否在第一次启动程序时看到油漆,但这就是原因,它不允许你在程序启动后再次绘画。
可能的修复方法可能是将initialDrawing
初始化为false,因此它最初不会绘制。然后,无论组件调用repaint()
方法,在操作中,首先将inititialDrawing
设置为true,然后调用repaint()
。禁用该组件,以便无法再次调用repaint()
。 (或具有这种逻辑性质的东西)。
这是一个例子
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DisablePaint extends JPanel {
ImagePanel panel;
JButton button;
boolean intialDraw = false;
public DisablePaint() {
button = new JButton("Paint Once");
setLayout(new BorderLayout());
panel = new ImagePanel();
add(panel, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
intialDraw = true;
panel.repaint();
button.setEnabled(false);
}
});
}
private class ImagePanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (intialDraw) {
g.setColor(Color.BLUE);
g.fillRect(50, 50, 200, 200);
initialDraw = false;
}
}
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new DisablePaint());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
您可以看到initialDraw
首先设置为false,因此它不会在程序的初始启动时绘制。然后,我在repaint()
中拨打actionPerformed
,但首先将intialDrawing
设置为true。然后禁用该按钮,不允许另一个初始绘画
答案 1 :(得分:1)
使用if语句,您的卡片只会在第一次拨打paintComponent()
时被提取。之后,该方法将仅调用super.paintComponent()
,删除之前在组件上绘制的任何内容。
由于您在调用paintComponent()
时没有很多控制权,因此最好避免在应用程序逻辑中包含与之相关的任何行为,就像使用if语句一样。
这是一段任意代码。尝试编译此示例并查看“重绘”的次数。
import javax.swing.*;
import java.awt.*;
public class Test {
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.add(new JPanel() {
public void paintComponent(Graphics g)
{
super.paintComponents(g);
System.out.println("Repainted");
}
});
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
答案 2 :(得分:0)
直接的解决方案是
if (initialDrawing) {
Card card;
for (int i = 0; i < deck.size(); i++) {
card = deck.get(i);
card.setY((int) (50 + 0.2 * i));
card.setX((int) (250 + 0.2 * i));
}
initialDrawing = false;
}
for (Card card : deck) {
card.paintCard(g);
}
然而,这表明,初始化应该在其他地方完成,也许在构造函数中完成。一般来说,绘画代码应该只绘画,可以多次调用。