2

I've been trying to follow an MVC pattern on my code and I was creating a system in which I have a JTabbedPane with Jbuttons inside the panel on my View, The content's info in the Model, and a the actionlisteners on my Controller. The problem I've been having is that I've been trying to put an actionlistener on my Jbuttons but it seems to be only working on my last tab (let's say i have 4 tabs, only the 4th tab with jbuttons work) Oh, and I should say that I've been using Jbutton arrays Note that I've been only using only one Jbutton array to place on my panel. how should this work? I need a sample code for reference.

here is my sample View class

import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class View extends JFrame
{
    private static final int HEIGHT = 700;
    private static final int WIDTH = 700;

    private JTabbedPane tabPane = new JTabbedPane();
    private JComponent tab1 = makePanel("1");
    private JComponent tab2 = makePanel("2");
    private JComponent tab3 = makePanel("3");
    private JComponent tab4 = makePanel("4");

    private JButton[] button;
    private String[] buttonlabel;

    public View()
    {
        setLayout(null);
        setSize(WIDTH, HEIGHT);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        tabPane.addTab("firstTab", tab1);
        tabPane.addTab("secondTab", tab2);
        tabPane.addTab("thirdTab", tab3);
        tabPane.addTab("fourtTab", tab4);

        add(tabPane);

        tabPane.setBounds(20, 20, 400, 400);
    }

    protected JComponent makePanel(String input)
    {
        JPanel panel = new JPanel(false);
        panel.setLayout(null);

        if(input == "1")
        {
            button = new JButton[4];
            buttonlabel = new String[]
            {
                "1button1",
                "2button1",
                "3button1",
                "4button1"
            };

            for(int x = 0; x < 4; x++)
            {
                button[x] = new JButton(buttonlabel[x]);
                panel.add(button[x]);
            }

            int yCord = 20;
            for(int x = 0; x < 4; x += 2)
            {
                int xCord = 20;
                for(int y = x; y < (x + 2); y++)
                {
                    button[y].setBounds(xCord, yCord, 100, 100);
                    xCord += 120;
                }
                yCord += 120;
            }
        }
        else if(input == "2")
        {
            button = new JButton[4];
            buttonlabel = new String[]
            {
                "1button2",
                "2button2",
                "3button2",
                "4button2"
            };

            for(int x = 0; x < 4; x++)
            {
                button[x] = new JButton(buttonlabel[x]);
                panel.add(button[x]);
            }

            int yCord = 20;
            for(int x = 0; x < 4; x += 2)
            {
                int xCord = 20;
                for(int y = x; y < (x + 2) && y < 5; y++)
                {
                    button[y].setBounds(xCord, yCord, 100, 100);
                    xCord += 120;
                }
                yCord += 120;
            }
        }
        else if(input == "3")
        {
            button = new JButton[4];
            buttonlabel = new String[]
            {
                "1button3",
                "2button3",
                "3button3",
                "4button3"
            };

            for(int x = 0; x < 4; x++)
            {
                button[x] = new JButton(buttonlabel[x]);
                panel.add(button[x]);
            }

            int yCord = 20;
            for(int x = 0; x < 4; x += 2)
            {
                int xCord = 20;
                for(int y = x; y < (x + 2) && y < 5; y++)
                {
                    button[y].setBounds(xCord, yCord, 100, 100);
                    xCord += 120;
                }
                yCord += 120;
            }
        }
        else if(input == "4")
        {
            button = new JButton[4];
            buttonlabel = new String[]
            {
                "1button4",
                "2button4",
                "3button4",
                "4button4"
            };

            for(int x = 0; x < 4; x++)
            {
                button[x] = new JButton(buttonlabel[x]);
                panel.add(button[x]);
            }

            int yCord = 20;
            for(int x = 0; x < 4; x += 2)
            {
                int xCord = 20;
                for(int y = x; y < (x + 2) && y < 5; y++)
                {
                    button[y].setBounds(xCord, yCord, 100, 100);
                    xCord += 120;
                }
                yCord += 120;
            }
        }
        return panel;
    }

    public void buttonListener(ActionListener buttonL)
    {
        for(int x = 0; x < button.length; x++)
        {
            button[x].addActionListener(buttonL);
        }
    }

    public static void main(String args[])
    {
        View view = new View();

        Controller control = new Controller(view);
        view.setVisible(true);
    }
}

here is my sample Controller class

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Controller 
{
    View view = new View();

    public Controller(View view)
    {
        this.view = view;

        this.view.buttonListener(new ButtonListener());
    }

    private class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ae)
        {
            System.out.println("BUTTON WORKS!");
        }
    }
}
  • 1
    Your question will be difficult if not impossible to answer as written, because it is essentially: "please guess why the code that I'm not showing you is not working". Please improve this by creating a new small program that compiles, runs, is small enough to post here with your question as code-formatted text, and that demonstrates your problem, a [mcve]. – Hovercraft Full Of Eels Mar 05 '17 at 14:00
  • I apologize for not posting a code earlier as I was creating a sample class. I have edited my question and posted a sample code. – Chris Tumanda Mar 05 '17 at 14:36
  • Thank you for posting code, and I will look at it all momentarily, but one problem immediately apparent is here: `else if(input == "2")`. Don't compare Strings using `==` or `!=`. Use the `equals(...)` or the `equalsIgnoreCase(...)` method instead. Understand that `==` checks if the two *object references* are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here. – Hovercraft Full Of Eels Mar 05 '17 at 14:41

