JButton не связан с ActionLister

public class OpenFrame extends JFrame implements ActionListener {

private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private BudgetPlanner budgetPlanner;

private JFrame openFrame;

private JLabel welcomeMessage;
private JPanel openPanel = new JPanel();
private JPanel inputSpace;

private JButton loadButton = new JButton();
private JButton resetButton = new JButton();
private JButton addIncomeButton;
private JButton addExpenseButton;
private JButton viewExpenseButton;
private JButton viewIncomeButton;

private JTextField inputIncome;

public BudgetPlanner callBudgetPlanner() {
    try {
        budgetPlanner = new BudgetPlanner();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return budgetPlanner;
}

public OpenFrame() {
    openFrame = new JFrame();
    openFrame.setTitle("BudgetPlanner");
    openFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    openFrame.setResizable(false);
    openFrame.setLayout(null);
    openFrame.setLocationRelativeTo(null);
    openFrame.setSize(new Dimension(WIDTH, HEIGHT));
    openFrame.getContentPane().setBackground(Color.GRAY);
    openPanel();
    openFrame.setContentPane(openPanel);

    openFrame.setVisible(true);
}

public void openPanel() {
    openPanel.setLayout(null);

    welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
    welcomeMessage.setVerticalTextPosition(TOP);
    welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
    welcomeMessage.setBounds(50, 20, 500, 200);
    welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));

    openPanel.setBounds(0, 0, 500, 500);
    openPanel.add(welcomeMessage);

    loadButton.setBounds(200, 170, 100, 50);
    loadButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    loadButton.setText("Load Data");
    loadButton.addActionListener(this);
    loadButton.setFocusable(false);

    resetButton.setBounds(200, 230, 100, 50);
    resetButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    resetButton.setText("Reset Data");
    resetButton.addActionListener(this);
    resetButton.setFocusable(false);

    openPanel.add(loadButton);
    openPanel.add(resetButton);
}

public void plannerScreen() {
    JPanel loadPanel = new JPanel();
    openFrame.setContentPane(loadPanel);
    loadPanel.setBounds(0, 0, 500, 500);
    JLabel loadCompleteMessage = new JLabel("Welcome to Budget Planner App.");
    loadCompleteMessage.setBounds(138, TOP, 500, 50);
    loadCompleteMessage.setFont(new Font("Arial", Font.BOLD, 14));
    loadPanel.add(loadCompleteMessage);
    JLabel optionMessage = new JLabel("What would you like to do?");
    optionMessage.setBounds(175, TOP + 40, 500, 10);
    optionMessage.setFont(new Font("Arial", Font.ITALIC, 13));
    loadPanel.add(optionMessage);
    openButton();
    loadPanel.add(addIncomeButton);
    loadPanel.add(addExpenseButton);
    loadPanel.add(viewIncomeButton);
    loadPanel.add(viewExpenseButton);
}

public void openButton() {
    addIncomeButton = new JButton("Add Income");
    addIncomeButton.setBounds(180, 110, 140, 45);
    addIncomeButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    addExpenseButton = new JButton("Add Expense");
    addExpenseButton.setBounds(180, 160, 140, 45);
    addExpenseButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    viewIncomeButton = new JButton("View Income");
    viewIncomeButton.setBounds(180, 210, 140, 45);
    viewIncomeButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    viewExpenseButton = new JButton("View Expense");
    viewExpenseButton.setBounds(180, 260, 140, 45);
    viewExpenseButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));

    addIncomeButton.addActionListener(new InputData());

}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == loadButton) {
        JOptionPane.showMessageDialog(null, "Loading Complete!");
        plannerScreen();
    }

    if (e.getSource() == resetButton) {
        JOptionPane.showMessageDialog(null, "Saved data erased.");
        plannerScreen();
    }
}

public class InputData implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        inputSpace = new JPanel();
        inputSpace.setBounds(0, 300, 500, 200);
        inputIncome = new JTextField("How much is your income?", 20);
        openPanel.add(inputSpace);
        inputSpace.add(inputIncome);
    }
}

Мой код показан выше. Проблема в том, что когда я нажимаю кнопку addIncomeButton, она не связывается с созданным мной списком действий InputData. После нажатия addIncomeButton ничего не происходит. Как решить эту проблему? ;-;

