簡體   English   中英

無法手動繪制到JPanel

[英]Unable to draw manually to JPanel

我正在嘗試制作軌道模擬器,但遇到了這個問題。 我已經檢查了堆棧溢出的全部內容,但是找不到解決方案。 我只是試圖手動繪制到JPanel ,但是它沒有顯示在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;
    }
}

和飛機課:

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

在此處輸入圖片說明

筆記:

  • 在EDT上開始擺動
  • 不要設置框架的大小(如果我的屏幕沒有1000像素高怎么辦?),而是調用pack()並確保在其上繪制@Override getPreferredSize()正確。 這意味着您將需要根據在其上繪制的內容進行計算。
  • 通常, setVisible(true)應該是您要做的最后一件事。 之后無需重新粉刷。
  • 從Java 7開始,您可以編寫HashSet<Body> bodies = new HashSet<>()而無需在RHS中指定泛型類型。
  • 不要使用原始類型Vector 實際上,根本沒有理由使用此類。 SetList通常會做得更好。 如果它們保存用於計算的數字,則它們的通用類型可能應該是FloatDouble

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM