graphics.setColor(color); 不工作

Rof*_*Rof 2 java graphics rgb awt jframe

我试图用颜色创建一个小小的塔防游戏但是颜色不起作用,这就是我绘制矩形的方法。

public static void fill(GridLocation loc, Color c){
    Main.frame.getGraphics().setColor(c);
    Main.frame.getGraphics().fillRect(loc.toFrameLocation().x, loc.toFrameLocation().y, 20, 20);
    Main.frame.getGraphics().dispose();
}
Run Code Online (Sandbox Code Playgroud)

这就是我调用/创建JFrame的方式

public static void main(String[] args) {
    frame = new JFrame("Tower defense");
    frame.setSize(1000, 700);
    frame.setVisible(true);
    frame.setLayout(null);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    while (frame.isVisible()){
        Grid.fill(new GridLocation(1,1), new Color(1F,0F,0F));
        Grid.fill(new GridLocation(2,1), Color.gray);
        Grid.drawGrid();
        Grid.fill(new GridLocation(3,1), Color.green);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题:矩形始终是黑色的?

Don*_*ter 5

请注意,如果getGraphics()在组件上使用以获取Graphics上下文,则由此获得的图形将不会保留。例如,在下面的代码中,您将看到,如果按下按钮,则会出现一个蓝色矩形,但是如果将GUI最小化并随后调整大小,则该蓝色矩形会消失。

另外,根据我的评论:

  1. 绘制JPanel的paintComponent方法。
  2. 使用Swing计时器不要一会儿(true)循环。
  3. 在该Timer中,更改绘图JPanel的状态(更改其字段),然后调用repaint()。
  4. 然后让paintComponent方法使用这些字段来告诉它如何绘制。
  5. 不要忘记在您的替代中调用super的绘画方法。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class UnstableStableGraphics extends JPanel {
    private static final int PREF_W = 800;
    private static final int PREF_H = 400;
    private static final int GAP = 20;

    public UnstableStableGraphics() {
        add(new JButton(new DrawBlueRectAction()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED);
        int w = PREF_W / 2 - 2 * GAP;
        int h = PREF_H - 2 * GAP;
        g.fillRect(GAP, GAP, w, h);     
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_H);
    }

    private class DrawBlueRectAction extends AbstractAction {
        public DrawBlueRectAction() {
            super("Draw Unstable Blue Rectangle");
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            Graphics g = getGraphics();
            g.setColor(Color.BLUE);
            int x = PREF_W / 2 + GAP;
            int w = PREF_W / 2 - 2 * GAP;
            int h = PREF_H - 2 * GAP;
            g.fillRect(x, GAP, w, h);
            g.dispose();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        UnstableStableGraphics mainPanel = new UnstableStableGraphics();
        JFrame frame = new JFrame("UnstableStableGraphics");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,最好使用通过getGraphics()在BufferedImage上调用来获得的Graphics对象(只要在完成后处置Graphics对象,在完成后节省资源),然后通常在paintComponent方法中显示该图像即可。作为背景图片。但是,通常,我调用createGraphics()BufferedImage,因为它返回的是功能更强大的Graphics2D对象,而不是Graphics对象。

例如,包括使用背景图像,子画面图像和Swing计时器:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class BackgroundExample extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = PREF_W;
    private static final int SPRITE_W = 20;
    private static final Color SPRITE_COLOR = Color.RED;
    private static final int TIMER_DELAY = 20;
    private Image background = null;
    private Image sprite = null;
    private int spriteX = 0;
    private int spriteY = 0;

    public BackgroundExample() {
        background = createBackground();
        sprite = createSprite();

        new Timer(TIMER_DELAY, new TimerListener()).start();
    }

    private Image createSprite() {
        BufferedImage img = new BufferedImage(SPRITE_W, SPRITE_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(SPRITE_COLOR);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int x = 1;
        int y = 1;
        int width = SPRITE_W -2;
        int height = SPRITE_W - 2;
        g2.fillOval(x, y, width, height);
        g2.dispose();
        return img;
    }

    private Image createBackground() {
        BufferedImage img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(Color.GREEN);
        g2.fillRect(0, 0, PREF_W, PREF_H);
        g2.setColor(Color.GRAY);
        int x = 0;
        int y = 0;
        g2.fillRect(x, y, 2 * SPRITE_W, 2 * SPRITE_W);
        x = PREF_W - 2 * SPRITE_W;
        g2.fillRect(x, y, 2 * SPRITE_W, 2 * SPRITE_W);
        y = PREF_H - 2 * SPRITE_W;
        g2.fillRect(x, y, 2 * SPRITE_W, 2 * SPRITE_W);
        x = 0;
        g2.fillRect(x, y, 2 * SPRITE_W, 2 * SPRITE_W);
        g2.dispose();
        return img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (background != null) {
            g.drawImage(background, 0, 0, this);
        }
        if (sprite != null) {
            g.drawImage(sprite, spriteX, spriteY, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        } else {
            return new Dimension(PREF_W, PREF_H); 
        }
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            spriteX++;
            spriteY++;
            repaint();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        BackgroundExample mainPanel = new BackgroundExample();
        JFrame frame = new JFrame("BackgroundExample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)