0

我正在编写一个工程应用程序,我想将它作为桌面上的普通 Java 应用程序和基于 Web 的小程序来执行。该应用程序可以在桌面上完美运行。作为一个 JApplet,它执行时没有错误,但实际上不显示任何内容。我的代码创建了一个名为 sim = new DynamicSimulationPanel() 的新对象,它扩展了 JPanel。这个 sim 对象有一个 setBackground(Color.black) 语句,实际上 Applet 对此作出响应并产生与上面相同颜色的空白屏幕。没有任何 GUI 组件(一些 JButton 等)出现,我无法启动模拟以检查对 jpanel 的绘画是否有效。我在这里做任何明显错误的事情吗?

/**
 * 
 */
package reid.dynamicplanes;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;

/**
 * @author pmr
 * 
 */
@SuppressWarnings("serial")
public class MainWindow extends JApplet implements ActionListener {
    private JFrame mw;
    private final String TITLETEXT = "Dynamics Solver";
    private JToolBar tb;
    private JTabbedPane tabbedPane;
    private JButton buttons[];
    private URL imageURLs[];
    private ImageIcon buttonImages[];
    private static final int NUM_BUTTONS = 1;
    private DynamicSimulationPanel sim;
    private static boolean isApplet = true;
    private static MainWindow m;

    public MainWindow() {
        m = this;
        if (isApplet == false) {
            mw = new JFrame(TITLETEXT); // generate the JFrame
            mw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mw.setExtendedState(JFrame.MAXIMIZED_BOTH); // maximise the window
            mw.setLayout(new BorderLayout());

            try { // this try-catch prevents the nasty Java GUI interface and
                    // makes
                    // the GUI look platform-native.
                UIManager.setLookAndFeel(UIManager
                        .getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException
                    | IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
                System.out
                        .println("Error setting the platform native look and feel: "
                                + e.getLocalizedMessage());
            }

            tb = new JToolBar();
            buttons = new JButton[NUM_BUTTONS];
            buttons[0] = new JButton("Exit");
            buttons[0].setToolTipText("Exits the application");
            imageURLs = new URL[NUM_BUTTONS];
            buttonImages = new ImageIcon[NUM_BUTTONS];
            for (int i = 0; i < NUM_BUTTONS; i++) {
                imageURLs[i] = this.getClass().getResource(
                        "/reid/dynamicplanes/res/exit.png");
                buttons[i].addActionListener(this); // tells the button to send
                                                    // its
                                                    // click signal to this
                                                    // class
                if (imageURLs[i] != null) {
                    // the image resource was found!
                    try {
                        buttonImages[i] = new ImageIcon(imageURLs[i],
                                "JButton " + i);
                        buttons[i].setIcon(buttonImages[i]);
                    } catch (NullPointerException e) {
                        // imageURL probably couldn't be found!
                        System.out.println(e.getLocalizedMessage());
                    }

                }

                tb.add(buttons[i]);
            }

            tabbedPane = new JTabbedPane(JTabbedPane.TOP);
            tabbedPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null,
                    null, null, null));
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
            tabbedPane.setToolTipText("Select your control tab");
        } // end (isApplet) tester

        sim = new DynamicSimulationPanel(); // instantiate a new DSP - the
                                            // Jpanel that displays the output
                                            // of the DynamicSimulatin's calcs.
        if (isApplet == true) {
            this.setLayout(new BorderLayout());
            this.getContentPane().add(sim, BorderLayout.CENTER);
        } else {
            tabbedPane.addTab("Simulation", null, sim, null);
            mw.getContentPane().add(tabbedPane, BorderLayout.CENTER);
            mw.add(tb, BorderLayout.PAGE_START);
            mw.setVisible(true);
            // do this stuff if running in a JFrame
        }

    }

    @Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    isApplet = true;
                    new MainWindow();
                }
            });
        } catch (Exception e) {
            System.err.println("init() did not complete successfully");
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        isApplet = false;
        new MainWindow();

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            if (buttons[0] != null && e.getSource().equals(buttons[0])) {
                // exit button was clicked
                System.exit(0);
            }
        } catch (NullPointerException npe) {
            npe.printStackTrace();
        }

    }
}

动态模拟面板.java:

/**
 * 
 */
package reid.dynamicplanes;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.text.DecimalFormat;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

/**
 * @author pmreid
 * 
 */
