在 JTextField 中的一个 Frame/Class/Window 中输入数字,并在另一个中的 JLabel 中显示它

Input number in one Frame/Class/Window in a JTextField and show it in a JLabel in another

我目前正在 Java 从事我自己的小项目,以学习和更好地理解面向对象编程。 这是一个银行应用程序,允许您存取款和检查您的余额,但我认为我的代码到处都是。

我无法将 TextField 的值从一帧获取到另一帧的 Label。我如何 link 将两个 JFrame 放在一起?

这是余额Class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Balance implements ActionListener {






    JFrame balanceFrame = new JFrame("Balance");
    JPanel balancePanel = new JPanel();
    JLabel balanceLabel = new JLabel("Balance:");
    JLabel refreshBalanceLabel = new JLabel();
    JButton exitBalanceButton = new JButton("EXIT");
    JButton backToMenuButton = new JButton("MENU");
    JButton refreshButton = new JButton("REFRESH");



    public void balance(){

        balanceFrame.setSize(420, 400);
        balanceFrame.add(balancePanel);
        balancePanel.setLayout(null);
        balanceFrame.setVisible(true);
        balanceFrame.setDefaultCloseOperation(balanceFrame.EXIT_ON_CLOSE);


        balanceLabel.setFont(new Font("Segoe UI", Font.PLAIN, 14));
        balanceLabel.setBounds(10,50,80,25);
        balancePanel.add(balanceLabel);

        refreshBalanceLabel.setFont(new Font("Segoe UI", Font.PLAIN, 14));
        refreshBalanceLabel.setBounds(80,50,80,25);
        balancePanel.add(refreshBalanceLabel);


        refreshButton.setBounds(100,220,100,25);
        refreshButton.setFocusPainted(false);
        balancePanel.add(refreshButton);
        refreshButton.addActionListener(this);


        exitBalanceButton.setBounds(100,160,100,25);
        exitBalanceButton.setFocusPainted(false);
        balancePanel.add(exitBalanceButton);


        backToMenuButton.setBounds(240,160,100,25);
        backToMenuButton.setFocusPainted(false);
        balancePanel.add(backToMenuButton);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Deposit depositObj = new Deposit();
        refreshBalanceLabel.setText(depositObj.newBalanceAmount);

    }

}

这是存款 Class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Deposit implements ActionListener {

    String newBalanceAmount;


    JFrame depositFrame = new JFrame("Deposit");
    JPanel depositPanel = new JPanel();
    JLabel amount = new JLabel("Amount:");
    JTextField amountTextField = new JTextField();
    JButton depositAmountButton = new JButton("DEPOSIT");



    public void depositing() {





        depositFrame.setSize(420, 400);
        depositFrame.add(depositPanel);
        depositPanel.setLayout(null);
        depositFrame.setVisible(true);
        depositFrame.setDefaultCloseOperation(depositFrame.EXIT_ON_CLOSE);


        amount.setFont(new Font("Segoe UI", Font.PLAIN, 14));
        amount.setBounds(10, 50, 80, 25);
        depositPanel.add(amount);


        amountTextField.setBounds(100, 50, 165, 25);
        depositPanel.add(amountTextField);


        depositAmountButton.setBounds(130, 160, 100, 25);
        depositAmountButton.setFocusPainted(false);
        depositPanel.add(depositAmountButton);
        depositAmountButton.addActionListener(this);

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        String newBalanceAmount = amountTextField.getText();
        Balance newBalance = new Balance();
        amountTextField.setText(newBalanceAmount);




    }

}

还有其他 classes 和框架,但它们与我现在的问题无关。

这里的大部分代码都是我的,有些来自互联网,所以它们都挤在一起,根本无法工作,我被卡住了。

我了解 java 的基础知识,目前在 OOP 方面做得很好,但我还不了解这一点。

如何将存款 class 中的 TextField(amountTextField) 输入复制到余额 class 中的 (refreshBalanceLabel)?

此外,我的代码有什么问题,我该如何改进它?

简介

让我们看看。我将您的 Deposit class 复制到我的 GUI 中。它不会编译。我修复了编译错误并添加了一个静态 main 方法,这样我就可以 运行 它并查看您的 GUI 是什么样子的。真是一团糟。为什么要将 GUI 设为固定大小?为什么对 Swing 组件使用绝对定位。为什么存款需要三个按钮?

