使用Java摆动GUI的形状计算器



我创建了一个不是 GUI 的形状计算器,并且根据所选形状可以很好地计算面积和体积,我正在尝试为同一个程序创建一个 GUI,我在显示形状和基于用户输入的结果时遇到了问题。我有 GUI 的布局,但使用 ActionPerformed,我无法弄清楚如何获取输入并调用该 shape 类来执行计算而不是显示结果。

我已经修复了一些错误,并将让它运行,但是它会给出错误消息以输入数字值,并且无法计算 0.0 以外的面积。

import javax.swing.*;
import java.awt.*;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ControlPane extends JPanel implements ActionListener{

// create buttons
private JRadioButton circle;
private JRadioButton square;
private JRadioButton rectangle;
private JRadioButton triangle;
private JRadioButton sphere;
private JRadioButton cube;
private JRadioButton cylinder;
private JRadioButton cone;
private JRadioButton torus;
private DrawPane drawPane;
public ControlPane() {

ButtonGroup bg1 = new ButtonGroup();
circle = new JRadioButton("Circle");
square = new JRadioButton("Square");
rectangle = new JRadioButton("Rectangle");
triangle = new JRadioButton("Triangle");
sphere = new JRadioButton("Sphere");
cube = new JRadioButton("Cube");
cylinder = new JRadioButton("Cylinder");
cone = new JRadioButton("Cone");
torus = new JRadioButton("Torus");
bg1.add(circle);
bg1.add(square);
bg1.add(rectangle);
bg1.add(triangle);
bg1.add(sphere);
bg1.add(cube);
bg1.add(cylinder);
bg1.add(cone);
bg1.add(torus);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
JPanel shape = new JPanel();
shape.add(circle);
shape.add(square);
shape.add(rectangle);
shape.add(triangle);
shape.add(sphere);
shape.add(cube);
shape.add(cylinder);
shape.add(cone);
shape.add(torus);
add(shape, gbc);
JPanel dimension = new JPanel();
JLabel heightLbl = new JLabel("Height: ");
JLabel widthLbl = new JLabel("Width: ");
JLabel sideLbl = new JLabel("Side: ");
JLabel radius1Lbl = new JLabel("Radius 1: ");
JLabel radius2Lbl = new JLabel("Radius 2: ");
JTextField heightTF = new JTextField(10);
JTextField widthTF = new JTextField(10);
JTextField sideTF = new JTextField(10);
JTextField radius1TF = new JTextField(10);
JTextField radius2TF = new JTextField(10);
heightLbl.setLabelFor(heightTF);
widthLbl.setLabelFor(widthTF); 
sideLbl.setLabelFor(sideTF);
radius1Lbl.setLabelFor(radius1TF);
radius2Lbl.setLabelFor(radius2TF);
dimension.add(heightLbl);
dimension.add(heightTF);
dimension.add(widthLbl);
dimension.add(widthTF);
dimension.add(sideLbl);
dimension.add(sideTF);
dimension.add(radius1Lbl);
dimension.add(radius1TF);
dimension.add(radius2Lbl);
dimension.add(radius2TF);
add(dimension, gbc);  
gbc.gridwidth = GridBagConstraints.REMAINDER;
drawPane = new DrawPane();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = gbc.BOTH;      
JPanel draw = new JPanel();
JLabel areaLbl = new JLabel("Area: ");
JTextField areaTF = new JTextField(10);
areaTF.setEditable(false);
JLabel volumeLbl = new JLabel("Volume: ");
JTextField volumeTF = new JTextField(10);
volumeTF.setEditable(false); 
JButton paint = new JButton("Draw & Calculate");
draw.add(paint);
draw.add(drawPane);
draw.add(areaLbl);
draw.add(areaTF);
draw.add(volumeLbl);
draw.add(volumeTF); 
add(draw, gbc);
paint.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double height = 0;
double width = 0;
double side = 0;
double radius1 = 0;
double radius2 = 0;
double area, volume;
try {
height = Double.parseDouble(heightTF.getText());
width = Double.parseDouble(widthTF.getText());
side = Double.parseDouble(sideTF.getText());
radius1 = Double.parseDouble(radius1TF.getText());
radius2 = Double.parseDouble(radius2TF.getText());
} catch(NumberFormatException ex) {
JOptionPane.showMessageDialog(draw, "Please enter a number value.");
}
if (circle.isSelected()) {
drawPane.setDrawableShape(DrawableShape.CIRCLE);
area = 3.14 * radius1 * radius1;
areaTF.setText(" "+ area);
} 
else if (square.isSelected()) {
drawPane.setDrawableShape(DrawableShape.SQUARE);
area = side * side;
areaTF.setText(" " + area);
}
else if (triangle.isSelected()) {
drawPane.setDrawableShape(DrawableShape.TRIANGLE);
area = 0.5 * width * height;
areaTF.setText(" " + area);
}
else if (rectangle.isSelected()) {
drawPane.setDrawableShape(DrawableShape.RECTANGLE);
area = height * width;
areaTF.setText(" " + area);
}
else if (sphere.isSelected()) {
volume = (4 / 3) * 3.14 * radius1 * radius1 * radius1;
volumeTF.setText(" " + volume);
}
else if (cube.isSelected()) {
volume = (side * side * side);
volumeTF.setText(" " + volume);
}
else if (cylinder.isSelected()) {
volume = (3.14 * radius1 * radius1 * height);
volumeTF.setText(" " + volume);
} 
else if (cone.isSelected()) {
volume = (3.14 * radius1 * radius1 * height) / 3;
volumeTF.setText(" " + volume);
}
else if (torus.isSelected()) {
volume = 2 * 3.14 * 3.14 * radius1 * radius1 * radius2;
volumeTF.setText(" " + volume);
}
}
});
}
} 

