graphics.setColor(颜色);不工作

时间:2016-12-25 13:22:16

标签: java graphics jframe awt rgb

我正在尝试使用颜色创建一个小型塔防游戏但是这里的颜色不起作用我是如何绘制rects做图形的。

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();
}

并且这就是我调用/创建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);
    }
}

我的问题:矩形总是黑色的?

1 个答案:

答案 0 :(得分:5)

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

另外,根据我的评论:

  1. 在JPanel的paintComponent方法中绘制。
  2. 使用Swing Timer而不是while(true)循环。
  3. 在该Timer中,更改绘图JPanel的状态(更改其字段),然后调用repaint()。
  4. 然后让paintComponent方法使用字段来告诉它如何绘制。
  5. 别忘了在你的覆盖中调用超级绘画方法。
  6. 例如:

    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);
        }
    }
    

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

    例如,包括使用背景图像,精灵图像和Swing Timer:

    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);
        }
    }