JFrame 程序和 运行 另一个 class in Java

JFrame program and running another class in Java

所以目前我想使用一个 jframe 程序,它将 运行 另一个 class 在 window.

一个工作示例:
Jframe:

import javax.swing.JFrame;

public class FaceJFrame
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setSize(300,400);
        frame.setTitle("A Rectangle Object in a JFrame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Face aRectangle = new Face();

        frame.add(aRectangle);
        frame.setVisible(true);
    }
}

程序:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import javax.swing.JComponent;

public class Face extends JComponent
{
    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;

        // Construct face and eyes
        Rectangle face = new Rectangle(0, 0, 50, 50); 
        Rectangle eye = new Rectangle(5, 5, 15, 15);
        Rectangle eye2 = new Rectangle(25, 5, 15, 15);

        //make some lines for the mouth
        Line2D mouth1 = new Line2D.Double(15, 30, 15, 35);
        Line2D mouth2 = new Line2D.Double(15, 35, 35, 35);
        Line2D mouth3 = new Line2D.Double(35, 35, 35, 30); 

        // draw the rectangle
        g2.draw(face); 
        g2.draw(eye);
        g2.draw(eye2);
        g2.draw(mouth1);
        g2.draw(mouth2);
        g2.draw(mouth3);
    }

}

使用这两个代码片段,运行在 cmd 中使用 Jframe 会弹出一个window,上面有一张小脸。

我想用下面的代码做同样的事情:
Jframe:

import javax.swing.JFrame;


public class Car_JFrame
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setSize(300,400);
        frame.setTitle("a car");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Car aRectangle = new Car();

        frame.add(aRectangle);
        frame.setVisible(true);
    }
}

和主要 class:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
public class Car
{
    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;

        Rectangle body = new Rectangle(0, 10, 60, 20); 

        Line2D roof1 = new Line2D.Double(10, 10, 20, 0);
        Line2D roof2 = new Line2D.Double(20, 0, 40, 0);
        Line2D roof3 = new Line2D.Double(40, 0, 50, 10); 
        Ellipse2D.Double wheel1 = new Ellipse2D.Double(15, 25, 10,10);
        Ellipse2D.Double wheel2 = new Ellipse2D.Double(45, 25, 10,10);
        // draw the rectangle
        g2.draw(body);
        g2.draw(roof1);
        g2.draw(roof2);
        g2.draw(roof3);
        g2.draw(wheel1);
        g2.draw(wheel2);

    }
}

它不会产生相同的结果。其实cmd中运行ning car_jframe会输出人脸程序。 (他们在同一个 blueJ 项目中)

我该怎么办?

您的主要问题是您的 Car class 没有扩展 JPanel 或 JComponent 或任何派生自它们的 class,因此无法将其添加到您的 JFrame 中,并且任何尝试这样做所以会导致编译错误。您有两个主要可能的解决方案:

  1. 通过扩展 JPanel(或 JComponent,但我推荐 JPanel)使 Car 成为真正的组件。
  2. 或者,如果您希望 Car 是逻辑 class 而不是组件 class,则创建一个包含 Car 对象的 JPanel 并通过直接调用该对象的 paintComponent 来绘制 Car 对象JPanel 自己的 paintComponent 方法中的方法。

其他说明:

  • 您几乎总是想在覆盖中调用 super.paintComponent(g) 方法,以便 JPanel 可以进行内务处理。
  • 您总是希望在您认为是带有@Override注解的重写方法的任何方法前加上这样的方法,如果您的假设不正确,编译器会警告您.

例如,

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.*;
import javax.swing.*;

public class TestCar {
    private static void createAndShowGui() {
        Car mainPanel = new Car();

        JFrame frame = new JFrame("A Car");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // start all code on the Swing event thread
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

class Car extends JPanel {
    private static final int PREF_W = 400;
    private static final int PREF_H = 300;
    private static final Rectangle BODY = new Rectangle(0, 10, 60, 20); 
    private static final Line2D ROOF_1 = new Line2D.Double(10, 10, 20, 0);
    private static final Line2D ROOF_2 = new Line2D.Double(20, 0, 40, 0);
    private static final Line2D ROOF_3 = new Line2D.Double(40, 0, 50, 10); 
    private static final Ellipse2D WHEEL_1 = new Ellipse2D.Double(15, 25, 10,10);
    private static final Ellipse2D WHEEL_2 = new Ellipse2D.Double(45, 25, 10,10);

    public Car() {

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // draw the rectangle
        g2.draw(BODY);
        g2.draw(ROOF_1);
        g2.draw(ROOF_2);
        g2.draw(ROOF_3);
        g2.draw(WHEEL_1);
        g2.draw(WHEEL_2);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }
}

如果你想要真正的花哨,使用 Path2D 对象、AffineTransform 和 Swing Timer 并给你的 GUI 一点动画:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Car2 extends JPanel {
    private static final int PREF_W = 400;
    private static final int PREF_H = 300;
    private static final Rectangle BODY = new Rectangle(0, 10, 60, 20);
    private static final Line2D ROOF_1 = new Line2D.Double(10, 10, 20, 0);
    private static final Line2D ROOF_2 = new Line2D.Double(20, 0, 40, 0);
    private static final Line2D ROOF_3 = new Line2D.Double(40, 0, 50, 10);
    private static final Ellipse2D WHEEL_1 = new Ellipse2D.Double(15, 25, 10,
            10);
    private static final Ellipse2D WHEEL_2 = new Ellipse2D.Double(45, 25, 10,
            10);
    private static final int TIMER_DELAY = 30;
    private static final int CAR_DELTA_X = 1;
    private static final int CAR_DELTA_Y = CAR_DELTA_X;
    private Path2D path2D = new Path2D.Double();

    public Car2() {
        path2D.append(BODY, false);
        path2D.append(ROOF_1, false);
        path2D.append(ROOF_2, false);
        path2D.append(ROOF_3, false);
        path2D.append(WHEEL_1, false);
        path2D.append(WHEEL_2, false);

        new Timer(TIMER_DELAY, new CarTimerListener()).start();;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.draw(path2D);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    class CarTimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            path2D.transform(AffineTransform.getTranslateInstance(CAR_DELTA_X, CAR_DELTA_Y));
            repaint();
        }
    }
}

您的应用程序中应该只有一个主要方法。我会像下面这样更改它,让用户 select 在 运行 应用程序时打印哪个形状。

import javax.swing.JFrame;

public class DrawFrame {
    public static void main(String[] args) {

        if(args[0].equals("face") {

            paintFace()
        }
        else if(args[0].equals("car") {

            paintCar();
        }
        else {
            System.out.println("No Shape Selected to Print");
        }
    }

    private static paintFace() {

        JFrame frame = new JFrame();
        frame.setSize(300,400);
        frame.setTitle("A Rectangle Object in a JFrame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Face face = new Face();
        frame.add(face);
        frame.setVisible(true);
    }

    private static paintCar() {

        JFrame frame = new JFrame();
        frame.setSize(300,400);
        frame.setTitle("a car");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Car car = new Car();
        frame.add(car);
        frame.setVisible(true);
    }
}

你的车也没有扩展组件。不行。

更正为

public class Car extends JComponent { ... }