@SuppressWarnings("serial")
public class DynamicSimulationPanel extends JPanel implements ActionListener,
        ComponentListener {
    private DynamicSimulation dsim;
    private static boolean isRunning = false;
    private static JPanel controls = new JPanel();
    private static JButton startsim = new JButton("Start Simulation");
    private static JButton setValues = new JButton("Set Values");
    private JLabel labels[] = new JLabel[4];
    private static JTextField textboxes[] = new JTextField[4];
    private static Font font = new Font(Font.MONOSPACED, Font.BOLD, 14);
    private static JPanel textoutput = new JPanel();
    private static JLabel outputLabels[] = new JLabel[3];
    private static JLabel totaltime = new JLabel();
    private static JLabel accel = new JLabel();
    private static JLabel distleft = new JLabel();
    private static double cumX = 0; // cumulative dist travelled.
    private static final int EDGE_OFFSET = 200;
    private static int availW;
    private static int availH;
    private static int x;
    private static int y;
    private static boolean drawPlane = false;
    private Timer paintTimer = new Timer(10, this);
    private static Point startPos;
    private static Point currentPos;
    private static double bodyR = 25; // radius of the body when we draw it, in
    public static JPanel panelGroup = new JPanel();
    private static final int ARR_SIZE = 6;
    private static final Color ARR_COL = Color.green;
    private static final int CompSize = 30;
    // px
    private static boolean hasStarted = false;
    private static double hyp; // the hypotenuse of the plane triangle
    private static AffineTransform tx;

    public DynamicSimulationPanel() {
        // super();
        this.setBackground(Color.black);
        this.setDoubleBuffered(true);
        // super.repaint();
        super.addComponentListener(this);
        this.setLayout(new BorderLayout());
        dsim = new DynamicSimulation();
        dsim.setupExternalForces();
        panelGroup.setLayout(new GridLayout(2, 1));
        setupControlPanel();
        setupOutput();
        panelGroup.add(controls);
        panelGroup.add(textoutput);
        this.add(panelGroup, BorderLayout.PAGE_START);
        paintTimer.start();
        startPos = new Point();
        currentPos = new Point();

    }

    private void setupOutput() {
        textoutput.setLayout(new GridLayout(1, 6));
        totaltime.setFont(font);
        distleft.setFont(font);
        totaltime.setForeground(Color.red);
        distleft.setForeground(Color.red);
        accel.setFont(font);
        accel.setForeground(Color.red);
        String lt = "";
        for (int i = 0; i < outputLabels.length; i++) {
            outputLabels[i] = new JLabel();
            outputLabels[i].setFont(font);
            switch (i) {
            case 0:
                lt = "Total time/s: ";
                outputLabels[i].setLabelFor(totaltime);
                outputLabels[i].setText(lt);
                textoutput.add(outputLabels[i]);
                textoutput.add(totaltime);
                break;
            case 1:
                lt = "Dist left/m: ";
                outputLabels[i].setLabelFor(distleft);
                outputLabels[i].setText(lt);
                textoutput.add(outputLabels[i]);
                textoutput.add(distleft);
                break;
            case 2:
                lt = "Accel (ms\u207B\u00B2): ";
                outputLabels[i].setLabelFor(accel);
                outputLabels[i].setText(lt);
                textoutput.add(outputLabels[i]);
                textoutput.add(accel);
                break;
            }

        }

    }

    private static double getRounded(double d) {
        DecimalFormat DForm = new DecimalFormat("#.###");
        return Double.valueOf(DForm.format(d));
    }

    private void setupControlPanel() {
        controls.setLayout(new FlowLayout());
        startsim.addActionListener(this);
        startsim.setEnabled(false);
        startsim.setOpaque(true);
        startsim.setBorderPainted(false);
        setValues.addActionListener(this);
        String lt = "";
        for (int i = 0; i < labels.length; i++) {
            textboxes[i] = new JTextField(15);
            textboxes[i].setFont(font);
            labels[i] = new JLabel();
            labels[i].setFont(font);
            labels[i].setLabelFor(textboxes[i]);
            switch (i) {
            case 0:
                lt = "Mu: ";
                break;
            case 1:
                lt = "Mass (kg): ";
                break;
            case 2:
                lt = "Req'd dist (m): ";
                break;
            case 3:
                lt = "Plane incline (deg): ";
                break;
            }
            labels[i].setText(lt);
            controls.add(labels[i]);
            controls.add(textboxes[i]);
        }
        controls.add(setValues);
        controls.add(startsim);

    }

    public static void moveObject(double x) {
        // a call-back method called by DynamicSimulation at each time step to
        // update the position of the object(s) on the GUI
        if (isRunning) {
            cumX += x;
            distleft.setText(String.valueOf(getRounded(DynamicSimulation.getS()
                    - cumX)));
            x = x * (hyp / DynamicSimulation.getS());
            double dx = x
                    * Math.cos(Math.toRadians(DynamicSimulation.getTheta()));
            double dy = x
                    * Math.sin(Math.toRadians(DynamicSimulation.getTheta()));
            currentPos.setLocation(currentPos.getX() - dx, currentPos.getY()
                    + dy);

        }

    }

    public static void setupValues() {
        boolean proceed = false;
        for (int n = 0; n < textboxes.length; n++) {
            if (textboxes[n].getText().equals("")
                    || Double.valueOf(textboxes[n].getText()) == 0) {
                // input is not usable, so alert user and quit
                JOptionPane.showMessageDialog(null,
                        "Error: your input values are invalid!");
                proceed = false;
            } else {
                proceed = true;
            }
        }

        if (proceed) {
            // all looks ok.

            DynamicSimulation.setS(Double.valueOf(textboxes[2].getText()));
            DynamicSimulation.setMass(Double.valueOf(textboxes[1].getText()));
            DynamicSimulation.setMu(Double.valueOf(textboxes[0].getText()));
            DynamicSimulation.setTheta(Double.valueOf(textboxes[3].getText()));
            DynamicSimulation.calcAccel();
            distleft.setText(String.valueOf(getRounded(DynamicSimulation.getS())));
            accel.setText(String.valueOf(getRounded(DynamicSimulation
                    .getAccel())));
            if (DynamicSimulation.getAccel() < 0) {
                // friction is winning, so stop!
                startsim.setBackground(Color.red);
                startsim.setEnabled(false);
                proceed = false;
                drawPlane = false;
                hasStarted = false;
            } else {
                DynamicSimulation.calcTime();
                totaltime.setText(String.valueOf(getRounded(DynamicSimulation
                        .getTime())));

                drawPlane = true;
                hasStarted = false;

                startsim.setBackground(Color.green);
                startsim.setEnabled(true);
            }

        }
    }

    public static void drawPlane(Graphics2D g2) {
        availW = (int) (x * 0.7);
        availH = (int) (y * 0.7);
        g2.setStroke(new BasicStroke(4.0f));
        g2.setColor(Color.red);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        Line2D base = new Line2D.Double(EDGE_OFFSET, y - EDGE_OFFSET,
                EDGE_OFFSET + availW, y - EDGE_OFFSET);
        hyp = Math.sqrt(availW * availW * 0.2 + availH * availH * 0.2);
        startPos.setLocation(
                EDGE_OFFSET
                        + hyp
                        * Math.cos(Math.toRadians(DynamicSimulation.getTheta())),
                y
                        - (EDGE_OFFSET + hyp
                                * Math.sin(Math.toRadians(DynamicSimulation
                                        .getTheta()))));
        if (!hasStarted) {
            currentPos.setLocation(startPos);
        }
        Line2D plane = new Line2D.Double(EDGE_OFFSET, y - EDGE_OFFSET,
                startPos.getX(), startPos.getY());

        g2.draw(base);
        g2.draw(plane);
        g2.drawString("\u03B8=" + DynamicSimulation.getTheta() + "\u00B0",
                (int) (EDGE_OFFSET + 85 * Math.cos(Math
                        .toRadians(DynamicSimulation.getTheta()))), y
                        - EDGE_OFFSET - 10);
    }

    public static void drawBody(Graphics2D g2) {
        // draws the mass and labels arrows etc.
        g2.setStroke(new BasicStroke(4.0f));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        GradientPaint gradient = new GradientPaint(0, 0, Color.red,
                (int) (2 * bodyR), (int) (2 * bodyR), Color.yellow, true);
        g2.setPaint(gradient);
        double PosCorrection = 20 * Math.sin(Math.toRadians(DynamicSimulation
                .getTheta()));
        Ellipse2D body = new Ellipse2D.Double(currentPos.getX() - (2 * bodyR),
                currentPos.getY() - (2 * bodyR - PosCorrection), 2 * bodyR,
                2 * bodyR);
        g2.fill(body);
        g2.setColor(Color.yellow);
        g2.setFont(font);
        g2.drawString(
                "W="
                        + String.valueOf(getRounded(9.8 * DynamicSimulation
                                .getMass())),
                (int) (currentPos.getX() - 4.5 * bodyR),
                (int) (currentPos.getY() + bodyR * 1.1)); // weight

        g2.drawString(
                "R="
                        + String.valueOf(getRounded(DynamicSimulation
                                .getReactionJ())),
                (int) (currentPos.getX() - 1.7 * bodyR),
                (int) (currentPos.getY() - bodyR * 3)); // reaction

        g2.drawString(
                "Fr="
                        + String.valueOf(getRounded(DynamicSimulation
                                .getFrictionI())),
                (int) (currentPos.getX() + 1.3 * bodyR),
                (int) (currentPos.getY() - bodyR * 1.3)); // friction

        drawArrow(g2, currentPos.getX() - bodyR - PosCorrection,
                currentPos.getY() - bodyR + PosCorrection, currentPos.getX()
                        - bodyR - PosCorrection,
                currentPos.getY() - bodyR + PosCorrection + CompSize
                        * DynamicSimulation.getWeightRatio()); // weight
        drawArrow(
                g2,
                currentPos.getX() - bodyR - PosCorrection,
                currentPos.getY() - bodyR + PosCorrection,
                currentPos.getX()
                        - bodyR
                        - PosCorrection
                        - CompSize
                        * DynamicSimulation.getReactionRatio()
                        * Math.sin(Math.toRadians(DynamicSimulation.getTheta())),
                currentPos.getY()
                        - bodyR
                        + PosCorrection
                        - DynamicSimulation.getReactionRatio()
                        * CompSize
                        * Math.cos(Math.toRadians(DynamicSimulation.getTheta())));// reaction

        drawArrow(
                g2,
                currentPos.getX() - bodyR - PosCorrection,
                currentPos.getY() - bodyR + PosCorrection,
                currentPos.getX()
                        - bodyR
                        - PosCorrection
                        + CompSize
                        * DynamicSimulation.getFrictionRatio()
                        * Math.cos(Math.toRadians(DynamicSimulation.getTheta())),
                currentPos.getY()
                        - bodyR
                        + PosCorrection
                        - DynamicSimulation.getFrictionRatio()
                        * CompSize
                        * Math.sin(Math.toRadians(DynamicSimulation.getTheta()))); // friction
    }

    static void drawArrow(Graphics2D g2, double x1, double y1, double x2,
            double y2) {
        g2.setColor(ARR_COL);
        tx = new AffineTransform();
        Polygon arrowHead = new Polygon();
        arrowHead.addPoint(0, ARR_SIZE);
        arrowHead.addPoint(-ARR_SIZE, -ARR_SIZE);
        arrowHead.addPoint(ARR_SIZE, -ARR_SIZE);
        Line2D.Double line = new Line2D.Double(x1, y1, x2, y2);
        g2.draw(line);
        tx.setToIdentity();
        double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
        tx.translate(line.x2, line.y2);
        tx.rotate((angle - Math.PI / 2d));
        // g2.setTransform(tx);
        // g2.fill(arrowHead);

    }

    public static void startSimulation() {
        cumX = 0;
        startsim.setEnabled(false);
        isRunning = true;
        hasStarted = true;
        DynamicSimulation.startSim();

    }

    public static void endSimulation() {
        isRunning = false;
        startsim.setEnabled(true);
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        super.paintComponent(g);
        if (drawPlane) {
            // it is OK to draw the triangle
            drawPlane(g2);
        }
        if (hasStarted) {
            drawBody(g2);
        }
        Toolkit.getDefaultToolkit().sync();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(startsim)) {
            // initiate the simulation.
            startSimulation();
        }
        if (e.getSource().equals(setValues)) {
            // set up the values
            setupValues();
        }
        if (e.getSource().equals(paintTimer)) {
            this.invalidate();
            repaint();
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.
     * ComponentEvent)
     */
    @Override
    public void componentResized(ComponentEvent e) {
        x = this.getWidth();
        y = this.getHeight();
        availW = (int) (x * 0.7);
        availH = (int) (y * 0.7);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent
     * )
     */
    @Override
    public void componentMoved(ComponentEvent e) {

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent
     * )
     */
    @Override
    public void componentShown(ComponentEvent e) {

    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.
     * ComponentEvent)
     */
    @Override
    public void componentHidden(ComponentEvent e) {

    }

}

未出现的按钮/文本框位于 DynamicSimulationPanel 中的 panelGroup JPanel 上。

任何帮助表示赞赏。

4

2 回答 2

0

所以我找到了一个解决方案,小程序和桌面应用程序都可以完美运行。

我创建了一个扩展 JPanel 并调用所有其他 Jpanel 类的类文件。然后,非常重要的是,当我将这个主面板 (mp) 添加到小程序时,我是在小程序的 init() 方法中完成的,而不是像以前那样调用新的 MainWindow():

@Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    isApplet = true;
                    // new MainWindow();
                    mp = new PanelLoader(TITLETEXT, true);
                    getContentPane().add(mp);
                    repaint();
                }
            });
        } catch (Exception e) {
            System.err.println("init() did not complete successfully");
        }
    }
于 2012-10-29T14:17:34.033 回答
0

仅当不满足条件 isApplet 时才创建按钮和选项卡式窗格。当 isApplet 为真时,唯一运行的代码是

m = this;
//...
sim = new DynamicSimulationPanel();
//...
if (isApplet == true) {
    this.setLayout(new BorderLayout());
    this.getContentPane().add(sim, BorderLayout.CENTER);
}
于 2012-10-28T17:13:05.363 回答