paintComponent中的if语句使它不能绘制

时间:2013-12-27 07:32:36

标签: java if-statement paintcomponent

我正在尝试写一个单人纸牌游戏 我希望在比赛开始时给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
这使得整个事情都没有油漆。

3 个答案:

答案 0 :(得分:2)

正在发生的事情是,使用paintComponent方法对该类进行初始实例化时,paintComponent方法被调用一次。因此,绘制将出现一次,但之后不再出现,因为在初始实例化中第一次调用initiaDrawingpaintComponent被设置为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);
}

然而,这表明,初始化应该在其他地方完成,也许在构造函数中完成。一般来说,绘画代码应该只绘画,可以多次调用。