gpt4 book ai didi

java - 无法手动绘制到 JPanel

转载 作者:行者123 更新时间:2023-12-01 10:35:13 25 4
gpt4 key购买 nike

我正在尝试制作一个轨道模拟器,但遇到了这个问题。我查遍了 Stack Overflow,但找不到解决方案。我只是想手动绘制到 JPanel,但它没有显示在上面。我已将布局设置为 null,使其可见,将其添加到 JFrame,将 Body 添加到 Plane,以及您通常会执行的所有操作。

这是 Body 类:

package viperlordx.orbitsimulator;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JLabel;

@SuppressWarnings("serial")
public class Body extends JLabel {
private double mass;
private Point location;
private Vector velocity;
private Color color;
private Plane plane;
public Body(double mass, Point location, Vector velocity, Color color) {
this.mass = mass;
this.location = location;
this.velocity = velocity;
this.color = color;
this.setVisible(true);
this.setBounds(location.x, location.y, 100, 100);
}
public void moveTick() {

velocity.addTo(location);
}
public void setPlane(Plane plane) {
this.plane = plane;
}
public Plane getPlane() {
return plane;
}
@Override
public void paintComponent(Graphics g) {
System.out.println("Painting");
super.paintComponent(g);
if (plane != null && g != null) {
g.setColor(color);
g.fillOval(location.x, location.y, getWidth(), getHeight());
}
}
public Point getLocation() {
return location;
}
public void setLocation(Point location) {
this.location = location;
}
public Vector getVelocity() {
return velocity;
}
public void setVelocity(Vector vector) {
velocity = vector;
}
}

以及 Plane 类:

package viperlordx.orbitsimulator;

import java.awt.Graphics;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Plane extends JPanel {
private HashSet<Body> bodies = new HashSet<Body>();
public void addBody(Body body) {
this.add(body);
bodies.add(body);
}
public Plane() {
this.setLayout(null);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (bodies != null) {
for (Body body : bodies) {
body.paintComponent(g);
}
}
}
public Set<Body> getBodies() {
return bodies;
}
}

现在是主类:

package viperlordx.orbitsimulator;

import java.awt.Color;
import java.awt.Point;

import javax.swing.JFrame;

public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 1000);
frame.setLocationRelativeTo(null);
Plane plane = new Plane();
frame.add(plane);
plane.setVisible(true);
frame.setLayout(null);
plane.setBounds(0, 0, 1000, 1000);
plane.setBackground(Color.WHITE);
plane.addBody(new Body(10.0, new Point(10, 10), new Vector(0, 0), Color.GREEN));
frame.setVisible(true);
frame.setTitle("Orbit");
plane.repaint();
}
}

最佳答案

您正在混合在组件上绘制形状并将组件添加到容器中。你的 Body 不应该是一个组件,而只是一个保存要绘制对象的数据的类。此数据用于在“目标”组件上绘制相应的形状 - 在您的例子中为Plane

我删除了不相关的代码并根据我上面的解释进行了更改:

public class Main {

public static void main(String[] args) {

SwingUtilities.invokeLater(() -> {

JFrame frame = new JFrame();
Plane plane = new Plane();
frame.add(plane);
plane.setBackground(Color.WHITE);
plane.addBody(new Body(10.0, new Point(10, 10), new Vector(0, 0), Color.GREEN));

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Orbit");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

@SuppressWarnings("serial")
class Plane extends JPanel {

private HashSet<Body> bodies = new HashSet<>();

public void addBody(Body body) {

bodies.add(body);
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
for (Body body : bodies) {
// Might want to call all needed accessors before getting to work.
g.setColor(body.getColor());
g.fillOval(body.getLocation().x, body.getLocation().y, getWidth(), getHeight());
}
}

@Override
public Dimension getPreferredSize() {

// Calculate the size
return new Dimension(1000, 500);
}
}

class Body {

private Point location;
private Vector velocity;
private Color color;

public Body(double mass, Point location, Vector velocity, Color color) {

this.location = location;
this.velocity = velocity;
this.color = color;
}

public Point getLocation() {

return location;
}

public Color getColor() {

return color;
}
}

enter image description here

注释:

  • Start Swing on the EDT
  • 不要设置框架的大小(如果我的屏幕高度没有 1000 像素怎么办?),而是调用 pack() 并确保您在其上绘制的组件为 @Override getPreferredSize()适本地。这意味着您需要根据您在其上绘制的内容进行计算。
  • 一般来说,setVisible(true) 应该是您最后执行的操作。之后无需重新绘制。
  • 从 Java 7 开始,您可以编写 HashSet<Body> bodies = new HashSet<>(),而无需在 RHS 中指定泛型类型。
  • 不要使用原始类型 Vector 。事实上,根本没有理由使用这个类。 SetList 通常效果更好。如果它们保存计算中使用的数字,那么它们的通用类型可能应该是 FloatDouble

关于java - 无法手动绘制到 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34792473/

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