繁体   English   中英

Repaint()没有被调用

[英]Repaint() not being called

最近,我一直在研究一个程序,该程序使用空的彩色正方形绘制区域。 它们在屏幕上的位置基于文本文件中的值1和2。 1应该被做成红色的盒子,而2应该被做成绿色的盒子。 但是,当我运行该程序时,只绘制了红色框。 我进行了一些测试,发现repaint方法仅被调用两次(有时由于某种原因有时被调用),即使文件中有接近300个值,并且应该为每个值调用一次repaint() 这是我的代码:

public class MAP extends JFrame {

    public static void main(String[] args) throws IOException {
        MAP map = new MAP();
    }

    Shape shape;
    int x = -32;
    int y = 0;
    ArrayList<Shape> shapes = new ArrayList<Shape>();
    Graphics2D g2;
    Color coulor = null;

    private class PaintSurface extends JComponent {

        public PaintSurface() {
        }

        public void paint(Graphics g) {
            g2 = (Graphics2D) g;
            g2.setColor(coulor);
            for (Shape s : shapes) {
                g2.draw(s);
            }

        }
    }

    public MAP() throws FileNotFoundException, IOException {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.add(panel);
        frame.setTitle("Grid Maker");
        frame.setSize(400, 200);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.add(new PaintSurface(), BorderLayout.CENTER);
        frame.setVisible(true);

        readNextLine();
    }

    private void readNextLine() throws IOException {
        File file = new File("map.txt");
        BufferedReader in = new BufferedReader(new FileReader(file));
        String line = in.readLine();

        while (line != null) {
            for (int i = 0; i < line.length(); i++) {
                char c = line.charAt(i);
                if (c == '1') {
                    coulor = Color.RED;
                    x += 32;
                    int smallX = x / 32;
                    int smallY = y / 32;
                    shape = new Rectangle2D.Float(x, y, 32, 32);
                    shapes.add(shape);
                    repaint();
                } else if (c == '2') {
                    coulor = Color.GREEN;
                    x += 32;
                    int smallX = x / 32;
                    int smallY = y / 32;
                    shape = new Rectangle2D.Float(x, y, 32, 32);
                    shapes.add(shape);
                    repaint();

                }
            }

            line = in.readLine();
            x = -32;
            y += 32;
        }
    }
}

为什么此代码无法正常工作?

绘画是短暂的或无状态的。

repaint是对重新绘制管理器发出的“请求”,告诉它应该在将来的某个时候准备就绪时绘制屏幕的某些部分,认为它是脏的。

这意味着,当您在paint方法中调用g2.setColor(coulor)时,它使用的是设置为LAST的值(当paint被调用时)....这可能是RED

Raufio是正确的,您应该随形状一起提供颜色信息。 就个人而言,我会成立第二个List刚刚包含Color的对象,其中的每个索引Shape列表直接对应的ColorColor List

查阅AWT和Swing中的绘画,以获得有关Swing中绘画工作原理的更多详细信息。

现在,到了令人苦恼的部分;)

不建议覆盖paint 造成这种情况的原因很多, paint负责调用许多重要的方法,包括paintChildrenpaintComponent ,它们执行非常重要的任务。

