Search code examples
javaswinglayout-managergridbaglayoutjtoolbar

How to set a JToolBar to the size of the frame


I am making a user interface for a music tracker I'm working on and I have some of the basics set up. I am new to user interfaces so I haven't yet got figured out all the stuff about swing graphics.

My biggest problem now is that i can't get the toolbar sized properly so it doesn't even appear. How do I set it's size to always be the width of the JFrame?

MainInterface gets initialised in a main class.

package userInterface;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.JTree;

/**
 *
 * @author Edward Jenkins
 */
public class MainInterface extends JFrame {
    
    // constants
    public static final int DEFAULT_WINDOW_WIDTH = 1080;
    public static final int DEFAULT_WINDOW_HEIGHT = 720;    
    
    // instance variables
    int screenWidth;
    int screenHeight;
    JMenuBar menuBar;
    JMenu fileMenu, editMenu, toolsMenu;
    GridBagLayout gbl;
    GridBagConstraints gbc;
    JTree tree;
    JTable trackerTable;
    JScrollPane tableScroll;
    Container toolBarContainer;
    JToolBar toolBar;
    JButton saveButton, loadButton, pauseButton, stopButton, backPatternButton, 
            forthPatternButton, playButton, recordButton, repeatSongButton;
    JTabbedPane tabbedPane;
    
    int numberOfChannels;
    
    // constructor
    public MainInterface() {
        getScreenSize();
        this.setTitle("Synth Tracker 1.0");
        this.setLayout(gbl);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds((int)(screenWidth / 2) - (int)(DEFAULT_WINDOW_WIDTH / 2),
                (int)(screenHeight / 2) - (int)(DEFAULT_WINDOW_HEIGHT / 2),
                DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
        addComponents();
        this.setVisible(true);
    }
    
    // get screen size
    private void getScreenSize() {
        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
                .getDefaultScreenDevice();
        screenWidth = gd.getDisplayMode().getWidth();
        screenHeight = gd.getDisplayMode().getHeight();
    }
    
    // set all components
    private void addComponents() {
        
        //Menu bar and its options
        menuBar = new JMenuBar();
        fileMenu = new JMenu("File");
        editMenu = new JMenu("Edit");
        toolsMenu = new JMenu("Tools");
        
        // add menues to menuBar
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(toolsMenu);
        this.setJMenuBar(menuBar);
        
        // set the grid and constraint
        gbl = new GridBagLayout();
        gbc = new GridBagConstraints();
        
        // set the row 1 of the grid
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        
        // set toolbar container
        toolBarContainer = this.getContentPane();
        
        // set the toolbar
        toolBar = new JToolBar();
        toolBar.setRollover(true);
        toolBar.setFloatable(false);
        
        // set the buttons in the toolbar
        saveButton = new JButton();
        saveButton.setIcon(
                new ImageIcon("src/userInterface/icons/save_icon.png"));
        saveButton.setToolTipText("Save"); 
        
        toolBar.add(saveButton);

        add(toolBar, gbc);
        
    }
    
    public void setNumberOfChannels(int numberOfChannels) {
        this.numberOfChannels = numberOfChannels;
    }
}

Solution

  • Instead of a GridBagLayout, use simpler layouts and nest them by using auxiliary JPanels. To continue using GridBagLayout, especially as a novice, I recommend using a graphical interface to play around with the constraints to get them just right (NetBeans has a nice GridBagLayout graphical editor & code generator).

    I would recommend using a BorderLayout, and placing the tool bar at the top (it will automatically stretch to full width):

    // within addComponents
    setLayout(new BorderLayout());
    getContentPane().add(toolBar, BorderLayout.NORTH);
    

    In your case, you appear to have forgotten to set the layout of the JFrame to a GridBagLayout - but even so, in my experience, you should prefer nesting JPanels to adding all interface elements into the same component. Using individual JPanels allows for easier layout, testing, and provides flexibility if you ever want to change the general layout while maintaining existing blocks consistent.