简体   繁体   English

从Java中的另一种方法调用paint()

[英]Calling paint() from another method in Java

what I am trying to achieve in Java is to be able to paint random shapes from another method without having to have those shapes already drawn from the start (user picks x, y, w, h themselves) 我想要在Java中实现的目标是能够从另一种方法绘制随机形状,而不必一开始就已经绘制出这些形状(用户自己选择x,y,w,h)

Here is what I have so far: 这是我到目前为止的内容:

public class Design extends JComponent {
private static final long serialVersionUID = 1L;

public void paint(Graphics g) {
    super.paintComponent(g);
}

public void drawRect(int xPos, int yPos, int width, int height) {
    Graphics g = null;
    g.drawRect(width, height, xPos, yPos);
}
}

As you can see above, I have the drawRect function coded but do not understand how to make it so when I call the drawRect() function, it gets the paint() function to draw a rectangle instead which is EXACTLY what the paint function does, inside it, you type g.drawRect() and your x,y,w,h. 正如您在上面看到的那样,我已经编码了drawRect函数,但不了解如何实现,因此当我调用drawRect()函数时,它将获得paint()函数来绘制矩形,而这恰恰是paint函数的作用,在其中键入g.drawRect()和x,y,w,h。 The reason why I am doing this and not just straight up using paint() is because i'm trying to make a component so instead of having to type out the paint() function everytime, I just add this class to my Swing and it's done. 我这样做而不是直接使用paint()的原因是因为我试图制造一个组件,所以不必每次都键入paint()函数,只需将此类添加到我的Swing中,完成。

Hope you understand what I'm trying to achieve here. 希望您理解我在这里想要实现的目标。 Thanks. 谢谢。

The first thing you need to do is let go of the idea that you can control the paint process, you can't, you can respond to paint events and make requests to the RepaintManager that an update might be needed. 您需要做的第一件事就是放开您可以控制绘制过程的想法,不能,您不能响应绘制事件,并向RepaintManager发出可能需要更新的请求。

Basically, you don't call paint directly, paint is called in response to the RepaintManager wanting something painted. 基本上,您不直接调用paint ,而是响应RepaintManager想要绘制的东西而调用paint

Take look at Painting in AWT and Swing and Performing Custom Painting . AWT中的绘画和摆动执行自定义绘画

On to your code. 转到您的代码。 Don't override paint and certainly don't circumvent the paint process, instead, it should look something more like this... 不要覆盖paint ,当然也不要绕过油漆过程,相反,它应该看起来像这样……

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    drawRect(g, 10, 10, 10, 10);
}

protected void drawRect(Graphics g, int xPos, int yPos, int width, int height) {
    g.drawRect(xPos, yPos, width, height);
}

Graphics#drawRect actually takes parameters x , y , width , height in that order... Graphics#drawRect实际上按该顺序获取参数xywidthheight ...

The reason why I am doing this and not just straight up using paint() is because i'm trying to make a component so instead of having to type out the paint() function every time 我这样做而不是直接使用paint()的原因是因为我试图制造一个组件,而不是每次都必须键入paint()函数

Doesn't make sense, that's the point of having the paint methods, so you can customise the way a component is paint, make lots of instances of it and add it your GUI...this is how all the Swing controls work... 没道理,那是拥有paint方法的关键所在,因此您可以自定义组件的绘制方式,制作许多实例,然后将其添加到GUI中...这就是所有Swing控件的工作方式。 。

Also, you might find 2D Graphics of interest 另外,您可能会发现感兴趣的2D图形

Updated based on comments 根据评论更新

So, you want a method that some other object can call and it will enable them to add a "rectangle" to the the existing object/component... 因此,您需要一个其他对象可以调用的方法,它将使它们能够向现有对象/组件添加“矩形”。

Start by defining an instance variable of Rectangle 首先定义Rectangle的实例变量

private Rectangle rectangle;

In your paintComponent , check to see if rectangle is null or not and if it's not, paint it... paintComponent ,检查rectangle是否为null ,如果不是,则将其绘制...

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (rectangle != null)  {
        Graphics2D g2d = (Graphics2D)g;
        g2d.draw(rectangle);
    }
}

Now, update your drawRect method to create an instance Rectangle and request that the component be repainted 现在,更新您的drawRect方法以创建一个Rectangle实例,并要求对该组件重新粉刷

public void drawRect(int xPos, int yPos, int width, int height) {
    rectangle = new Rectangle(xPos, yPos, width, height);
    repaint();
}

For example... 例如...

public class Design extends JComponent {

    private Rectangle rectangle;

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (rectangle != null)  {
            Graphics2D g2d = (Graphics2D)g;
            g2d.draw(rectangle);
        }
    }

    public void drawRect(int xPos, int yPos, int width, int height) {
        rectangle = new Rectangle(xPos, yPos, width, height);
        repaint();
    }
}

Now, if you want to support having multiple rectangles, you could simply use a List and add as many instances Rectangle as you want, iterating over the List in the paintComponent method 现在,如果要支持具有多个矩形,则可以简单地使用List并根据需要添加任意数量的Rectangle实例,然后在paintComponent方法中遍历List

You need to do all paintings inside paintComponent() method with calling super.paintComponent() . 您需要通过调用super.paintComponent()paintComponent()方法内进行所有绘画。

I suggest you to store all needed shapes in List and draw all of them in paintComponent() . 我建议您将所有需要的形状存储在List ,并在paintComponent()绘制所有形状。 Instead of drawRect use something like addRect which adding new shape to your List and call repaint() method. 除了使用drawRect使用诸如addRect类的addRect ,该方法会为List添加新形状并调用repaint()方法。 Examine next simple example: 检查下一个简单的例子:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

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

public class TestFrame extends JFrame {

    public TestFrame() {
        System.out.println("as".equalsIgnoreCase(null));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        init();
        pack();
        setVisible(true);
    }

    private void init() {
        final Design d = new Design();
        d.addRect(0,0,10,20);

        JButton b = new JButton("add");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Random r = new Random();
                int w = r.nextInt(100);
                int h = r.nextInt(100);
                d.addRect(0,0,w,h);
            }
        });
        add(d);
        add(b,BorderLayout.SOUTH);
    }

    public static void main(String... strings) {
        new TestFrame();
    }

    private class Design extends JComponent {
        private static final long serialVersionUID = 1L;

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

        public void paint(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for(Shape s : shapes){
                g2d.draw(s);
            }
        }

        public void addRect(int xPos, int yPos, int width, int height) {
            shapes.add(new Rectangle(xPos,yPos,width,height));
            repaint();
        }

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

    }

}

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

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