在Java中从另一个方法调用paint()

在Java中从另一个方法调用paint(),java,swing,graphics,components,paint,Java,Swing,Graphics,Components,Paint,我试图在Java中实现的是能够从另一种方法绘制随机形状,而不必从一开始就绘制这些形状(用户自己选择x、y、w、h) 以下是我到目前为止的情况: public class Design extends JComponent { private static final long serialVersionUID = 1L; public void paint(Graphics g) { super.paintComponent(g); } public void drawRect(in

我试图在Java中实现的是能够从另一种方法绘制随机形状,而不必从一开始就绘制这些形状(用户自己选择x、y、w、h)

以下是我到目前为止的情况:

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);
}
}
正如您在上面看到的,我对drawRect函数进行了编码,但不知道如何使其如此。当我调用drawRect()函数时,它会让paint()函数绘制一个矩形,而这正是paint函数所做的,在其中,您键入g.drawRect()和您的x,y,w,h。 我之所以这样做,而不仅仅是直接使用paint()是因为我正在尝试创建一个组件,所以我不必每次都键入paint()函数,而是将这个类添加到Swing中,这样就完成了

希望你能理解我在这里想要实现的目标。
谢谢。

您需要做的第一件事就是放弃您可以控制绘制过程的想法,您不能,您可以响应绘制事件并向
重新绘制管理器发出可能需要更新的请求

基本上,您不会直接调用
paint
,调用paint是为了响应
repaitmanager
想要绘制的内容

看一看

在你的代码上。不要覆盖
绘制
,当然也不要绕过绘制过程,相反,它应该看起来更像这样

@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
实际按该顺序获取参数
x
y
宽度
高度

我之所以这样做,而不仅仅是直接使用paint()是因为我试图制作一个组件,而不是每次都必须键入paint()函数

没有意义,这就是使用
paint
方法的意义所在,因此您可以自定义组件的绘制方式,创建大量实例并将其添加到GUI中…这就是所有Swing控件的工作方式

此外,您可能会发现您感兴趣的

根据评论更新

因此,您需要一个其他对象可以调用的方法,它将使他们能够向现有对象/组件添加一个“矩形”

首先定义一个实例变量
Rectangle

private Rectangle rectangle;
paintComponent
中,检查
rectangle
是否为
null
,如果不是,则绘制它

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (rectangle != null)  {
        Graphics2D g2d = (Graphics2D)g;
        g2d.draw(rectangle);
    }
}
现在,更新您的
drawRect
方法以创建一个实例
Rectangle
,并请求重新绘制组件

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

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();
    }
}

现在,如果您想支持多个矩形,只需使用
列表
并添加任意多个实例
矩形
,在
paintComponent
方法中迭代
列表
,您需要在
paintComponent()中进行所有绘制
方法,调用
super.paintComponent()

我建议您将所有需要的形状存储在
列表中
并在
paintComponent()
中绘制所有形状。 不要使用像
addRect
这样的东西,它可以向
列表中添加新形状,并调用
repaint()
方法。检查下一个简单示例:

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);
        }

    }

}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.Shape;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Random;
导入javax.swing.JButton;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
公共类TestFrame扩展了JFrame{
公共测试框架(){
System.out.println(“as.equalsIgnoreCase(null));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
包装();
setVisible(真);
}
私有void init(){
最终设计d=新设计();
d、 addRect(0,0,10,20);
JButton b=新JButton(“添加”);
b、 addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
随机r=新随机();
int w=r.nextInt(100);
int h=r.nextInt(100);
d、 addRect(0,0,w,h);
}
});
加(d);
增加(b,南部边界布局);
}
公共静态void main(字符串…字符串){
新的TestFrame();
}
私有类设计扩展了JComponent{
私有静态最终长serialVersionUID=1L;
私有列表形状=新的ArrayList();
公共空间涂料(图g){
超级组件(g);
Graphics2D g2d=(Graphics2D)g;
用于(形状s:形状){
g2d.图纸;
}
}
公共void addRect(int xPos、int yPos、int width、int height){
添加(新矩形(xPos、yPos、宽度、高度));
重新油漆();
}
@凌驾
公共维度getPreferredSize(){
返回新维度(100100);
}
}
}

感谢您的输入,就像您编写drawRect(g,10,10,10,10)的paintComponent()方法一样;但是我要做的是能够从另一个类中执行它,所做的就是在我调用这个方法的第二秒,它会强迫自己画一个矩形,我想要控制它,就像我希望的那样,就像这个类的一个实例。我不是被迫这样画一个长方形,我想怎么画就怎么画。是的,谢谢你,就像另一个人一样,这很完美。再次感谢您的快速支持,如果我还可以选择另一个,请考虑您自己的正确性。谢谢。谢谢大家的快速帮助!所以,我尝试了你在这里所做的一切,它实际上完全按照预期的那样工作!现在只需要添加更多的形状,但有一件事,当我尝试执行它时,矩形是由