【问题标题】:Why does my program crash when textfields are left blank?当文本字段留空时,为什么我的程序会崩溃?
【发布时间】:2017-10-09 19:40:38
【问题描述】:

我有这个用于学校的程序,当您填写所有文本字段时它运行良好。但是,如果您在字段上留任何空白,整个程序将崩溃。这是我的代码:

 /** Kyle N Welch
  * Sept 29th, 2017
  * This program will calculate the expanses of a business
  * man/woman on a business trip using the GUI
  * */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.DecimalFormat;

//Class name declaration
public class KNW_TravelExpenses extends JFrame
{
  private JPanel travelInfoPanel;
  private JPanel buttonPanel;

  // Labels
  private JLabel numDaysOnTripLabel;
  private JLabel amountAirfairLabel;
  private JLabel amountCarRentalLabel;
  private JLabel milesDrivenLabel;
  private JLabel parkingFeesLabel;
  private JLabel taxiFeesLabel;
  private JLabel confRegLabel;
  private JLabel lodgingChargesPerNightLabel;

  // Text Fields
  private JTextField numDaysOnTripTextField;
  private JTextField amountAirfairTextField;
  private JTextField amountCarRentalTextField;
  private JTextField milesDrivenTextField;
  private JTextField parkingFeesTextField;
  private JTextField taxiFeesTextField;
  private JTextField confRegTextField;
  private JTextField lodgingChargesPerNightTextField;

  // Buttons
  private JButton resetButton;
  private JButton calcButton;

  // Meals amount reimbursed by company per day.
  private double mealsAmount = 37.00;

  // Parking Fees amount reimbursed by company per day.
  private double parkingFeesReimbursed = 10.00;

  // Taxi Charges amount reimbursed by company per day.
  private double taxiChargesReimbursed = 20.00;

  // Lodging Charges amount reimbursed by company per day.
  private double lodgingChargesReimbursed = 95.00;

  // Private Vehicle per miles reimbursment rate.
  private double prVechiclePerMileReimbursed = 0.27;

