为小费计算器使用复选框和文本框

Using checkbox and textbox for tip calculator

我正在做一个项目,制作一个小费计算器,它有两个复选框 15% 和 20%,还有一个文本框可以让你输入你自己的百分比,我只是不知道如何 link 将复选框和文本框添加到它们会影响答案的位置。我只是希望有人能指出 link 这些东西在一起需要什么。

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JCheckBox;
import java.awt.BorderLayout;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;

public class TipCalc {

    private JFrame frame;
    private JLabel lblTipAmount;
    private JTextField txtEnterBill;
    private JTextField txtCustomTip;
    private final ButtonGroup buttonGroup = new ButtonGroup();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TipCalc window = new TipCalc();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public TipCalc() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.getContentPane().setForeground(Color.GREEN);
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        double percent = 1;
        double base = 1 * percent;

        JButton btnGetTip = new JButton("Get Tip");
        btnGetTip.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                double num1;
                double answer;
                Enumeration<AbstractButton> bg = buttonGroup.getElements();
                    while (bg.hasMoreElements()) {
                        JCheckBox jcb = (JCheckBox) bg.nextElement();
                            if(jcb.isSelected());
                            JOptionPane.showMessageDialog(null, "Hello");
                    }



                try {
                    num1=Double.parseDouble(txtEnterBill.getText());

                                        answer=num1 * base;
                    lblTipAmount.setText(Double.toString(answer));
                } catch(Exception e1) {
                    JOptionPane.showMessageDialog(null, "Please Enter A valid Amount");
                }
                //JOptionPane.showMessageDialog(null, "Test");
                //lblTipAmount.setText("The Tip is:" + answer);

            }
        });
        btnGetTip.setBackground(Color.CYAN);
        btnGetTip.setBounds(130, 121, 150, 50);
        frame.getContentPane().add(btnGetTip);

        txtEnterBill = new JTextField();
        txtEnterBill.setHorizontalAlignment(SwingConstants.CENTER);
        txtEnterBill.setText("Enter Bill");
        txtEnterBill.setBounds(130, 11, 150, 20);
        frame.getContentPane().add(txtEnterBill);
        txtEnterBill.setColumns(10);

        lblTipAmount = new JLabel("Tip Amount");
        lblTipAmount.setHorizontalAlignment(SwingConstants.CENTER);
        lblTipAmount.setBounds(130, 201, 150, 20);
        frame.getContentPane().add(lblTipAmount);

        JCheckBox checkBox15 = new JCheckBox("15%");
        buttonGroup.add(checkBox15);
        checkBox15.setBounds(130, 38, 97, 23);
        frame.getContentPane().add(checkBox15);

        if (checkBox15.isSelected())
            percent = (double) 1.15;

        JCheckBox checkBox20 = new JCheckBox("20%");
        buttonGroup.add(checkBox20);
        checkBox20.setBounds(130, 64, 97, 23);
        frame.getContentPane().add(checkBox20);

        txtCustomTip = new JTextField();
        txtCustomTip.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            }
        });
        txtCustomTip.setHorizontalAlignment(SwingConstants.CENTER);
        txtCustomTip.setText("Custom Tip In % or Decimal\r\n");
        txtCustomTip.setBounds(125, 94, 160, 20);
        frame.getContentPane().add(txtCustomTip);
        txtCustomTip.setColumns(10);
    }
}

基本答案是,检查每个 JCheckBox 看它是否被选中,并根据选中的那个,将它代表的数量分配给某个变量。这将需要ui您了解有关JCheckBox的一些信息。

你可以:

  • 使用实例字段并简单地检查每个实例字段以查看它们是否被选中,如果您有大量字段,这将成为一个问题
  • 使用组件 putClientPropertygetClientProperty 功能在每个字段中根据键存储对象,个人而言,这有点脏,因为您需要进行对象转换,容易出错
  • 使用某种模型和 Action API

此示例使用简单的 "model" 和 Action API 来设置基本功能。

