gpt4 book ai didi

java - 在运行时从另一个类中调用 JPanel

转载 作者:行者123 更新时间:2023-12-02 04:39:36 24 4
gpt4 key购买 nike

我有一个类 Roundabout(JFrame)、Surface(JPanel) 和 Spawn。在 Surface paintComponent 中,我已经绘制了一些交通信号灯,因为它们始终位于环形交叉路口上。但我也想在运行时绘制组件。所以我向 JFrame 添加了一个 mousePressed 事件,我在这里调用的方法最终从 Spawn.java 调用了 spawnPedestrian,我可以看到这一点是因为 println。但是,当调用 spawnPedestrian 时,什么也没有绘制!如果我在 Surface 类中创建一个行人并绘制它,它就可以工作。我如何才能使 spawnPedestrian 工作?我尝试包含最少的代码片段(见下文)。

human人类.png

track环岛.png

public class Spawn {

public void spawnPedestrian(){
//Create a new pedestrian.

Pedestrian p = new Pedestrian(100,100);

Roundabout.getSurface().add(p);
Roundabout.getSurface().revalidate();
Roundabout.getSurface().repaint();

}
}

public class Roundabout extends JFrame{

static Surface surface=new Surface();

public Roundabout(){
initUI();
}

private void initUI() {

setTitle("Roundabout");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

add(surface);

this.addMouseListener(new MouseAdapter() {// empty implementation of all
// MouseListener`s methods
@Override
public void mousePressed(MouseEvent e) {
System.out.println(e.getX() + "," + e.getY());
Spawn spawn=new Spawn();
spawn.spawnPedestrian();

}
});

setSize(1618,850);
setLocationRelativeTo(null);

}

public static JPanel getSurface() {
return surface;
}

public static void main(String[] args) {

//Swing thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Roundabout roundabout=new Roundabout();
roundabout.setVisible(true);
}
});
}

class Surface extends JPanel {

Track track=new Track();

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);

//Make sure the track is painted first
track.paint(g);

}

}

public class Track{

BufferedImage track;
Point trackPosition;
static final Point TRACK_POS = new Point(0, 0);
static final Point SENSOR_POS = new Point(250, 70);

public Track(){
try {
track = ImageIO.read(Roundabout.class.getResource("images/roundabout.png"));
} catch (Exception ex) {
System.out.println("Problem loading track image: " + ex);
}
trackPosition=new Point(TRACK_POS.x,TRACK_POS.y);
}

public void paint(Graphics g)
{
g.drawImage(track,TRACK_POS.x, TRACK_POS.y, null);
}
}


public class Spawn {


//Needs x/y pos
public void spawnPedestrian(){
Pedestrian p = new Pedestrian(30,50);

System.out.println("Spawn me ");

Roundabout.getSurface().add(p);
Roundabout.getSurface().revalidate();
Roundabout.getSurface().repaint();


}
}
}

public class Pedestrian extends JComponent {

BufferedImage pedestrian;
Point pedestrianPosition;
double pedestrianRotation = 0;
int pedestrianW, pedestrianH;

public Pedestrian(int x, int y){
try {
pedestrian = ImageIO.read(Car.class.getResource("images/human.png"));
} catch (IOException e) {
System.out.println("Problem loading pedestrian images: " + e);
}

pedestrianPosition = new Point(x,y);
pedestrianW = pedestrian.getWidth();
pedestrianH = pedestrian.getHeight();

}

public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.rotate(Math.toRadians(pedestrianRotation), pedestrianPosition.x, pedestrianPosition.y);
g2d.drawImage(pedestrian, pedestrianPosition.x, pedestrianPosition.y, null);
}

编辑:我想我通过将Surface布局设置为null并使用setBounds来解决Pedestrian >。但是,图像向右移动得越多,在 setBounds() 中设置的 heightwidth 就越高。有谁可以帮忙吗?

编辑:修改了我的帖子,现在它是一个可运行的示例,您只需为 TrackPedestrian 选择自己的图像。

编辑:一个复制粘贴操作即可添加代码和图像。

最佳答案

当您编写 Roundabout.getSurface().add(p); 时,您正在将 JComponent 添加到 JPanel 对象。 JPanel 必须有一个布局来显示子组件。默认情况下,这是 FlowLayout (请参阅 doc )。 FlowLayout 旨在将组件显示在一行中的其他组件旁边。它不支持在任意坐标处显示组件。

我不确定为什么行人没有显示,但原因可能是它们的尺寸为0x0。您可以使用以下方法轻松检查:

p.setPreferredSize(new Dimension(50,50));

根据您的需要,您可以采用不同的方法:Surface 可以是一个简单的 Canvas,保存“可绘制对象”列表,例如行人,而不是扩展 JPanel。在 Surface.paintComponent() 中,您可以调用每个 Paintable.paint(),为它们提供 Graphics 对象:

interface Paintable {
public void paint(Graphics2D g);
}

class Pedestrian implements Paintable {
public double x, y;
public void paint(Graphics2D g){
Shape circle = new Ellipse2D.Double(x - 5, y - 5, 10, 10);
g2d.draw(circle);
}
}

class Surface extends Canvas {

public List<Paintable> components = new ArrayList<Paintable>();

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);

for(Paintable p : components)
p.paint((Graphics2D) g);

}

}

编辑:我发现您的代码存在一些其他问题:

  • Surface.java:请注意,您按原样使用默认的 FlowLayout(因此它不会管理给定坐标处的显示组件)。
  • Pedestrian.java:在构造函数末尾添加 setPreferredSize(Roundabout.getSurface().getSize());。将您的 Paint() 方法替换为:

.

public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.rotate(Math.toRadians(pedestrianRotation),
pedestrianPosition.x, pedestrianPosition.y);
g2d.drawImage(pedestrian, pedestrianPosition.x,
pedestrianPosition.y, null);
}
  • RoundAbout.java:surface =new Surface(); 应在 initUI() 内调用,以便在事件线程上实例化。

关于java - 在运行时从另一个类中调用 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30323218/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com