Моя цель состоит в том, что после нажатия кнопки появится JTextField, который будет добавлен на ту же панель.

Любая помощь будет оценена! Огромное спасибо!

Обычно рекомендуется не использовать макет null и возиться с setBounds(). Вместо этого используйте фактический менеджер компоновки, см. docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Progman 19.03.2022 12:36

Вы не видите новые компоненты, потому что openFrame.setContentPane(loadPanel); заменил видимый openPanel на loadPanel.

Progman 19.03.2022 13:26

Канонический способ поменять местами представления — использовать CardLayout. И да, избегайте нулевых макетов, как метко предлагает @Progman.

Hovercraft Full Of Eels 19.03.2022 13:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Решение не идеально, вы можете улучшить код в соответствии с вашими потребностями. Кажется, что кнопка реагирует на клики, чтобы убедиться, что я добавил оператор System.out.println("Clicked") внутри метода actionPerformed.

package swingButton;


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

import static javax.swing.SwingConstants.TOP;

public class OpenFrame extends JFrame implements ActionListener {

    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;
//    private BudgetPlanner budgetPlanner;

    private JFrame openFrame;

    private JLabel welcomeMessage;
    private JPanel openPanel = new JPanel();
    private JPanel inputSpace;

    private JButton loadButton = new JButton();
    private JButton resetButton = new JButton();
    private JButton addIncomeButton;
    private JButton addExpenseButton;
    private JButton viewExpenseButton;
    private JButton viewIncomeButton;

    private JTextField inputIncome;

//    public BudgetPlanner callBudgetPlanner() {
//        try {
//            budgetPlanner = new BudgetPlanner();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//        return budgetPlanner;
//    }

    public OpenFrame() {
        openFrame = new JFrame();
        openFrame.setTitle("BudgetPlanner");
        openFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        openFrame.setResizable(false);
        openFrame.setLayout(null);
        openFrame.setLocationRelativeTo(null);
        openFrame.setSize(new Dimension(WIDTH, HEIGHT));
        openFrame.getContentPane().setBackground(Color.GRAY);
        openPanel();
        openFrame.setContentPane(openPanel);

        openFrame.setVisible(true);
    }

    public void openPanel() {
        openPanel.setLayout(null);

        welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
        welcomeMessage.setVerticalTextPosition(TOP);
        welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
        welcomeMessage.setBounds(50, 20, 500, 200);
        welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));

        openPanel.setBounds(0, 0, 500, 500);
        openPanel.add(welcomeMessage);

        loadButton.setBounds(200, 170, 100, 50);
        loadButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        loadButton.setText("Load Data");
        loadButton.addActionListener(this);
        loadButton.setFocusable(false);

        resetButton.setBounds(200, 230, 100, 50);
        resetButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        resetButton.setText("Reset Data");
        resetButton.addActionListener(this);
        resetButton.setFocusable(false);

        openPanel.add(loadButton);
        openPanel.add(resetButton);
    }

    public void plannerScreen() {
        JPanel loadPanel = new JPanel();
        openFrame.setContentPane(loadPanel);
        loadPanel.setBounds(0, 0, 500, 500);
        JLabel loadCompleteMessage = new JLabel("Welcome to Budget Planner App.");
        loadCompleteMessage.setBounds(138, TOP, 500, 50);
        loadCompleteMessage.setFont(new Font("Arial", Font.BOLD, 14));
        loadPanel.add(loadCompleteMessage);
        JLabel optionMessage = new JLabel("What would you like to do?");
        optionMessage.setBounds(175, TOP + 40, 500, 10);
        optionMessage.setFont(new Font("Arial", Font.ITALIC, 13));
        loadPanel.add(optionMessage);
        openButton();
        loadPanel.add(addIncomeButton);
        loadPanel.add(addExpenseButton);
        loadPanel.add(viewIncomeButton);
        loadPanel.add(viewExpenseButton);
    }

    public void openButton() {
        addIncomeButton = new JButton("Add Income");
        addIncomeButton.setBounds(180, 110, 140, 45);
        addIncomeButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        addExpenseButton = new JButton("Add Expense");
        addExpenseButton.setBounds(180, 160, 140, 45);
        addExpenseButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        viewIncomeButton = new JButton("View Income");
        viewIncomeButton.setBounds(180, 210, 140, 45);
        viewIncomeButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        viewExpenseButton = new JButton("View Expense");
        viewExpenseButton.setBounds(180, 260, 140, 45);
        viewExpenseButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));

        addIncomeButton.addActionListener(new InputData(this));

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == loadButton) {
            JOptionPane.showMessageDialog(null, "Loading Complete!");
            plannerScreen();
        }

        if (e.getSource() == resetButton) {
            JOptionPane.showMessageDialog(null, "Saved data erased.");
            plannerScreen();
        }
    }

    public class InputData implements ActionListener {
        JFrame parent;

        public InputData(JFrame parent) {
            this.parent = parent;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Clicked");
            JDialog dialog = new JDialog(parent);
            JPanel inputSpace = new JPanel();
            inputSpace.setLayout(new FlowLayout());
//            inputSpace.setBounds(0, 300, 500, 200);
            var incomeLabel = new JLabel("How much is your income?");
            inputIncome = new JTextField("How much is your income?", 20);
            inputSpace.add(incomeLabel);
            inputSpace.add(inputIncome);
            inputSpace.add(new JButton("OK"));
            inputSpace.add(new JButton("Cancel"));
//            openPanel.add(inputSpace);
//            openFrame.removeAll();
//            openFrame.setContentPane(inputSpace);
//            openFrame.add(inputSpace);
//            parent.setContentPane(inputSpace);
            dialog.add(inputSpace);
            System.out.println("Removing all");
            dialog.setSize(500, 300);
            dialog.setVisible(true);
        }
    }

    public static void main(String... $) {
        var of = new OpenFrame();
    }
}