这里有一种方法可以创建一个 JFrame GUI,它结合了存款功能和取款功能。

当您创建 Swing GUI 时,您应该尽量使其尽可能小。如果用户想要更大,可以拉伸 JFrame

为了创建像这样的 GUI,您必须了解如何布局 Swing GUI。因为这个GUI看起来像一个窗体,所以我用了一个GridBagLayout来构建这个GUI。我没有使用绝对定位。

我创建了一个保存帐户信息和交易信息的应用程序模型。 Account class 包含姓名、帐号和余额。 Transaction class 包含支票号码(可选)、日期、收款人和金额。

一旦我有了应用程序模型,构成 GUI 的 Swing 组件就很简单了。我用一个 JPanel 来容纳所有这些组件。我将组件一个一个地添加到我的 JPanel 中,运行 添加每个组件后进行测试。并非每次测试都成功。由于我一次只添加一个组件,所以我大致知道哪里出错了。

正如我在评论中所说,通读 Oracle 教程,Creating a GUI With JFC/Swing。跳过 Netbeans 部分。了解如何构建合适的 Swing GUI。

编辑添加

我创建了一个比较完整的支票簿 GUI。左侧 JTable 包含所有交易记录。右边是允许我添加事务的控件JPanel

我没有做任何错误检查。日期必须以 M/d/yy 格式输入。

如您所见,余额会在每次输入存款或取款交易后更新。

GUI 相当宽,为 1309 x 525 像素。也许寄存器应该显示在 JDialog 中,但我喜欢看到交易出现在 JTable 中的即时反馈。

说明

当我创建 Swing GUI 时,我使用 model / view / controller (MVC) 模式。这种模式使我能够将我的关注点分开并一次专注于应用程序的一部分。

我创建了 3 个模型 classes、一个视图 class 和 4 个控制器 classes。其中两个控制器 classes 处理 JTable 显示,另外两个控制器 classes 是 ActionListener classes 用于存款和取款 JButtons.

型号

Checkbook class 是主平面 Java getter / setter class 包含 [=15= 的实例] 和 java.util.ListTransaction 个实例。

Account class 是一个普通的 Java getter / setter class 包含账户名,账户号码,和账户余额。帐户余额是一个包含便士的 int 字段。这样可以确保添加存款和扣除提款不会导致任何浮点数舍入错误。

Transaction class 是一个普通的 Java getter / setter class 包含支票号码,交易日期,收款人、说明和金额。由于我们不对交易进行任何算术运算,因此金额存储为双精度值。

希望您注意到这里的趋势。所有应用程序模型 classes 都是普通的 Java getter / setter classes。该视图将处理 Swing 组件。

查看

视图由一个JFrame、一个tableJPanel和一个控件JPanel组成。 JFrame有一个默认的BorderLayout,所以我把tableJPanel放在中间,控件JPanel放在右边。如果扩展 JFrame,所有额外的 space 将转到 table JPanel

tableJPanel持有一个JScrollPane,后者持有一个JTable。 table JPanel 使用 BorderLayout。我为 JTable 创建了一个 table 模型和一个单元格渲染器。这些 classes 改进了 JTable 的视觉外观,并允许我根据底层 class 对 table 列进行排序。例如,金额列是 Double 值,但显示为逗号分隔的 String 值。

控件 JPanel 包含存款和取款交易的所有输入字段。我使用 GridBagLayout 来放置 Swing 组件。这个 JPanel 上有相当多的 Swing 组件。也许,我应该将控件 JPanel 设为单独的 class.

控制器

我不打算讨论 JTable 控制器。这个回答已经很长了。

我创建了两个单独的 ActionListener classes,一个用于存款,一个用于取款。我没有做任何错误检查。通过编写单独的 ActionListener classes,每个 class 都保持简单明了。

结语

创建这个 GUI 花了我几个小时。我一次编码一小块,并多次测试每一小块。我在写这个答案时发现代码中有几个错误。

这是完整的 运行 可用代码。我将所有 classes 都放在 classes 内,这样我就可以 post 把它作为一个块。复制代码并将其 运行 复制到您的 IDE 中以查看其工作原理。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

