import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; /** a GUI application playing with containers using different layout managers @author Sharon Tuttle @version 2021-10-05 */ public class LayoutTrio1 { /** creates a simple frame with several panels using a variety of layout managers @param args not used here */ public static void main(String[] args) { EventQueue.invokeLater( () -> { LayoutTrio1Frame mainFrame = new LayoutTrio1Frame(); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setVisible(true); } ); } } /** A frame with a panel that includes buttons! */ class LayoutTrio1Frame extends JFrame { // data fields private static final int DEFAULT_WIDTH = 600; private static final int DEFAULT_HEIGHT = 450; /** construct a LayoutTrio1Frame instance */ public LayoutTrio1Frame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); setTitle("Multiple Managers"); LayoutTrio1Panel mainPanel = new LayoutTrio1Panel(); add(mainPanel); } } /** A panel containing subpanels, using several layout managers */ class LayoutTrio1Panel extends JPanel { // data fields! private static final Font BIG_FONT = new Font("SanSerif", Font.PLAIN, 30); private int runningTotal; private JTextField resultsField; /** constructs a LayoutTrio1Panel instance */ public LayoutTrio1Panel() { runningTotal = 0; setLayout(new BorderLayout()); // I decide to have a label on a subpanel in the north // (this subpanel is using the JPanel layout manager // default, FlowLayout) JPanel welcomePanel = new JPanel(); JLabel welcome = new JLabel("Three-layouts-at-once Demo"); welcome.setFont(BIG_FONT); welcome.setForeground(Color.BLUE); welcomePanel.add(welcome); add(welcomePanel, BorderLayout.NORTH); // setting up a subpanel in the center that is itself using // BorderLayout! JPanel centerPanel = new JPanel(); centerPanel.setLayout(new BorderLayout()); // set up a subpanel in the *center* of *centerPanel* // with an array of numeric buttons JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new GridLayout(4, 3)); JButton[] buttonArray = new JButton[12]; for (int i=0; i < buttonArray.length; i++) { // after class, decided this might be a less-klugey // way to convert the (i+1) int to a String // for the new button's text buttonArray[i] = new JButton( Integer.toString(i+1) ); buttonArray[i].setFont(BIG_FONT); // example of a new Color instance -- looked up the // RGB value for this on the Internet... 8-) buttonArray[i].setForeground(new Color(0, 102, 0)); buttonArray[i].addActionListener(new NumButtonAction()); buttonPanel.add(buttonArray[i]); } centerPanel.add(buttonPanel, BorderLayout.CENTER); // set up a subpanel in the *south* of *centerPanel* to hold the // results-related components // (this subpanel is using the JPanel layout manager // default, FlowLayout) JPanel resultsPanel = new JPanel(); JLabel resultsLabel = new JLabel("Sum so far: "); resultsLabel.setFont(BIG_FONT); resultsPanel.add(resultsLabel); resultsField = new JTextField("0", 5); resultsField.setFont(BIG_FONT); resultsField.setEditable(false); resultsPanel.add(resultsField); centerPanel.add(resultsPanel, BorderLayout.SOUTH); add(centerPanel, BorderLayout.CENTER); // in the new LayoutTrio1Panel's south region, put a subpanel // with a Clear button // (this subpanel is using the JPanel layout manager // default, FlowLayout) JPanel clearPanel = new JPanel(); JButton clearButton = new JButton("Clear"); clearButton.setFont(BIG_FONT); clearButton.setForeground(Color.RED); clearButton.addActionListener(new ClearButtonAction()); clearPanel.add(clearButton); add(clearPanel, BorderLayout.SOUTH); } // end LayoutTrio1Panel constructor /** An action listener that updates sum so far, adding in the amount on the button pushed */ private class NumButtonAction implements ActionListener { // default constructor will suffice, in this case /** adds the source's label value to the running total @param event a click of a number button */ public void actionPerformed(ActionEvent event) { // a little kluge/shortcut: getActionCommand returns the // corresponding "command" for an action event. For // a button action, the command is the text associated // with that button! // SINCE the buttons are labeled with digits, I can thus // parse this command as an integer to grab this button's // value-to-add... // CONSIDER: why didn't I put this in a try-block? int currButtonVal = Integer.parseInt( event.getActionCommand() ); runningTotal += currButtonVal; // (changed after class -- is this a less-klugey way // to get the String version of int runningTotal? 8-) ) resultsField.setText( Integer.toString(runningTotal) ); } } /** An action listener that clears the sum so far, resetting it to 0 */ private class ClearButtonAction implements ActionListener { // default constructor will suffice, in this case /** clears out the running total @param event a click of the clear button */ public void actionPerformed(ActionEvent event) { runningTotal = 0; resultsField.setText("0"); } } }