Budget Planner

Ответ принят как подходящий

Основные рекомендации:

  1. Избегайте использования нулевого макета и использования setBounds(...) для размещения компонентов, так как это делает очень негибкие графические интерфейсы, которые, хотя они могут хорошо выглядеть на одной платформе, выглядят ужасно на большинстве других платформ или разрешений экрана, и их очень сложно обновлять и поддерживать.
  2. Лучший способ поменять местами или показать/скрыть компоненты с помощью Swing — использовать CardLayout. Пожалуйста, ознакомьтесь с Учебник CardLayout.
  3. Разные представления должны быть представлены разными панелями JPanel.
  4. Различные представления должны иметь свой собственный класс
  5. Разделите данные и логику вашей программы (модель программы) из представления на отдельные классы, по крайней мере, на классы модели и представления или, если хотите, шаблон модель-представление-контроллер (MVC).

Например:

в приведенном ниже примере кода у меня есть модель и некоторый управляющий код в классе SwapModel:

import java.beans.*;
import java.util.*;
import javax.swing.event.*;

public class SwapModel {
    public static String INCOME = "income";
    private PropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
    private SwapGuiMainPanel mainGui;
    private Deque<String> cardStack = new LinkedList<>();
    private double income = 0;

    public SwapModel(SwapGuiMainPanel mainGui) {
        this.mainGui = mainGui;
    }

    // when income is changed, update it and notify listeners.
    public void addIncome(double value) {
        double oldValue = this.income;
        double newValue = this.income + value;
        this.income = newValue;
        pcSupport.firePropertyChange(INCOME, oldValue, newValue);
    }
    
    public double getIncome() {
        return income;
    }

    // go to the next CardLayout view by calling show and pushing the view's constraint String onto the cardStack
    public void swap(String name) {
        mainGui.getCardLayout().show(mainGui.getHolderPanel(), name);
        cardStack.push(name);
    }
    
    // go to the previous CardLayout view by popping the cardStack.
    public String popCardStack() {
        String name = null;
        if (cardStack.size() > 1) {
            cardStack.pop();
            name = cardStack.peek();
            mainGui.getCardLayout().show(mainGui.getHolderPanel(), name);           
        }
        return name;
    }
    
    public void addPropertyChangeListener(String propName, PropertyChangeListener propListener) {
        pcSupport.addPropertyChangeListener(propName, propListener);
    }
}

Он содержит значение дохода и уведомляет любые классы, которые хотят зарегистрировать слушателей, об изменениях значения дохода, используя поддержку изменения свойств JavaBeans. Это также помогает контролировать, какое представление отображается в какое время, управляя объектом CardLayout.