1 Answers1

1

You're re-filling the button array with each creation of a JTabbedPane, and in doing so, the references for all the previous buttons have been discarded from the array and only the last remains.

I suggest that you create a class for the panel of the JTabbedPane and allow it to be injected from the control. Keep it simple.

One example:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class View2 extends JPanel {
    private static final long serialVersionUID = 1L;
    private static final String[] TAB_NAMES = {"First Tab", "Second Tab", "Third Tab", "Fourth Tab"};
    private static final int PREF_W = 400;
    private static final int PREF_H = 150;
    private JTabbedPane tabbedPane = new JTabbedPane();
    private List<MyTab> myTabs = new ArrayList<>();
    private Controller2 controller2;

    public View2() {
        setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
        setLayout(new BorderLayout());
        add(tabbedPane, BorderLayout.CENTER);

        for (int i = 0; i < TAB_NAMES.length; i++) {
            int tabNumber = i + 1;
            MyTab myTab = new MyTab(TAB_NAMES[i], tabNumber);
            tabbedPane.add(myTab.getTabName(), myTab);
            myTabs.add(myTab);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension superSz = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return superSz;
        }
        int prefW = Math.max(superSz.width, PREF_W);
        int prefH = Math.max(superSz.height, PREF_H);
        return new Dimension(prefW, prefH);
    }

    public Controller2 getController2() {
        return controller2;
    }

    public void setController2(Controller2 controller2) {
        this.controller2 = controller2;
        for (MyTab myTab : myTabs) {
            myTab.setController2(controller2);
        }
    }

    private static void createAndShowGui() {
        View2 viewPanel = new View2();
        new Controller2(viewPanel);

        JFrame frame = new JFrame("View2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(viewPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

}

class MyTab extends JPanel {
    private static final long serialVersionUID = 1L;
    private static final int BUTTON_COUNT = 4;
    private String tabName;
    private int tabNumber;
    private List<JButton> buttons = new ArrayList<>();
    private Controller2 controller2;

    public MyTab(String tabName, int tabNumber) {
        this.tabName = tabName;
        this.tabNumber = tabNumber;

        setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
        setLayout(new GridLayout(2, 2, 4, 4));
        for (int i = 0; i < BUTTON_COUNT; i++) {
            String title = (i + 1) + " Button " + tabNumber;
            JButton button = new JButton(title);
            button.addActionListener(e -> {
                if (controller2 != null) {
                    controller2.buttonAction(e);
                }
            });
            add(button);
            buttons.add(button);
        }
    }

    public void setController2(Controller2 controller2) {
        this.controller2 = controller2;
    }

    public String getTabName() {
        return tabName;
    }

    public int getTabNumber() {
        return tabNumber;
    }

    public List<JButton> getButtons() {
        return buttons;
    }

}

class Controller2 {

    private View2 view;

    public Controller2(View2 view) {
        this.view = view;
        view.setController2(this);
    }

    public void buttonAction(ActionEvent e) {
        System.out.println("Button pressed! " + e.getActionCommand());
    }

    public View2 getView() {
        return view;
    }

}

This example uses a simple anonymous inner class ActionListener in the view to call a controller method.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I actually thought that it gets discarded as you said but, I am not familiar on how to inject it to the control. I have only just started on MVC patterns so I am not too familiar on how to code it. – Chris Tumanda Mar 05 '17 at 15:03
  • @ChrisTumanda: there are many ways to code it. Perhaps "injection" is a bad term, although true "dependency injection" a la Guice or Spring is probably the best way to hook up MVC, although that is over-kill for your situation. – Hovercraft Full Of Eels Mar 05 '17 at 15:19
  • Thank you! You helped me a ton on giving a reference, and also thank you for the advice on comparing Strings. – Chris Tumanda Mar 05 '17 at 15:43