首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未调用Repaint()

未调用Repaint()
EN

Stack Overflow用户
提问于 2013-02-11 06:57:03
回答 3查看 361关注 0票数 1

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

代码语言:javascript
复制
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;
        }
    }
}

为什么这段代码不能正常工作?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-11 07:52:40

为了补充其他答案,这里有一段代码(基于你的),它看起来已经好多了(但仍然存在一些问题,但你还没有做到):

代码语言:javascript
复制
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;
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2013-02-11 07:49:40

绘制是暂时的,或者说是无状态的。

repaint是一个向重绘管理器发出的“请求”,告诉它应该在将来的某个时候,当它准备好的时候,应该绘制屏幕的某一部分,它认为这是脏的。

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

Raufio是对的,你应该在提供形状的同时提供颜色信息。就我个人而言,我会设置第二个List,它只包含Color对象,其中Shape列表的每个索引都直接对应于Color List中的Color

有关如何在Swing中进行绘制的更多详细信息,请查看Painting in AWT and Swing

现在,到了发牢骚的部分;)

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

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

有关更多详细信息,请查看Performing Custom Painting

使用粗略示例进行更新

这是我所说的一个粗略的例子。

代码语言:javascript
复制
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();

        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2013-02-11 07:08:43

我看到的第一件事是,你一次只能给形状着色一种颜色。所以这里:

代码语言:javascript
复制
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
    }
}

当您想用不同的颜色绘制所有形状时,它们将以相同的颜色绘制。此外,我会将paint方法更改为以下效果:

代码语言:javascript
复制
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) {...}块,而不是直接将其抛出。类似于:

代码语言:javascript
复制
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();
    }
}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14803590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档