  // Constructor
  public KNW_TravelExpenses( )
  {
    //set the title.
    super("TRAVEL EXPENSES");
    // Set the main window
    setLocationRelativeTo(null);
    // Specify an action for the close button.
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Create a BorderLayout manager for the content pane.
    setLayout(new BorderLayout());
    // Build the TravelInfo and Buttons panels
    buildTravelInfoPanel();
    buildButtonPanel();
    // Add the panels to the frame's content pane
    add(travelInfoPanel, BorderLayout.CENTER);
    add(buttonPanel, BorderLayout.SOUTH);
    // Pack the contents of the window and display it.
    pack();
    setVisible(true);
  }
  // The buildTravelInfoPanel method adds the labels
  //and text fiels to the TravelInfo panel.
  private void buildTravelInfoPanel()
  {
    // Create the labels for TravelInfo fields
    numDaysOnTripLabel = new JLabel("Number of days on trip: ");
    amountAirfairLabel = new JLabel("Amount of airfair: ");
    amountCarRentalLabel = new JLabel("Amount of car rental fees: ");
    milesDrivenLabel = new JLabel("Number of Miles driven: ");
    parkingFeesLabel = new JLabel("Amount of Parking fees: ");
    taxiFeesLabel = new JLabel("Amount of Tax charges: ");
    confRegLabel = new JLabel("Conference or Seminar registration fees: ");
    lodgingChargesPerNightLabel = new JLabel("Lodging charges per night: ");
    // Create the text boxes for TravelInfo user input
    numDaysOnTripTextField = new JTextField(3);
    amountAirfairTextField = new JTextField(8);
    amountCarRentalTextField = new JTextField(8);
    milesDrivenTextField = new JTextField(4);
    parkingFeesTextField = new JTextField(6);
    taxiFeesTextField = new JTextField(6);
    confRegTextField = new JTextField(8);
    lodgingChargesPerNightTextField = new JTextField(6);
    // Create a panel to hold labels and text fields.
    travelInfoPanel = new JPanel();
    // Create GridLayout manager
    travelInfoPanel.setLayout(new GridLayout(10, 2));
    // Add the labels and text fields to this panel.
    travelInfoPanel.add(numDaysOnTripLabel);
    travelInfoPanel.add(numDaysOnTripTextField);
    travelInfoPanel.add(amountAirfairLabel);
    travelInfoPanel.add(amountAirfairTextField);
    travelInfoPanel.add(amountCarRentalLabel);
    travelInfoPanel.add(amountCarRentalTextField);
    travelInfoPanel.add(milesDrivenLabel);
    travelInfoPanel.add(milesDrivenTextField);
    travelInfoPanel.add(parkingFeesLabel);
    travelInfoPanel.add(parkingFeesTextField);
    travelInfoPanel.add(taxiFeesLabel);
    travelInfoPanel.add(taxiFeesTextField);
    travelInfoPanel.add(confRegLabel);
    travelInfoPanel.add(confRegTextField);
    travelInfoPanel.add(lodgingChargesPerNightLabel);
    travelInfoPanel.add(lodgingChargesPerNightTextField);
    // Add an empty border around the panel for spacing.
    travelInfoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 1, 10));
  }

  /*** The buildButtonPanel method creates and adds the Reset and Calculate
    * buttons to the TravelExpense panel as its own panel.
    */
  private void buildButtonPanel()
  {
    // Create the calcButton.
    calcButton = new JButton("CALCULATE");

    // Register an event listener
    calcButton.addActionListener(new CalcButtonListener());

    //Create the resetButton.
    resetButton = new JButton("RESET");

    // Create the Buttons panels.
    buttonPanel = new JPanel();

    buttonPanel.setLayout(new BorderLayout(5, 5));

    buttonPanel.add(resetButton, BorderLayout.WEST);
    buttonPanel.add(calcButton, BorderLayout.CENTER);

    //Add an empty border around the panel for spacing.
    buttonPanel.setBorder(BorderFactory.createEmptyBorder(1, 10, 10, 10));
  }

  /** Private inner class that handles the event when the user clicks
    * the Calculate button .
    */
  private class CalcButtonListener implements ActionListener
  {
    // Declare variables
    String input;
    int days;
    double air;
    double carRental;
    double miles;
    double parking;
    double taxi;
    double confReg;
    double lodging;
    double mealsAmount;

    public void actionPerformed(ActionEvent e)
    {
      //Declare variables
      double actualExpenses;
      double milesExpenses;
      double allowableExpenses;
      double excessAir;
      double excessCarRental;
      double excessParking;
      double excessTaxi;
      double excessLodging;
      double excessAmountTotal;
      double amountSaved=0;
      double paidBackAmount=0;

      //Create a DecimalFormat object to format the totals as dollar amounts.
      DecimalFormat dollar = new DecimalFormat("$#,##0.00");

      //Get Input Data the user entered in the text fields.
      days = Integer.parseInt(numDaysOnTripTextField.getText());
      air = Double.parseDouble(amountAirfairTextField.getText());
      carRental = Double.parseDouble(amountCarRentalTextField.getText());
      miles = Double.parseDouble(milesDrivenTextField.getText());
      parking = Double.parseDouble(parkingFeesTextField.getText());
      taxi = Double.parseDouble(taxiFeesTextField.getText());
      confReg = Double.parseDouble(confRegTextField.getText());
      lodging = Double.parseDouble(lodgingChargesPerNightTextField.getText());

      //Determine actualExpenses method.
      milesExpenses = miles * prVechiclePerMileReimbursed;
      actualExpenses = (carRental + parking + taxi + lodging +mealsAmount)
        *days+air+milesExpenses+ confReg ;

      // Calculate the allowableExpenses.
      allowableExpenses=(mealsAmount+parkingFeesReimbursed+taxiChargesReimbursed+lodgingChargesReimbursed)
        *days+milesExpenses+air+confReg;

      // Calculate the paidBackAmount.
      if(actualExpenses>allowableExpenses)
        paidBackAmount=actualExpenses-allowableExpenses;
      else
        amountSaved=allowableExpenses-actualExpenses;

      // Display the Totals message box.
      if(paidBackAmount>0)
        JOptionPane.showMessageDialog(null, "Total expenses: "
                                        + dollar.format(actualExpenses) +"\n" +"Allowable expenses: "
                                        + dollar.format(allowableExpenses)+"\n" +"\n" + "Amount to be paid back: "
                                        +dollar.format(paidBackAmount));
      else if(amountSaved>0)
        JOptionPane.showMessageDialog(null, "Total expenses: " + dollar.format(actualExpenses)
                                        +"\n" +"Allowable expenses: " + dollar.format(allowableExpenses)+"\n" +
                                      "\n" + "Amount Saved: "+dollar.format(amountSaved));
      else
        JOptionPane.showMessageDialog(null, "Total expenses: " + dollar.format(actualExpenses)
                                        +"\n" +"Allowable expenses: " + dollar.format(allowableExpenses)+"\n" );
    }
  }

  /*** Private inner class that handles the event when the user clicks
    * the RESET button .
    */
  private class ResetButtonListener implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      numDaysOnTripTextField.setText(" ");
      amountAirfairTextField.setText(" ");
      amountCarRentalTextField.setText(" ");
      milesDrivenTextField.setText(" ");
      parkingFeesTextField.setText(" ");
      taxiFeesTextField.setText(" ");
      confRegTextField.setText(" ");
      lodgingChargesPerNightTextField.setText(" ");
    }
  }
// The main method
  public static void main(String[] args)
  {
    new TravelExpenses();
  }
}

当字段留空时可能导致 GUI 程序崩溃的任何内容。必须有一些东西,我显然错过了它。如果您能向我指出并告诉我如何解决它,将不胜感激?

【问题讨论】:

  • 请花时间将您的代码编辑为minimal reproducible example
  • 给我堆栈跟踪
  • @a_river_in_canada
  • 定义“崩溃”。它是如何失败的?什么是异常或错误?当您在调试器中单步执行时,具体发生在哪里?
  • 尝试将“”转换为整数/双精度..你会得到你需要的

标签: java user-interface crash jtextfield


【解决方案1】:

在使用 parseInt 时尝试 try-catch,因为它会引发 FormatException(尝试从 null 字符串到 parseInt 可能会以崩溃结束)。

【讨论】:

    【解决方案2】:

    错误的发生很可能是因为您尝试将空字符串视为数字。该程序是否应该处理丢失的数据?如果是,则必须修改计算,将空白视为零或以其他方式。

    重要的一课是查看堆栈跟踪。 Java 会准确地告诉你什么地方出了问题。正如其他人所说,要么将您的程序减少到最小,这样我们就不必猜测,或者提供堆栈跟踪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多