public class CheckbookGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CheckbookGUI());
    }
    
    private final Checkbook checkbook;
    
    private CheckbookTableModel tableModel;
    
    private JFrame frame;
    
    private JTable transactionTable;
    
    private JTextField balanceField;
    private JTextField depositDateField;
    private JTextField depositAmountField;
    private JTextField withdrawalCheckNumberField;
    private JTextField withdrawalDateField;
    private JTextField withdrawalPayeeField;
    private JTextField withdrawalDescriptionField;
    private JTextField withdrawalAmountField;
    
    public CheckbookGUI() {
        this.checkbook = new Checkbook();
    }

    @Override
    public void run() {
        frame = new JFrame("Checkbook GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createTablePanel(), BorderLayout.CENTER);
        frame.add(createTransactionPanel(), BorderLayout.AFTER_LINE_ENDS);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        
        System.out.println(frame.getSize());
    }
    
    private JPanel createTablePanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        String[] headers = { "Check #", "Date", "Payee", "Description", 
                "Deposit", "Withdrawal"};
        tableModel = new CheckbookTableModel();
        
        for (int index = 0; index < headers.length; index++) {
            tableModel.addColumn(headers[index]);
        }
        
        for (int index = 0; index < checkbook.getTransactions().size(); index++) {
            Transaction transaction = checkbook.getTransactions().get(index);
            updateTableModel(transaction);
        }
        
        transactionTable = new JTable(tableModel);
        transactionTable.setAutoCreateRowSorter(true);
        int[] width = { 75, 100, 250, 250, 75, 75 };
        int totalWidth = 0;
        CheckbookCellRenderer cellRenderer = new CheckbookCellRenderer();
        TableColumnModel columnModel = transactionTable.getColumnModel();
        for (int index = 0; index < headers.length; index++) {
            columnModel.getColumn(index).setCellRenderer(cellRenderer);
            columnModel.getColumn(index).setPreferredWidth(width[index]);
            totalWidth += width[index];
        }
        
        JScrollPane scrollPane = new JScrollPane(transactionTable);
        panel.add(scrollPane, BorderLayout.CENTER);
        
        Dimension d = panel.getPreferredSize();
        d.width = totalWidth + 50;
        panel.setPreferredSize(d);
        
        return panel;
    }
    
    public void updateTableModel(Transaction transaction) {
        Object[] object = new Object[6];
        object[0] = transaction.getCheckNumber();
        object[1] = transaction.getTransactionDate();
        object[2] = transaction.getPayee();
        object[3] = transaction.getDescription();
        
        double amount = transaction.getAmount();
        if (amount > 0.0) {
            object[4] = transaction.getAmount();
            object[5] = 0.0;
        } else {
            object[4] = 0.0;
            object[5] = -transaction.getAmount();
        }
        
        tableModel.addRow(object);
    }
    
    private JPanel createTransactionPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        Font titleFont = new Font("Segoe UI", Font.PLAIN, 24);
        Font font = new Font("Segoe UI", Font.PLAIN, 14);
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.gridwidth = 1;
        gbc.weightx = 1.0;
        
        gbc.gridx = 0;
        gbc.gridy = 0;
        JLabel nameLabel = new JLabel(checkbook.getAccount().getAccountName());
        nameLabel.setFont(titleFont);
        panel.add(nameLabel, gbc);
        
        gbc.gridx++;
        JLabel accountNumberLabel = new JLabel(
                checkbook.getAccount().getAccountNumber());
        accountNumberLabel.setFont(titleFont);
        accountNumberLabel.setHorizontalAlignment(JLabel.TRAILING);
        panel.add(accountNumberLabel, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        JLabel label = new JLabel("Balance:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        balanceField = new JTextField(20);
        balanceField.setEditable(false);
        balanceField.setFont(font);
        balanceField.setHorizontalAlignment(JTextField.TRAILING);
        balanceField.setText(String.format("%,.2f", 
                checkbook.getAccount().getBalance()));
        panel.add(balanceField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Deposit");
        label.setFont(titleFont);
        panel.add(label, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Date:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        depositDateField = new JTextField(20);
        depositDateField.setFont(font);
        panel.add(depositDateField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Amount:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        depositAmountField = new JTextField(20);
        depositAmountField.setFont(font);
        depositAmountField.setHorizontalAlignment(JTextField.TRAILING);
        panel.add(depositAmountField, gbc);
        
        gbc.gridwidth = 2;
        gbc.gridx = 0;
        gbc.gridy++;
        JButton button = new JButton("Deposit");
        button.addActionListener(new DepositListener(this, checkbook));
        button.setFont(font);
        panel.add(button, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Withdrawl");
        label.setFont(titleFont);
        panel.add(label, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Check Number:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        withdrawalCheckNumberField = new JTextField(20);
        withdrawalCheckNumberField.setFont(font);
        withdrawalCheckNumberField.setHorizontalAlignment(JTextField.TRAILING);
        panel.add(withdrawalCheckNumberField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Date:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        withdrawalDateField = new JTextField(20);
        withdrawalDateField.setFont(font);
        panel.add(withdrawalDateField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Payee:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        withdrawalPayeeField = new JTextField(20);
        withdrawalPayeeField.setFont(font);
        panel.add(withdrawalPayeeField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Description:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        withdrawalDescriptionField = new JTextField(20);
        withdrawalDescriptionField.setFont(font);
        panel.add(withdrawalDescriptionField, gbc);
        
        gbc.gridx = 0;
        gbc.gridy++;
        label = new JLabel("Amount:");
        label.setFont(font);
        panel.add(label, gbc);
        
        gbc.gridx++;
        withdrawalAmountField = new JTextField(20);
        withdrawalAmountField.setFont(font);
        withdrawalAmountField.setHorizontalAlignment(JTextField.TRAILING);
        panel.add(withdrawalAmountField, gbc);
        
        gbc.gridwidth = 2;
        gbc.gridx = 0;
        gbc.gridy++;
        button = new JButton("Withdrawal");
        button.addActionListener(new WithdrawalListener(this, checkbook));
        button.setFont(font);
        panel.add(button, gbc);
        
        return panel;
    }
    
    public void pack() {
        frame.pack();
    }
    
    public void updateBalanceField() {
        this.balanceField.setText(String.format("%,.2f", 
                checkbook.getAccount().getBalance()));
    }

    public JTextField getDepositDateField() {
        return depositDateField;
    }

    public JTextField getDepositAmountField() {
        return depositAmountField;
    }

    public JTextField getWithdrawalCheckNumberField() {
        return withdrawalCheckNumberField;
    }

    public JTextField getWithdrawalDateField() {
        return withdrawalDateField;
    }

    public JTextField getWithdrawalPayeeField() {
        return withdrawalPayeeField;
    }

    public JTextField getWithdrawalDescriptionField() {
        return withdrawalDescriptionField;
    }

    public JTextField getWithdrawalAmountField() {
        return withdrawalAmountField;
    }
    
    public class CheckbookTableModel extends DefaultTableModel {

        private static final long serialVersionUID = 1L;

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
            case 0:
                return Integer.class;
            case 1:
                return LocalDate.class;
            case 4:
            case 5:
                return Double.class;
            default:
                return String.class;
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
        
    }
    
    public class CheckbookCellRenderer implements TableCellRenderer {
        
        private DateTimeFormatter formatter;
        
        private JLabel label;
        
        public CheckbookCellRenderer() {
            this.formatter = DateTimeFormatter.ofPattern("MMM d, yyyy");
            Font font = new Font("Segoe UI", Font.PLAIN, 14);
            this.label = new JLabel();
            label.setFont(font);
            
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, 
                Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {
            label.setHorizontalAlignment(JLabel.LEADING);
            
            switch (column) {
            case 0:
                if (Integer.valueOf(value.toString()) <= 0) {
                    label.setText("");
                } else {
                    label.setHorizontalAlignment(JLabel.TRAILING);
                    label.setText(value.toString() + "  ");
                }
                break;
            case 1:
                LocalDate date = (LocalDate) value;
                label.setText("  " + formatter.format(date));
                break;
            case 4:
            case 5:
                double amount = Double.valueOf(value.toString());
                if (amount <= 0.0) {
                    label.setText("");
                } else {
                    label.setHorizontalAlignment(JLabel.TRAILING);
                    label.setText(String.format("%,.2f", amount) + "  ");
                }
                break;
            default:
                label.setText("  " + value.toString());
                break;
            }
            
            return label;
        }
        
    }
    
    public class DepositListener implements ActionListener {
        
        private final CheckbookGUI view;
        
        private final Checkbook model;
        
        public DepositListener(CheckbookGUI view, Checkbook model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            String date = view.getDepositDateField().getText().trim();
            Double amount = Double.valueOf(view.getDepositAmountField().getText().trim());
            Transaction transaction = new Transaction(null, date, "Deposit", "", amount);
            
            model.addTransaction(transaction);
            model.getAccount().addDeposit(amount);
            
            view.updateBalanceField();
            view.updateTableModel(transaction);
            view.getDepositAmountField().setText("");
            view.getDepositDateField().setText("");
        }
        
    }
    
    public class WithdrawalListener implements ActionListener {
        
        private final CheckbookGUI view;
        
        private final Checkbook model;
        
        public WithdrawalListener(CheckbookGUI view, Checkbook model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            String checkNumberString = view.getWithdrawalCheckNumberField().getText().trim();
            String date = view.getWithdrawalDateField().getText().trim();
            String payee = view.getWithdrawalPayeeField().getText().trim();
            String description = view.getWithdrawalDescriptionField().getText().trim();
            Double amount = Double.valueOf(view.getWithdrawalAmountField().getText().trim());
            
            Integer checkNumber = null;
            try {
                checkNumber = Integer.valueOf(checkNumberString);
            } catch (NumberFormatException e) {
            }
            
            Transaction transaction = new Transaction(checkNumber, date, payee, 
                    description, -amount);
            
            model.addTransaction(transaction);
            model.getAccount().subtractWithdrawal(amount);
            
            view.updateBalanceField();
            view.updateTableModel(transaction);
            view.getWithdrawalCheckNumberField().setText("");
            view.getWithdrawalDateField().setText("");
            view.getWithdrawalPayeeField().setText("");
            view.getWithdrawalDescriptionField().setText("");
            view.getWithdrawalAmountField().setText("");
        }
        
    }

    public class Checkbook {
        
        private final Account account;
        
        private final List<Transaction> transactions;
        
        public Checkbook() {
            this.transactions = new ArrayList<>();
            this.account = new Account("10002939", "John H. Smith");
            this.account.addDeposit(1400.00);
            Transaction transaction = new Transaction(
                    null, "4/1/21", "Starting Balance", "", 1400.00);
            addTransaction(transaction);
        }
        
        public void addTransaction(Transaction transaction) {
            this.transactions.add(transaction);
        }

        public Account getAccount() {
            return account;
        }

        public List<Transaction> getTransactions() {
            return transactions;
        }
        
    }
    
    public class Account {
        
        private int balance;
        
        private final String accountNumber;
        private final String accountName;
        
        public Account(String accountNumber, String accountName) {
            this.accountNumber = accountNumber;
            this.accountName = accountName;
            this.balance = 0;
        }

        public String getAccountNumber() {
            return accountNumber;
        }

        public String getAccountName() {
            return accountName;
        }

        public double getBalance() {
            return 0.01 * balance;
        }

        public void addDeposit(double amount) {
            this.balance += (int) (100.0 * amount);
        }
        
        public void subtractWithdrawal(double amount) {
            this.balance -= (int) (100.0 * amount);
        }
        
    }
    
    public class Transaction {
        
        private final double amount;
        
        private final int checkNumber;
        
        private final DateTimeFormatter inputFormatter;
        
        private final LocalDate transactionDate;
        
        private final String description;
        private final String payee;

        public Transaction(Integer checkNumber, String transactionDateString, 
                String payee, String description, double amount) {
            if (checkNumber == null) {
                this.checkNumber = 0;
            } else {
                this.checkNumber = checkNumber;
            }
            
            this.inputFormatter = DateTimeFormatter.ofPattern("M/d/yy");
            this.transactionDate = LocalDate.parse(transactionDateString, inputFormatter);
            this.payee = payee;
            this.description = description;
            this.amount = amount;
        }

        public double getAmount() {
            return amount;
        }

        public int getCheckNumber() {
            return checkNumber;
        }

        public LocalDate getTransactionDate() {
            return transactionDate;
        }

        public String getPayee() {
            return payee;
        }

        public String getDescription() {
            return description;
        }
        
    }

}