You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX课程作业HBox.setMargin静态调用错误及功能优化求助

解决方案

问题1:HBox.setMargin静态访问错误修复

该报错是因为setMargin是HBox类的静态方法,不能通过HBox的实例对象调用,修改方式如下:
将原代码中的

hbox.setMargin(rect, new Insets(20,30,40,50));

替换为

HBox.setMargin(rect, new Insets(20,30,40,50));

即可解决报错。

问题2:空输入/非法输入异常处理

新增输入转换工具方法,空输入、非数字输入统一返回0,避免抛出NumberFormatException,同时补充总价小数格式化逻辑,保留两位小数符合金额显示规范:

private double parseInput(TextField tf) {
    try {
        String text = tf.getText().trim();
        return text.isEmpty() ? 0 : Double.parseDouble(text);
    } catch (NumberFormatException e) {
        return 0;
    }
}

在结算点击事件中调用该方法读取每个输入框的值即可。

问题3:代码精简优化方案

原代码存在大量重复的控件创建逻辑,我们可以把水果的元数据(图片路径、单价、网格位置)封装为结构,循环批量创建控件,大幅减少重复代码,同时提升可维护性,后续新增水果仅需要补充元数据即可。


优化后的完整代码
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.text.DecimalFormat;

// 水果元数据类,存储每个水果的基础属性
class Fruit {
    String imgPath;
    double price;
    int col;
    int row;

    public Fruit(String imgPath, double price, int col, int row) {
        this.imgPath = imgPath;
        this.price = price;
        this.col = col;
        this.row = row;
    }
}

public class Grid_Layout extends Application {
    private static final DecimalFormat PRICE_FORMAT = new DecimalFormat("0.00");

    public static void main(String[] args) {
        Application.launch(args);
    }

    // 输入转换工具方法,处理空/非法输入
    private double parseInput(TextField tf) {
        try {
            String text = tf.getText().trim();
            return text.isEmpty() ? 0 : Double.parseDouble(text);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public void start(Stage primaryStage) {
        BorderPane border = new BorderPane();
        HBox hbox = new HBox(20);
        GridPane pane = new GridPane();
        border.setCenter(pane);
        border.setBottom(hbox);

        // GridPane基础配置
        pane.setAlignment(Pos.CENTER);
        pane.setPadding(new Insets(10,20,10,20));
        pane.setHgap(10);
        pane.setVgap(20);
        pane.setStyle("-fx-background-color: #e6ffb3;");

        // 批量定义所有水果的元数据,后续新增水果只需要在这里加条目即可
        Fruit[] fruits = new Fruit[]{
                new Fruit("File:images/apple.png", 0.99, 0, 1),
                new Fruit("File:images/apricot.png", 1.49, 3, 1),
                new Fruit("File:images/banana.png", 0.49, 6, 1),
                new Fruit("File:images/cherry.png", 1.99, 0, 2),
                new Fruit("File:images/grape.png", 0.99, 3, 2),
                new Fruit("File:images/lemmon.png", 1.99, 6, 2),
                new Fruit("File:images/orange.png", 0.99, 0, 3),
                new Fruit("File:images/pear.png", 1.49, 3, 3),
                new Fruit("File:images/strawberry.png", 1.99, 6, 3),
                new Fruit("File:images/watermelon.png", 0.99, 0, 4)
        };

        // 存储每个水果对应的输入框,用于后续结算读取数值
        TextField[] inputFields = new TextField[fruits.length];

        // 循环创建所有水果对应的图片、价格标签、输入框
        for (int i = 0; i < fruits.length; i++) {
            Fruit fruit = fruits[i];
            // 创建图片控件
            ImageView iv = new ImageView(new Image(fruit.imgPath));
            pane.add(iv, fruit.col, fruit.row);
            // 创建价格标签
            pane.add(new Label(fruit.price + "/lb"), fruit.col + 1, fruit.row);
            // 创建输入框
            TextField tf = new TextField();
            tf.setMaxWidth(50);
            inputFields[i] = tf;
            pane.add(tf, fruit.col + 2, fruit.row);
        }

        // 窗口尺寸配置
        ColumnConstraints col = new ColumnConstraints();
        col.setPercentWidth(10);
        pane.setPrefSize(700, 350);
        pane.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);

        // 标题配置
        Label titlelbl = new Label("Anna's Fresh Market");
        border.setTop(titlelbl);
        BorderPane.setAlignment(titlelbl, Pos.CENTER);
        titlelbl.setPadding(new Insets(10));
        titlelbl.setStyle("-fx-font-size: 25px; -fx-text-fill: green;-fx-background-color: #e6ffb3;");
        border.setStyle("-fx-background-color: #e6ffb3;");

        // 底部HBox配置
        Rectangle rect = new Rectangle();
        hbox.setAlignment(Pos.BOTTOM_CENTER);
        hbox.setStyle("-fx-border-color: green;");
        rect.setFill(Color.TRANSPARENT);
        hbox.setPadding(new Insets(10,10,10,10));
        // 静态方法用类名调用,解决报错
        HBox.setMargin(rect, new Insets(20,30,40,50));

        Label result = new Label("Total: $0.00");
        result.setAlignment(Pos.CENTER);
        Button btAdd = new Button("Checkout");
        hbox.getChildren().addAll(rect, result, btAdd);

        // 结算逻辑
        btAdd.setOnAction(e -> {
            double total = 0;
            for (int i = 0; i < fruits.length; i++) {
                total += parseInput(inputFields[i]) * fruits[i].price;
            }
            result.setText("Total: $" + PRICE_FORMAT.format(total));
        });

        // 窗口渲染
        Scene scene = new Scene(border);
        primaryStage.setTitle("Anna's Fresh Market");
        primaryStage.setScene(scene);
        primaryStage.setResizable(true);
        primaryStage.show();
    }
}

内容的提问来源于stack exchange,提问作者MOJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 07:06:04