Часть просмотра этого примера программных кодов для нескольких панелей JPanel, в том числе:

  • Панель приветствия, которая отображает текст приветствия и имеет кнопки, которые помогают пользователю загружать другие панели JPanel. В настоящее время он позволяет отображать только одну JPanel, LoadPanel.
  • LoadPanel, который представляет собой меню, позволяющее пользователю добавлять или просматривать расходы или доходы. JPanel включает в себя несколько менеджеров компоновки, включая BoxLayout, GridLayout и GridBagLayout, чтобы обеспечить гибкий графический интерфейс. Метод buttonFactory позволяет создавать JButton большего размера с однородным внешним видом.
  • AddIncomePanel, который позволяет пользователю добавлять дополнительный доход к модели программы.
  • Панель ViewIncomePanel, показывающая пользователю текущий доход. Этот класс будет прослушивать изменения в свойстве дохода модели с помощью PropertyChangeListener.
  • Наконец, SwapGuiMainPanel для хранения CardLayout и держателяPanel, который использует этот макет, и чтобы собрать все вместе:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.*;
import java.beans.*;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.border.Border;

@SuppressWarnings("serial")
public class SwapGuiMainPanel extends JPanel {
    private CardLayout cardLayout = new CardLayout();
    private JPanel holderPanel = new JPanel(cardLayout);
    private SwapModel swapModel = new SwapModel(this);
    private WelcomePanel welcomePanel = new WelcomePanel(swapModel);
    private LoadPanel loadPanel = new LoadPanel(swapModel);
    private AddIncomePanel addIncomePanel = new AddIncomePanel(swapModel);
    private ViewIncomePanel viewIncomePanel = new ViewIncomePanel(swapModel);
    
    public SwapGuiMainPanel() {
        holderPanel.add(welcomePanel, WelcomePanel.NAME);
        holderPanel.add(loadPanel, LoadPanel.NAME);
        holderPanel.add(addIncomePanel, AddIncomePanel.NAME);
        holderPanel.add(viewIncomePanel, ViewIncomePanel.NAME);
        
        swapModel.addPropertyChangeListener(SwapModel.INCOME, new IncomeListener());
        
        int gap = 10;
        setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        setLayout(new BorderLayout());
        add(holderPanel);
    }
    
    private class IncomeListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Double income = (Double) evt.getNewValue();
            if (income != null) {
                viewIncomePanel.setIncomeValue(income);
            }
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SwapGuiMainPanel mainPanel = new SwapGuiMainPanel();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

    public void swap(String constraint) {
        cardLayout.show(holderPanel, constraint);
    }
    
    public CardLayout getCardLayout() {
        return cardLayout;
    }
    
    public JPanel getHolderPanel() {
        return holderPanel;
    }
    
}
@SuppressWarnings("serial")
class WelcomePanel extends JPanel {
    public static final String NAME = "welcome panel";
    private static final String WELCOME_TEXT = "Hello and Welcome! Choose an Option Below:";
    private SwapModel model;

    public WelcomePanel(SwapModel model) {
        this.model = model;
        
        int gap = 20;
        JPanel buttonPanel = new JPanel(new GridLayout(0, 1, gap, gap));
        JButton loadButton = new JButton("Load Data");
        loadButton.addActionListener(e -> loadData());
        JButton resetButton = new JButton("Reset Data");
        Font btnFont = loadButton.getFont().deriveFont(Font.BOLD, 16f);
        loadButton.setFont(btnFont);
        resetButton.setFont(btnFont);       
        buttonPanel.add(loadButton);
        buttonPanel.add(resetButton);
        
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(gap, gap, gap, gap);
        add(new JLabel(WELCOME_TEXT), gbc);     
        gbc.gridy++;
        add(buttonPanel, gbc);
    }
    
    private void loadData() {
        model.swap(LoadPanel.NAME);
    }
    
}
@SuppressWarnings("serial")
class LoadPanel extends JPanel {
    public static final String NAME = "load panel";
    private SwapModel model;

