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 actionlister。單擊 addIncomeButton 后,它不會執行任何操作。我該如何解決這個問題?;-;
我的目標是,一旦單擊按鈕,將出現一個 JTextField 將被添加到同一個面板上。
任何幫助將不勝感激!非常感謝!
uj5u.com熱心網友回復:
基本建議:
- 避免使用 null 布局和
setBounds(...)用于組件放置,因為這會導致非常不靈活的 GUI,雖然它們在一個平臺上看起來不錯,但在大多數其他平臺或螢屏解析度上看起來很糟糕,并且很難更新和維護。 - 使用 Swing 交換或顯示/隱藏組件的最佳方法是使用 CardLayout。請查看
在下面的示例代碼中,我在 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); } }This holds an income value, and notifies any classes that want to register listeners about changes in the income value, by use of JavaBeans property change support. It also helps control which view is shown at what time, by controlling a CardLayout object.
The view portion of this example program codes for several JPanels, including:
- A WelcomePanel that displays welcome text and has buttons that helps the user load other JPanels. It currently only allows display of one JPanel, the LoadPanel.
- A LoadPanel that is a menut to allow the user to add or view expenses or income. The JPanel nests several layout managers, including a BoxLayout, GridLayout, and GridBagLayout, to allow for a flexible GUI. A buttonFactory method allows for creation of larger JButtons with a uniform appearance.
- 一個 AddIncomePanel,允許用戶向程式模型添加額外收入。
- 向用戶顯示當前收入的 ViewIncomePanel。此類將使用 PropertyChangeListener 偵聽模型的收入屬性的更改。
- 最后是一個 SwapGuiMainPanel 來保存 CardLayout 和使用此布局的 holderPanel,并將所有內容放在一起:
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(); } }uj5u.com熱心網友回復:
該解決方案并不完美,您可以根據需要改進代碼。似乎按鈕正在回應點擊以驗證我是否在方法中添加了
System.out.println("Clicked")陳述句。actionPerformedpackage 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(); } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/445632.html
