JFrame程序并在Java中运行另一个类

时间:2015-10-26 00:49:11

标签: java swing jframe paintcomponent

所以目前我想使用一个可以在窗口中运行另一个类的jframe程序。

一个工作实例:
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会给出一个带有小脸的弹出窗口。

我想用以下代码做同样的事情:
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);
    }
}

和主要课程:

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中运行car_jframe会输出face程序。 (他们在同一个blueJ项目中)

我该怎么办?

2 个答案:

答案 0 :(得分:2)

您的主要问题是您的Car类不会扩展JPanel或JComponent或从中派生的任何类,因此无法将其添加到您的JFrame中,任何尝试这样做都会导致编译错误。您有两种主要的解决方案:

  1. 通过扩展JPanel(或JComponent,但我推荐JPanel)使Car成为真正的组件。
  2. 或者如果您希望Car成为逻辑类而不是组件类,则创建一个包含Car对象的JPanel,并通过在JPanel&#39中直接调用该对象的paintComponent方法来绘制Car对象。 ; s拥有paintComponent方法。
  3. 其他说明:

    • 您几乎总是希望在覆盖中调用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();
            }
        }
    }
    

答案 1 :(得分:1)

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

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 { ... }