1


我正在尝试从列表数组呈现到 JPanel。我已经创建了自己的 2D 渲染器,但是当我尝试使用 RenderAdd 函数添加到列表中时,它要么不添加,要么列表数组不允许读取列表......他的代码启动它。

JFrame frame = new JFrame();
    frame.setSize(900, 500);
    frame.setVisible(true);
    Render render = new Render(new RenderDimension(frame.getX(),frame.getY(),frame.getWidth(),frame.getHeight()), frame);
    BufferedImage zombie = new ImageLoader().readImage("zombie");
    BufferedImage player = new ImageLoader().readImage("player");
    render.RenderAdd(new RenderImage(new RenderDimension(100, 100, player.getWidth(), player.getHeight()), player));
    render.RenderAdd(new RenderImage(new RenderDimension(0, 0, zombie.getWidth(), zombie.getHeight()), zombie));
    render.start();
    render.RenderAdd(new RenderImage(new RenderDimension(200, 100, player.getWidth(), player.getHeight()), player));

'render' 是渲染部分的主要渲染类。然后,RenderAdd 添加一个 RenderImage,它的 RenderDimension 是对象的 x 和 y,以及图像的宽度和高度。然后也将 BufferedImage 作为参数。

虽然,每次我尝试运行该程序时,它都会出现一个空白屏幕

现在,在 Render 类中,有另一个类扩展了一个线程。这是一个将框架作为参数的类,删除内容并开始绘制到 getContentPane()。下一个代码在 renderthread 类的 paintComponent() 函数中。不幸的是,没有任何东西可以绘制,但是确实可以处理,因为我尝试过使用 System.out.print("h") 重复打印自身。

for (RenderImage r : render.getList()){
    int x = r.getSize().getX();
    int y = r.getSize().getY();
    int wi = r.getSize().getWidth();
    int hi = r.getSize().getHeight();
    if (x + wi >= -1 && x + wi <= d.getWidth()){
        if (y + hi >= -1 && y + hi <= d.getHeight()){
            g.drawImage(r.getImage(), x, y, null);
        }
    }
}
frame.getContentPane().add(p);
frame.getContentPane().validate();
frame.getContentPane().repaint();

我认为问题在于列表不会添加,所以这就是那部分。

List<RenderImage> render = new ArrayList<RenderImage>();

public List<RenderImage> getList(){
    return render;
}

public void RenderAdd(RenderImage renders){
    render.add(renders);
}
4

1 回答 1

3

用你给我们的示例代码很难知道。

场景 #1,覆盖JComponent#paintComponent

如果您在paintComponent方法中执行此操作

for (RenderImage r : render.getList()){
    int x = r.getSize().getX();
    int y = r.getSize().getY();
    int wi = r.getSize().getWidth();
    int hi = r.getSize().getHeight();
    if (x + wi >= -1 && x + wi <= d.getWidth()){
        if (y + hi >= -1 && y + hi <= d.getHeight()){
            g.drawImage(r.getImage(), x, y, null);
        }
    }
}
frame.getContentPane().add(p);
frame.getContentPane().validate();
frame.getContentPane().repaint();

然后不要。

从方法中以任何方式调用任何更新 UI 的paint方法只会导致灾难。这只是触发另一个重绘请求添加到事件调度线程,它会调用你paintComponent的方法,你可以说好你的 CPU 和程序的响应能力。

此外,请确保在从 EDT 以外的其他用户更新 UI 时,确保使用或Thread将请求同步回 EDTSwingUtilities#invokeLaterSwingUtilities.invokeAndWait

另外,请确保您正在调用super.paintComponent

场景#2,使用JComponent#getGraphics

想到的问题是,g你的例子是从哪里来的。

如果你正在使用JComponent#getGraphics,那么不要。这是重绘之间图形的简单快照,一旦发生下一次重绘,它将被删除。

从类似的东西创建一个自定义组件JPanel并覆盖它的paintComponent方法并使用RenderImage循环更新组件(只需省略更改 UI 的代码)

此外,确保所有重绘请求都是在 EDT 的上下文中发出的

于 2012-10-20T08:17:18.403 回答