画东西类

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawStuff extends JFrame {
public static void main(String[] args) {
new DrawStuff();
}
public DrawStuff() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException |     IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Shape Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ControlPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

绘制窗格类

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawPane extends JPanel {
private DrawableShape drawableShape;
public DrawPane() {
}
public void setDrawableShape(DrawableShape drawableShape) {
this.drawableShape = drawableShape;
repaint();
}
public DrawableShape getDrawableShape() {
return drawableShape;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
DrawableShape shape = getDrawableShape();
if (shape != null) {
int width = getWidth() - 20;
int height = getHeight() - 20;
int size = Math.min(width, height);
int x = (getWidth() - size) / 2;
int y = (getHeight() - size) / 2;
if (shape == DrawableShape.CIRCLE) {
g2d.fillOval(x, y, size, size);
} else if (shape == DrawableShape.SQUARE) {
g2d.fillRect(x, y, size, size);
} else if (shape == DrawableShape.TRIANGLE) {
g2d.fillPolygon(new int[] {20, 40, 60}, new int[] {100, 50, 100}, 3);
}
}
g2d.dispose();
}
}

可绘制形状类

public enum DrawableShape {
CIRCLE,
SQUARE,
TRIANGLE
}

为了避免错误的错误消息,您只需要解析相关的TextField,而不是全部。
例如,不需要解析圆的heightTF,并且会引发异常。
您可以通过将按钮操作侦听器更改为paint.addActionListener(e -> calculate());其中计算定义如下:

//for simplicity only 3 shapes are handled:
private void calculate(){
double area = 0, volume = 0;
try {
if (circle.isSelected()) {
drawPane.setDrawableShape(DrawableShape.CIRCLE);
double radius1 = Double.parseDouble(radius1TF.getText());
area = 3.14 * radius1 * radius1;
}
else if (cube.isSelected()) {
drawPane.setDrawableShape(null);
double side = Double.parseDouble(sideTF.getText());
volume = side * side * side;
}
else if (rectangle.isSelected()) {
drawPane.setDrawableShape(DrawableShape.RECTANGLE);
double height = Double.parseDouble(heightTF.getText());
double width = Double.parseDouble(widthTF.getText());
area = height * width;
}
areaTF.setText(" "+ area);
volumeTF.setText(" " + volume);
} catch(NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Please enter a number value.");
}
}

您需要将所有TextField变量设置为类变量:

private final JTextField heightTF, widthTF, sideTF, radius1TF, areaTF, volumeTF;

对于更好、更面向对象的解决方案,定义Shape

interface Shape {
double getArea();
double getVolume();
void draw(Graphics g, int x, int y);
}

并为每个形状实现它。例如:

class Circle implements Shape{
private final int radius;
Circle(int radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public double getVolume() {
return 0;
}
@Override
public void draw(Graphics g, int x, int y) {
g.fillOval(x, y, radius, radius);
}
}

最新更新