了解java摆动的困难

时间:2016-04-09 14:41:20

标签: java swing java-2d

我试图通过点击JMenu在JPanel上绘制随机(尚未)圆圈。 我使用JTextField(并且必须保留它)用于某些输出。 这是我的班级:

class RandomDrawer extends JPanel implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        //double x = Math.random();
        //double y = Math.random();
        Random generator = new Random();
        int x = generator.nextInt(100)+1;
        int y = generator.nextInt(100)+1;
        //System.out.printf("x = %d y = %d\n", x, y);
        status.setText(String.format("rnd draw x: %d y: %d", x, y));
        Graphics2D gg = (Graphics2D) canvas.getGraphics();
        gg.setColor(Color.BLACK);
        gg.drawOval(50, 50, 50, 50);
    }
}

只要我放线

status.setText(String.format(“rnd draw x:%d y:%d”,x,y));

留在那里我什么都没画。没有它我得到我的圈子,我不知道问题是什么。我无法弄清楚为什么没有画出来。

非常感谢

编辑:

您好,我试图了解给定的信息。 遗憾的是我必须使用Graphics2D类绘制,所以我想我无法使用形状绘制。所以我试过这个,遗憾的是它还没有画出来,你能给我一些提示吗? 我试图创建一个新类DrawShape,我的想法是我可以跟踪这些对象。 根据我的理解,现在应该有一个绘制的椭圆形     gg.drawOval(100,100,100,100);

谢谢。

class DrawShape {
    public DrawShape(String string) {
        // TODO Auto-generated constructor stub
    }
}

class RandomDrawer extends JPanel implements ActionListener {
    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */ 
    private List<DrawShape> shapes = new ArrayList<DrawShape>();


    public void addShape(DrawShape s) {
        shapes.add(s);
        repaint();
    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        final Graphics2D gg = (Graphics2D) g;
        gg.setColor(Color.BLACK);
        gg.drawOval(100, 100, 100, 100);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        Random generator = new Random();
        int x = generator.nextInt(100)+100;
        int y = generator.nextInt(100)+100;

        if (e.getActionCommand()==("Draw RandomCircle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            status.setText(String.format("rnd draw x:%d  y:%d ", x, y));
            DrawShape circle = new DrawShape("Circle");
            addShape(circle);
            int count = shapes.size(); 
            System.out.printf("objects in array: %d\n", count); 
        }

        else if (e.getActionCommand()==("Draw RandomRectangle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            //status.setText(String.format("rnd draw x:  y: "));
            //Graphics2D gg = (Graphics2D) canvas.getGraphics();
            //gg.setColor(Color.BLACK);
            //gg.drawRect(x, y, generator.nextInt(x), generator.nextInt(y));
        }
    }
}

3 个答案:

答案 0 :(得分:2)

  

Graphics2D gg =(Graphics2D)canvas.getGraphics();

不要使用getGraphics()方法进行绘画。这幅画是暂时的。例如,如果您调整框架大小,它将会丢失。

相反,您需要覆盖面板的paintComponent()方法。

如果要绘制多个对象,则需要跟踪每个对象。查看Custom Painting Approaches以了解执行此操作的两种常用方法:

  1. 保留要绘制的对象列表,然后在每次重新绘制组件时遍历列表。
  2. 将Object直接绘制到BufferedImage,然后绘制BufferedImage。
  3. 该示例绘制矩形。基本上你需要像addRectangle(...)方法这样的方法来添加一个新对象来绘制。因此,每次单击按钮时,都会添加新的随机形状。

答案 1 :(得分:2)

据推测,您的问题源于setText()以某种意外方式修改Graphics对象的调用。在您自己的代码中使用getGraphics()很少是合适的。相反,使用提供给您的Graphics进行绘画。

你的方法无论如何都是有缺陷的。如果您设法仅在GUI组件上绘制一次,就像您尝试的那样,那么在下次重新绘制组件时,您绘制的任何内容都将消失。重绘可能由于各种原因而发生,其中许多原因与程序的行为无关。

您需要做的是存储组件的paintComponent()方法依赖的某些数据,以便每次进行自定义绘图。因此,您需要覆盖要绘制圆的组件的paintComponent()方法。例如,您可以创建一个类,记录一个圆圈所需的所有绘图详细信息,并将RandomDrawerList个对象作为成员变量。动作监听器适当地操作该列表并安排重新绘制,并覆盖paintComponent()以执行实际绘制。

答案 2 :(得分:2)

绘画和这样的事件驱动。如果需要重新绘制一个组件,则调用其paintComponent方法。

这意味着您需要一个能够如何绘制的组件,例如:

public class DrawShape {

    public final String text;
    public final Color color;
    public final Shape shape;

    public DrawShape(String text, Color color, Shape shape) {
        this.text = text;
        this.color = color;
        this.shape = shape;
    }
}

public class CanvasWithShapes extends JPanel {

    private List<DrawShape> shapes = new ArrayList<>();

    public void addShape(DrawShape shape) {
        shapes.add(shape);
    }

    @Override
    public void paintComponent(Graphics g) {
        final Graphics2D gg = (Graphics2D) g;
        // Java 8: shapes.stream().forEach((shape) -> gg.draw(shape));
        for (DrawShape drawShape : shapes) {
            gg.setColor(drawShape.color);
            gg.draw(drawShape.shape);
            Rectangle bounds = shape.getBounds();
            gg.drawString(shape.text, bounds.x+ 10, bounds.y + 20);
        }
    }
}

然后稍后再添加要重绘的形状。

Shape oval = ...;
c.add(oval);
c.repaint(50L); // A bit later 

更详细

Shape有许多感兴趣的实现,如矩形和椭圆形。 Graphics2D可以绘制和填充Shape。所以在你的情况下,添加这样的Shape是理想的。也许与颜色和文字一起。所以我拿着你的DrawShape类来保存这些属性。

    Random generator = new Random();
    int x = generator.nextInt(100)+100;
    int y = generator.nextInt(100)+100;

    if (e.getActionCommand().equals("Draw RandomCircle")) {
        System.out.printf("x = %d y = %d\n", x, y);
        status.setText(String.format("rnd draw x:%d  y:%d ", x, y));
        int w = generator.nextInt(100) + 10;
        int h = w;
        Shape circle = new Ellipse2D.Double(x, y, w, h);
        addShape(new DrawShape(text, Color.BLACK, circle));
        int count = shapes.size(); 
        System.out.printf("objects in array: %d\n", count); 
    } else if (e.getActionCommand().equals("Draw RandomRectangle")) {
        System.out.printf("x = %d y = %d\n", x, y);

generator.nextInt(Y));             int w = generator.nextInt(100)+ 10;             int h = generator.nextInt(100)+ 10;             形状rect = Rectangle2D.Double(x,y,w,h)             addShape(new DrawShape(text,Color.BLACK,rect));         }