使用自己的 Graphics 对象为我的 JPanel class 提供动态可运行对象?

Give dynamic runnables to my JPanel class using its own Graphics object?

好吧,听我说完。我目前有一个 class 类似于下面的:

public class GraphicsPanel extends JPanel {

    public void paint(Graphics g) {
       super.paintComponents(g);
       g.setColor(Color.RED);
       g.fillRect(100, 100, 100, 100);
    }
}

但显然这不是很有用,因为它唯一能做的就是制作 fillRect。现在我想要做的是让父 JFrame 能够将自定义指令传递给它的一个窗格,这样 GraphicsPanel 的每个实例都能够做一些不同的事情。我希望能够继续将指令作为可运行对象添加到对象中。我心中有一个总体设计:

public class GraphicsPanel extends JPanel {

private static final long serialVersionUID = 5890041512607678296L;
private java.util.List<Runnable> graphics = new ArrayList<Runnable>();

public void paint(Graphics g) {
    super.paintComponents(g);

    for (Runnable r: graphics) {
        r.run();
    }
}

public void addGraphics(Runnable r) {
    graphics.add(r);
}

public void clearGraphics() {
    graphics.clear();
}
}

在父框架的代码中会调用这样的东西:

graphicspane.addGraphics(() -> {
    g.fillOval(200, 200, 200, 200);
});

//Later, in a button ActionListener or some other event...
graphicspane.addGraphics(() -> {
    g.fillArc(200, 200, 200, 200, 13, 16);
});

//Also later, dynamically called by parent JFrame...
graphicspane.clearGraphics();

如您所见,我真正想要的是能够向 GraphicsPanel 提供动态指令。 问题是: 当我在父 JFrame 中创建可运行对象时,出于明显的原因,我无法使用 JPanel 的图形对象给出指令,因为我无法访问JFrame 范围内的本地图形参数 g

我很确定我想要做的是一种相当简单的事情,但从这里似乎没有明显的路径。如果您有关于放弃我当前的设计以获得更简单的设计的建议,请分享。有时我倾向于重新发明轮子,也许我在做这件事时完全错了。谢谢!

I currently have a class similar to the one below:

那不是你定制绘画的方式。

你应该:

  1. 覆盖 paintComponent(...) - 不是 paint()

  2. 然后调用 super.paintComponent(...) - 而不是 super.paintComponent()。

阅读有关 Custom Painting 的 Swing 教程部分,了解更多信息和工作示例。

pass custom instructions to one of its panes, so every instance of GraphicsPanel would be able to do something different. I want to be able to keep adding instructions as runnables to the object.

您不添加 Runnable 对象来进行绘画。 Swing 确定何时完成绘制,因此 paintComponent() 方法只是绘制面板的当前状态。

因此,要更改面板的状态,您可以保留要绘制的对象的 ArrayList。您创建一个方法来将要绘制的对象添加到 ArrayList。然后在 paintComponent() 方法中遍历 ArrayList 来绘制每个对象。

有关此方法的示例,请参阅 Custom Painting Approaches

在您的情况下,因为您想要绘制不同的对象,所以您需要将 Shape 个对象添加到 ArrayList。 Shape界面支持圆弧、矩形、椭圆等