相反,您应该重写paintComponent (并确保调用super.paintComponent

请查看执行自定义绘画以获取更多详细信息。

用粗略的例子更新

所以这是我在说的一个粗糙的例子...

在此处输入图片说明

public class TestPainting {

    public static void main(String[] args) {
        new TestPainting();
    }

    public TestPainting() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PaintingPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintingPane extends JPanel {

        private static final int WIDTH = 200;
        private static final int HEIGHT = 200;

        private List<Shape> shapes;
        private List<Color> colors;

        public PaintingPane() {
            shapes = new ArrayList<>(25);
            colors = new ArrayList<>(25);

            for (int index = 0; index < (int) Math.round(Math.random() * 100); index++) {

                int x = (int) Math.round(Math.random() * (WIDTH * 0.75f));
                int y = (int) Math.round(Math.random() * (HEIGHT * 0.75f));
                int width = (int) Math.round(Math.random() * (WIDTH * 0.25f));
                int height = (int) Math.round(Math.random() * (HEIGHT * 0.25f));

                if (width < 5) {
                    width = 5;
                }
                if (height < 5) {
                    height = 5;
                }

                if (x + width > WIDTH) {
                    x -= width - WIDTH;
                }
                if (y + height > HEIGHT) {
                    y -= height - HEIGHT;
                }
                if (x < 0) {
                    x = 0;
                }
                if (y < 0) {
                    y = 0;
                }

                Color color = ((int)Math.round(Math.random() * 2)) == 1 ? Color.RED : Color.GREEN;

                shapes.add(new Rectangle(x, y, width, height));
                colors.add(color);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(WIDTH, HEIGHT);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (int index = 0; index < shapes.size(); index++) {
                g2d.setColor(colors.get(index));
                g2d.draw(shapes.get(index));
            }
            g2d.dispose();

        }
    }
}

只是为了增加其他答案,以下是一段代码(基于您的代码),看起来看起来已经好了很多(但是仍然存在一些问题,但是您还不存在):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class MAP extends JFrame {

    public static void main(String[] args) throws IOException {
        MAP map = new MAP();
    }

    public static class ColoredShape {
        private Shape shape;
        private Color color;

        public ColoredShape(Shape shape, Color color) {
            super();
            this.shape = shape;
            this.color = color;
        }

        public Shape getShape() {
            return shape;
        }

        public Color getColor() {
            return color;
        }
    }

    int x = -32;
    int y = 0;
    List<ColoredShape> shapes = new ArrayList<ColoredShape>();
    Graphics2D g2;

    private class PaintSurface extends JComponent {

        public PaintSurface() {
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g2 = (Graphics2D) g;
            for (ColoredShape s : shapes) {
                g2.setColor(s.getColor());
                g2.draw(s.getShape());
            }

        }
    }

    public MAP() throws FileNotFoundException, IOException {
        JFrame frame = new JFrame();
        frame.setTitle("Grid Maker");
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.add(new PaintSurface(), BorderLayout.CENTER);
        frame.setVisible(true);

        readNextLine();
    }

    private void readNextLine() throws IOException {
        BufferedReader in = new BufferedReader(new StringReader("11121\n1221\n2212\n221121\n111221\n11221\n222\n2222\n"));
        String line = in.readLine();

        while (line != null) {
            for (int i = 0; i < line.length(); i++) {
                char c = line.charAt(i);
                Color color = null;
                if (c == '1') {
                    color = Color.RED;
                } else if (c == '2') {
                    color = Color.GREEN;
                }
                if (color != null) {
                    shapes.add(new ColoredShape(new Rectangle2D.Float(x, y, 32, 32), color));
                    x += 32;
                    repaint();
                }
            }

            line = in.readLine();
            x = -32;
            y += 32;
        }
    }
}

我看到的第一件事是,您一次只能为一种形状上色一种颜色。 所以在这里:

public void paint(Graphics g) {
    g2 = (Graphics2D) g;
    g2.setColor(coulor);        //set the drawing color
    for (Shape s : shapes) {
         g2.draw(s);            //draw in that color
    }
}

当您要为不同形状着色时,所有形状均以相同颜色绘制。 我认为一种更好的处理方法是将所有形状添加到列表中,跟踪其颜色,然后一次调用repaint() 另外,我将Paint方法更改为以下效果:

public void paint(Graphics g) {
    g2 = (Graphics2D) g;
    for (Shape s : shapes) {
         g2.setColor(coulor[indexOfShape]);   //set the drawing color
         g2.draw(s);            //draw in that color
    }
}

另外,对于repaint仅被调用两次:它可能抛出IOException 尝试使用try {...} catch(IOException e) {...}块,而不是仅仅将其扔在一行上。 就像是:

private void readNextLine() {
    try {
       File file = new File("map.txt");
       BufferedReader in = new BufferedReader(new FileReader(file));
       String line = in.readLine();
       ...
       ...
    } catch (IOException e) {
       e.printStackTrace();
    }
}

如果阅读不正确,它应该抱怨一些东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM