methuselah
methuselah

Reputation: 13206

JPanel layout - adding text box and rearranging components

I am having some issues with my Swing GUI.

It currently looks like this:

enter image description here

But I would like to move a couple things around.

  1. Firstly I want the buttons underneath the keyboard
  2. I want to add a text field on top of the keyboard with the submit button on the right hand side.

How can I accomplish this? I've tried to create a GridLayout and slot things by row,column coordinate but it doesn't seem to work.

  private class Display extends JPanel {
    Display() {
      setPreferredSize(new Dimension(620, 420));
      setBackground(new Color(250, 230, 180));
      setFont(new Font("Serif", Font.BOLD, 20));
    }

    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      ((Graphics2D) g).setStroke(new BasicStroke(3));
      if (message != null) {
        g.setColor(Color.RED);
        g.drawString(message, 30, 40);
        g.drawString("00:00", 30, 410);
      }
    }
  }

  private void createWindow() {
    setJMenuBar(menuBarCreator());

    // The ActionListener that will respond to button clicks.
    ButtonHandler buttonHandler = new ButtonHandler();

    // Create the subpanels and add them to the main panel.
    display = new Display();
    setLayout(new BorderLayout(3, 3));
    add(display, BorderLayout.CENTER);
    JPanel bottom = new JPanel();
    bottom.setLayout(new GridLayout(1,1));
    add(bottom, BorderLayout.NORTH);

    // Add keyboard
    JPanel keyboard = new JPanel();
    JPanel keyboardHolder = new JPanel();
    keyboard.setLayout(new GridLayout(2, 13));
    keyboardHolder.setLayout(new GridLayout(1, 2));
    for (char alphabet = 'a'; alphabet <= 'z'; alphabet++) {
      JButton button = new JButton(String.valueOf(alphabet));
      button.addActionListener(buttonHandler);
      keyboard.add(button);
      alphabetButtons.add(button);
    }
    keyboardHolder.add(keyboard, 0,0);
    add(keyboardHolder, BorderLayout.SOUTH);

    // Create three buttons, register the ActionListener to respond to clicks on the
    // buttons, and add them to the bottom panel.

    JButton submitButton = new JButton("Submit");
    submitButton.addActionListener(buttonHandler);
    keyboard.add(submitButton);

    JButton startButton = new JButton(GuiText.START.toString());
    startButton.addActionListener(buttonHandler);
    bottom.add(startButton);

    JButton nextButton = new JButton(GuiText.NEXT.toString());
    nextButton.addActionListener(buttonHandler);
    bottom.add(nextButton);

    JButton skipButton = new JButton(GuiText.SKIP.toString());
    skipButton.addActionListener(buttonHandler);
    bottom.add(skipButton);

    JButton quit = new JButton(GuiText.QUIT.toString());
    quit.addActionListener(buttonHandler);
    bottom.add(quit);

    setBackground(new Color(100, 0, 0));

    nextButton.setEnabled(false);
    skipButton.setEnabled(false);
  }

Upvotes: 0

Views: 1502

Answers (1)

Abra
Abra

Reputation: 20914

Below is a concrete example of what camickr wrote in his comment to the original question. Note that this is not the only possibility. There are many layout managers. I recommend visiting Laying Out Components Within a Container

The purpose of the code is only to show you how to achieve your desired layout.

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class GuesGame implements Runnable {
    private JFrame frame;

    public void run() {
        showGui();
    }

    private JPanel createBottomPanel() {
        JPanel bottomPanel = new JPanel(new GridLayout(3, 1));
        bottomPanel.add(createSubmitPanel());
        bottomPanel.add(createKeyboardPanel());
        bottomPanel.add(createButtonsPanel());
        return bottomPanel;
    }

    private JPanel createButtonsPanel() {
        JPanel buttonsPanel = new JPanel();
        JButton startButton = new JButton("Start");
        buttonsPanel.add(startButton);
        JButton nextButton = new JButton("Next");
        buttonsPanel.add(nextButton);
        JButton skipButton = new JButton("Skip");
        buttonsPanel.add(skipButton);
        JButton quitButton = new JButton("Quit");
        buttonsPanel.add(quitButton);
        return buttonsPanel;
    }

    private JPanel createKeyboardPanel() {
        JPanel keyboardPanel = new JPanel(new GridLayout(2, 13));
        for (char c = 'a'; c <= 'z'; c++) {
            JButton button = new JButton(String.valueOf(c));
            keyboardPanel.add(button);
        }
        return keyboardPanel;
    }

    private JPanel createSubmitPanel() {
        JPanel submitPanel = new JPanel();
        JTextField txtFld = new JTextField(20);
        submitPanel.add(txtFld);
        JButton submitButton = new JButton("Submit");
        submitPanel.add(submitButton);
        return submitPanel;
    }

    private void showGui() {
        frame = new JFrame("Guess Game");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(new Display(), BorderLayout.CENTER);
        frame.add(createBottomPanel(), BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new GuesGame());
    }
}

class Display extends JPanel {
    private String message;

    Display() {
        message = "Starting game";
        setPreferredSize(new Dimension(620, 420));
        setBackground(new Color(250, 230, 180));
        setFont(new Font("Serif", Font.BOLD, 20));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        ((Graphics2D) g).setStroke(new BasicStroke(3));
        if (message != null) {
            g.setColor(Color.RED);
            g.drawString(message, 30, 40);
            g.drawString("00:00", 30, 410);
        }
    }
}

You want three "rows" below the Display panel as follows

  1. Text field and "submit" button.
  2. Keyboard
  3. Other buttons.

Hence the "bottom" panel contains three panels laid out one above the other.
The first panel is the text field and "submit" panel.
Underneath that is the "keyboard".
And underneath the keyboard are the other buttons.

Note that the default layout manager for JPanel is java.awt.FlowLayout and this layout manager is suitable for the panel containing the "submit" button and also suitable for the panel containing the other buttons.

Here is a screen capture of the running app.

layout example

Upvotes: 1

Related Questions