绘制程序不使用并行数组来正确存储大小和颜色

时间:2014-09-09 16:40:46

标签: java arrays swing arraylist paintcomponent

这是一个简单的Paint风格程序,它基于使用数组和arraylists来保存使用JFrame,paintComponent和各种鼠标侦听器在屏幕上绘制的不同点的坐标,大小和颜色。

我最近解决了一个问题,它会吐出一个ArrayOutOfBounds错误并指向第34行,其颜色数组超过其限制10000.但是我需要运行程序,每个点的大小和颜色相互平行所以每次程序重新绘制点时,每个都保留自己的大小和颜色变量。感谢您的投入!

    import java.util.ArrayList;
    import javax.swing.JPanel;
    import java.awt.*;
    import java.awt.event.*;

    public class Proj1Panel extends JPanel{
        public int SIZE = 5, c = 0, s = 0;

        private ArrayList<Point> pointList;
        public int[] sizes;
        public Color[] colors;

        public Proj1Panel(){
            pointList = new ArrayList<Point>();
            sizes = new int[10000];
            colors = new Color[10000];

            addMouseListener (new Proj1Listener());
            addMouseMotionListener (new Proj1Listener());
            addMouseWheelListener (new Proj1Listener());

            setBackground(Color.black);
            setPreferredSize(new Dimension(300, 200));
        }
        public void paintComponent(Graphics page){
            super.paintComponent(page);
            for(Point spot : pointList){
                page.setColor(colors[c]);
                page.fillRect(spot.x-sizes[pointList.size()], spot.y-sizes[pointList.size()], sizes[pointList.size()]*2, sizes[pointList.size()]*2);
                c = 0;
            }
            repaint();
            page.setColor(Color.RED);
            page.fillRect(5, 40, 30, 30);
            page.setColor(Color.BLUE);
            page.fillRect(5, 75, 30, 30);
            page.setColor(Color.GREEN);
            page.fillRect(5, 110, 30, 30);
            page.setColor(Color.WHITE);
            page.fillRect(5, 145, 30, 30);
            page.setColor(Color.WHITE);
            page.drawString("Count: " + pointList.size() + "/10000", 5, 15);
            page.drawString("Size: " + SIZE, 5, 30);
        }
        private class Proj1Listener implements MouseListener, MouseMotionListener, MouseWheelListener{
            public void mousePressed(MouseEvent event){
                pointList.add(event.getPoint());
                sizes[pointList.size()] = SIZE;
                repaint();
            }
            public void mouseDragged(MouseEvent event){
                pointList.add(event.getPoint());
                sizes[pointList.size()] = SIZE;
                repaint();
            }
            public void mouseWheelMoved(MouseWheelEvent event){
                SIZE -= event.getWheelRotation();
                repaint();
            }
            public void mouseClicked(MouseEvent event){
                int x1 = event.getX();
                int y1 = event.getY();
                if(x1 > 5 && x1 < 35 && y1 > 40 && y1 < 70){
                    colors[c] = Color.RED;
                }
                if(x1 > 5 && x1 < 35 && y1 > 75 && y1 < 105){
                    colors[c] = Color.BLUE;
                }
                if(x1 > 5 && x1 < 35 && y1 > 110 && y1 < 140){
                    colors[c] = Color.GREEN;
                }
                if(x1 > 5 && x1 < 35 && y1 > 145 && y1 < 175){
                    colors[c] = Color.WHITE;
                }
            }
            public void mouseReleased(MouseEvent event){}
            public void mouseEntered(MouseEvent event){}
            public void mouseExited(MouseEvent event){}
            public void mouseMoved(MouseEvent event){}
        }
    }

修改
我能够解决我的程序问题。在绘制循环之前,我不得不重置几个变量。这是工作计划!

import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;

public class Proj1Panel extends JPanel{
    public int SIZE = 5, c = 0, s = 0;
    private ArrayList<Point> pointList;
    private int[] sizes;
    private Color[] colors;
    public String colorIs = "WHITE";

