Approach A: Each JButton's has its own class. In its constructor you put:

    this.addActionListener(this);
and later in that same class:
    public void actionPerformed(ActionEvent event) {
        ...
    }

In this approach the JButton will probably need another object to help it do its work in actionPerformed.

Approach B: Each JButton asks the ControlsPanel to respond to its button press. So the ControlsPanel would have code like this:
    JButton button1 = ...;
    button1.addActionListener(this);

    JButton button2 = ...;
    button2.addActionListener(this);

    ...

    public void actionPerformed(ActionEvent event) {
        if (((JButton) (event.getSource()).getText().equals("Add Car") {
            ...
        } else {
            ...
    }
Approach C: each JButton has an anonymous class that responds to its button press. So the ControlsPanel would have code like this:
    JButton button1 = ...;
    button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            ControlsPanel.this.constructCar();
        }
    });
and similarly for the other buttons, with methods in the ControlsPanel for constructing Cars, etc.