"model"保持当前选择的百分比。选择其中一个可用选项后,模型会自动更新。当用户按下 "calculate" 按钮时,从 "model" 中获取小费百分比并进行计算

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JSpinner subTotal;
        private JSpinner custom;
        private JButton btnCalculate;

        private TipModel model;

        private JLabel tipAmountLabel;
        private JLabel billTotalLabel;

        public TestPane() {
            setBorder(new EmptyBorder(10, 10, 10, 10));
            subTotal = new JSpinner(new SpinnerNumberModel());
            subTotal.setValue(0d);
            subTotal.setEditor(new JSpinner.NumberEditor(subTotal, "$#0.0#"));

            model = new TipModel();

            custom = new JSpinner(new SpinnerNumberModel(0, 0, 1, 0.05));
            custom.setEditor(new JSpinner.NumberEditor(custom, "##%"));

            JCheckBox cb15 = new JCheckBox(new TipAction(model, 0.15d));
            JCheckBox cb20 = new JCheckBox(new TipAction(model, 0.20d));
            JCheckBox cbCustom = new JCheckBox(new CustomTipAction(model, custom));

            ButtonGroup bg = new ButtonGroup();
            bg.add(cb15);
            bg.add(cb20);
            bg.add(cbCustom);

            btnCalculate = new JButton("Calculate Tip");
            btnCalculate.setMargin(new Insets(10, 10, 10, 10));

            tipAmountLabel = new JLabel("...");
            billTotalLabel = new JLabel("...");
            billTotalLabel.setHorizontalAlignment(JLabel.CENTER);
            tipAmountLabel.setHorizontalAlignment(JLabel.CENTER);

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(2, 2, 2, 2);
            add(subTotal, gbc);

            gbc.anchor = GridBagConstraints.WEST;
            gbc.gridy++;
            gbc.fill = GridBagConstraints.NONE;
            add(cb15, gbc);
            gbc.gridy++;
            add(cb20, gbc);
            gbc.gridwidth = 1;
            gbc.gridy++;
            add(cbCustom, gbc);

            gbc.gridx++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(custom, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(btnCalculate, gbc);

            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridy++;
            add(tipAmountLabel, gbc);
            gbc.gridy++;
            add(billTotalLabel, gbc);

            btnCalculate.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    double tipPercentage = model.getTipPercentage();

                    if (tipPercentage > 0.0) {

                        double subTotalAmount = (double) subTotal.getValue();
                        double tipAmount = subTotalAmount * tipPercentage;
                        double billTotal = subTotalAmount + tipAmount;

                        tipAmountLabel.setText("Tip amount: " + NumberFormat.getCurrencyInstance().format(tipAmount));
                        billTotalLabel.setText("Bill total: " + NumberFormat.getCurrencyInstance().format(billTotal));

                    } else {
                        JOptionPane.showMessageDialog(TestPane.this, "Please provide a valid tip percentage");
                    }
                }
            });
        }

        public class TipModel {

            private double tipPercentage;

            public double getTipPercentage() {
                return tipPercentage;
            }

            public void setTipPercentage(double tipPercentage) {
                this.tipPercentage = tipPercentage;
            }

        }

        public class TipAction extends AbstractAction {

            private TipModel model;
            private double tipPercentage;

            public TipAction(TipModel model, double tipPercentage) {
                this.model = model;
                this.tipPercentage = tipPercentage;
                putValue(NAME, NumberFormat.getPercentInstance().format(tipPercentage));
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                model.setTipPercentage(tipPercentage);
            }

        }

        public class CustomTipAction extends AbstractAction {

            private TipModel model;
            private JSpinner spinner;

            public CustomTipAction(TipModel model, JSpinner spinner) {
                this.model = model;
                this.spinner = spinner;

                spinner.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        model.setTipPercentage((double) spinner.getValue());
                    }
                });
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                model.setTipPercentage((double) spinner.getValue());
            }

        }

    }

}

避免使用 null 布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件个体大小的因素太多,none您可以控制。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

看看:

了解更多详情