    public Proj1Panel(){
        pointList = new ArrayList<Point>();
        sizes = new int[1000000];
        colors = new Color[1000000];

        addMouseListener (new Proj1Listener());
        addMouseMotionListener (new Proj1Listener());
        addMouseWheelListener (new Proj1Listener());

        setBackground(Color.black);
        setPreferredSize(new Dimension(300, 200));
    }
    public void paintComponent(Graphics page){
        super.paintComponent(page);
        page.setColor(Color.WHITE);
        c = 0;
        s = 0;
        for(Point spot : pointList){
            page.setColor(colors[c]);
            page.fillRect(spot.x-sizes[s], spot.y-sizes[s], sizes[s]*2, sizes[s]*2);
            c++;
            s++;
        }
        repaint();
        page.setColor(Color.BLACK);
        page.fillRect(0, 0, 150, 35);
        page.setColor(Color.BLACK);
        page.fillRect(0, 35, 40, 180);
        page.setColor(Color.RED);
        page.fillRect(5, 40, 30, 30);
        page.setColor(Color.BLUE);
        page.fillRect(5, 75, 30, 30);
        page.setColor(Color.GREEN);
        page.fillRect(5, 110, 30, 30);
        page.setColor(Color.WHITE);
        page.fillRect(5, 145, 30, 30);
        page.setColor(Color.WHITE);
        page.fillRect(5, 180, 30, 30);
        page.setColor(Color.BLACK);
        page.fillRect(7, 182, 26, 26);
        page.setColor(Color.WHITE);
        page.drawString("Count: " + pointList.size() + "/1000000", 5, 15);
        page.drawString("Size: " + SIZE, 5, 30);
        page.drawString("Color: ", 65, 30);
        page.drawString(colorIs, 100, 30);
    }
    private class Proj1Listener implements MouseListener, MouseMotionListener, MouseWheelListener{
        public void mousePressed(MouseEvent event){
            pointList.add(event.getPoint());
            sizes[pointList.size()] = SIZE;
            repaint();
        }
        public void mouseDragged(MouseEvent event){
            pointList.add(event.getPoint());
            sizes[pointList.size()] = SIZE;
            repaint();
        }
        public void mouseWheelMoved(MouseWheelEvent event){
            SIZE -= event.getWheelRotation();
            repaint();
        }
        public void mouseClicked(MouseEvent event){
            int x1 = event.getX();
            int y1 = event.getY();
            if(x1 > 5 && x1 < 35 && y1 > 40 && y1 < 70){
                colors[c] = Color.RED;
                colorIs = "RED";
            }
            if(x1 > 5 && x1 < 35 && y1 > 75 && y1 < 105){
                colors[c] = Color.BLUE;
                colorIs = "BLUE";
            }
            if(x1 > 5 && x1 < 35 && y1 > 110 && y1 < 140){
                colors[c] = Color.GREEN;
                colorIs = "GREEN";
            }
            if(x1 > 5 && x1 < 35 && y1 > 145 && y1 < 175){
                colors[c] = Color.WHITE;
                colorIs = "WHITE";
            }
            if(x1 > 5 && x1 < 35 && y1 > 180 && y1 < 210){
                colors[c] = Color.black;
                colorIs = "BLACK";
            }
        }
        public void mouseReleased(MouseEvent event){}
        public void mouseEntered(MouseEvent event){}
        public void mouseExited(MouseEvent event){}
        public void mouseMoved(MouseEvent event){}
    }
}

2 个答案:

答案 0 :(得分:2)

您永远不会将用作颜色数组索引的c变量重置为paintComponent方法中的0。而是在程序开始时将其设置为0。因此它将单调增加,直到阵列溢出。考虑在paintComponent的开头将其重置为0.

另外,你使用的是哪种Point类?它包含一些我们没有看到的数组。这里:

spot.x-sizes[pointList.size()]

修改
我道歉,因为我误读了你的代码,而且我也没有很好地解释我的答案。您仍应增加c变量,但应在paintcomponent的开始处将其重新设置为0。例如:

public void paintComponent(Graphics page) {
  super.paintComponent(page);
  c = 0;  // each time paintComponent starts, c should be 0
  for (Point spot : pointList) {
     page.setColor(colors[c]);
     page.fillRect(spot.x - sizes[pointList.size()], spot.y
           - sizes[pointList.size()], sizes[pointList.size()] * 2,
           sizes[pointList.size()] * 2);
     c++;  // but within the for loop, it should increment.
  }
  // .... etc

或者,不要使用for-each循环,而是使用基本for循环,这样你甚至不需要c变量。

答案 1 :(得分:1)

创建一个自定义对象,以包含绘制所需的信息。这是您的自定义对象可以包含要绘制的颜色和矩形。

有关如何执行此操作的示例,请参阅Custom Painting Approaches,然后更改代码以使用自定义对象。您可以使用DrawOnComponent示例。

  

我的教授希望pointList中的每个点都可以在框架上绘制,并具有自己相应的大小和颜色,指向两个大小和颜色的平行数组。

我刚刚阅读了上述评论,所以我的建议并没有帮助。但是,看一下这个例子看每次添加一个&#34;点&#34;在ArrayList的顶部,您还需要同时设置颜色和大小。即使我的代码使用了Rectangle,代码也需要相同的逻辑。

另外,为什么你有一个数据结构作为ArrayList和另外两个结构作为数组。 (告诉教授)这是一个可怕的要求。 ArrayList可以增长到任何大小,但是Arrays是硬编码,可以达到幻数1000.