无法手动绘制到JPanel

时间:2016-01-14 14:49:56

标签: java swing jpanel paintcomponent

我试图制作一个轨道模拟器,但我遇到了这个问题。我已经检查了Stack Overflow,但我无法找到解决方案。我只是想手动绘制到JPanel,但它没有显示出来。JFrame。我已将布局设置为null,使其可见,将其添加到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; } } ,以及您通常会执行的所有操作。

这是Body类:

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

现在是主要班级:

function myController($scope, someService) {
    $scope.formules = { label : 'label' };
    someService.getData().then(function(data) {
      $scope.formules.year = getYear(data);
    });
}

1 个答案:

答案 0 :(得分:1)

您正在混合组件上的绘图形状并将组件添加到容器中。您的Body不应该是一个组件,只是一个包含要绘制的对象数据的类。此数据用于在&#34; target&#34;上绘制相应的形状。组件 - 您的案例中的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开始,您可以在不指定RHS中的泛型类型的情况下编写HashSet<Body> bodies = new HashSet<>()
  • 不要使用原始类型Vector。事实上,根本没有理由使用这个类。 SetList通常会做得更好。如果他们持有计算中使用的数字,那么他们的通用类型可能应为FloatDouble