    public LoadPanel(SwapModel model) {
        this.model = model;
        
        JLabel title = new JLabel("Welcome to Budget Planner App");
        title.setHorizontalAlignment(SwingConstants.CENTER);
        title.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        title.setFont(title.getFont().deriveFont(Font.BOLD, 16f));
        
        JLabel subTitle = new JLabel("What would you like to do?");
        subTitle.setHorizontalAlignment(SwingConstants.CENTER);
        subTitle.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        subTitle.setFont(subTitle.getFont().deriveFont(Font.ITALIC));
        
        JPanel titlePanel = new JPanel();
        titlePanel.setLayout(new BoxLayout(titlePanel, BoxLayout.PAGE_AXIS));
        titlePanel.add(title);
        titlePanel.add(subTitle);
        titlePanel.add(Box.createVerticalStrut(30));
        
        JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
        buttonPanel.add(buttonFactory("Add Income", e -> addIncome()));
        buttonPanel.add(buttonFactory("Add Expense", null));
        buttonPanel.add(buttonFactory("View Income", e -> viewIncome()));
        buttonPanel.add(buttonFactory("View Expense", null));
        
        JPanel wrapperPanel = new JPanel(new GridBagLayout());
        wrapperPanel.add(buttonPanel);
                
        int gap = 10;
        setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        setLayout(new BorderLayout());
        add(titlePanel, BorderLayout.PAGE_START);
        add(wrapperPanel);
    }
    
    private void addIncome() {
        model.swap(AddIncomePanel.NAME);
    }
    
    private void viewIncome() {
        model.swap(ViewIncomePanel.NAME);
    }
    
    private JButton buttonFactory(String text, ActionListener listener) {
        JButton button = new JButton(text);
        button.addActionListener(listener);
        button.setFont(button.getFont().deriveFont(Font.BOLD, 16f));
        Border originalBorder = button.getBorder();
        int gap = 10;
        Border innerBorder = BorderFactory.createEmptyBorder(gap, gap, gap, gap);
        button.setBorder(BorderFactory.createCompoundBorder(originalBorder, innerBorder));
        return button;
    }
    
}
@SuppressWarnings("serial")
class AddIncomePanel extends JPanel {
    public static final String NAME = "add income panel";
    private SwapModel swapModel;
    private JTextField incomeField = new JTextField(20);
    private JButton submitButton = new JButton("Submit");
    private JButton cancelButton = new JButton("Cancel");

    public AddIncomePanel(SwapModel swapModel) {
        this.swapModel = swapModel;
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Enter Income:"));
        topPanel.add(incomeField);
        
        submitButton.addActionListener(e -> submitData());
        cancelButton.addActionListener(e -> cancel());
        JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        buttonPanel.add(submitButton);
        buttonPanel.add(cancelButton);
        
        JPanel innerPanel = new JPanel();
        innerPanel.setLayout(new GridLayout(0, 1, 5, 5));
        innerPanel.add(topPanel);
        innerPanel.add(buttonPanel);
        
        JButton backButton = new JButton("Back");
        backButton.addActionListener(e -> back());
        JPanel bottomButtonPanel = new JPanel();
        bottomButtonPanel.add(backButton);
        
        setLayout(new BorderLayout());
        add(innerPanel, BorderLayout.PAGE_START);
        add(bottomButtonPanel, BorderLayout.PAGE_END);
    }

    private void back() {
        swapModel.popCardStack();
    }

    private void submitData() {
        String text = incomeField.getText();
        try {
            double value = Double.parseDouble(text);
            swapModel.addIncome(value);
            back();
        } catch (NumberFormatException e) {
            // TODO: show error message
        }
    }
    
    private void cancel() {
        back();
    }
    
}
@SuppressWarnings("serial")
class ViewIncomePanel extends JPanel {
    public static final String NAME = "view income panel";
    private SwapModel swapModel;
    private JLabel incomeValue = new JLabel();
    private NumberFormat format = NumberFormat.getCurrencyInstance();

    public ViewIncomePanel(SwapModel swapModel) {
        this.swapModel = swapModel;
        
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Income: "));
        topPanel.add(incomeValue);

        JButton backButton = new JButton("Back");
        backButton.addActionListener(e -> back());
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(backButton);
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(buttonPanel, BorderLayout.PAGE_END);
    }
    
    public void setIncomeValue(double income) {
        incomeValue.setText(format.format(income));
    }
    
    private void back() {
        swapModel.popCardStack();
    }
}

Другие вопросы по теме