我正在编写一个工程应用程序,我想将它作为桌面上的普通 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 上。
任何帮助表示赞赏。