Results 1 to 19 of 19
Like Tree1Likes
  • 1 Post By KevinWorkman

Thread: MVC design issue:

  1. #1
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default MVC design issue:

    I am having an issue with the MVC design. I just want to call the controller in main and just send it the a "new model and view class"
    Java Code:
    public class Main {
    	
    	public static void main(String args[]){
    		
    		 SwingUtilities.invokeLater(new Runnable()
    		 {
    		    View view =new View();
    		    Model model = new Model();
    		    public void run()
    		    {
    		       new Controller(view,model);
    		    }
    		    });
    		
    	}
    
    }
    Here is the issue:

    I have a class of buttons that takes in two parameters and they are created in the view class. I am doing this because I am creating a maze and later turning it into a graph to search the shortest distance from one pressed button to another. Think breath first search, depth first search etc.
    Java Code:
    public class Mybuttons extends JButton {
    	
    	private static final long serialVersionUID = 1L;
    	Model model;
    		
    	static public ImageIcon greenIcon = new ImageIcon("green.png");
    	static public ImageIcon redIcon = new ImageIcon("red.png");
    	private ImageIcon yellowIcon = new ImageIcon("yellow.png");
    	private ImageIcon resetIcon = new ImageIcon("null");
    	public int counter;
    	static ImageIcon state;
    	private int xCoordinate;
    	
    	Mybuttons(int x, int y){
    		model = new Model();
    		model.barrier = false;
    		model.startNode=false;
    		model.targetNode=false;
    		model.visted=false;
    		setState(null);
    		setxCoordinate(x);
    	}
    In the view class I am getting an error in the constructor saying:
    [code=java]
    Implicit super constructor Mybuttons() is undefined. Must explicitly invoke another constructor

    Below is some of the view class posted. I create the matrix of buttons in the JPanel matrixPan()

    Java Code:
    public class View extends Mybuttons{
    	
    	private static final long serialVersionUID = 1L;
    	JFrame frame;
    	JPanel matrixPanel, optionsPanel;
    	Mybuttons[][] matrixBtn;
    	JButton enterBtn;
    	JButton resetBtn;
    	int size;
    	
    	View(){
    		
    		frame = new JFrame("See BFS and DFS in action");
    		frame.setSize(900,500);
    		frame.setLayout(new BorderLayout());
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		
    		matrixPanel=matrixPan();
    		optionsPanel=optionsPan();
    		frame.add(matrixPanel,BorderLayout.EAST);
    		frame.add(optionsPanel,BorderLayout.LINE_END);
    		//frame.pack();
    		frame.setResizable(false);
    		frame.setVisible(true);
    	}
    	
    	JPanel matrixPan(){
    		matrixBtn = new Mybuttons[25][25];
    		JPanel panel = new JPanel();
    		panel.setSize(550,550);
    		panel.setLayout(new GridLayout(25,25));
    		//creating a 25x25 matrix of buttons
    		for(int i=0; i<25; i++){
    			for(int j=0;j<25;j++)
    			{	//use myButtons to create the matrix of buttons
    				panel.add(matrixBtn[i][j] = new Mybuttons(i,j));
    				
    				//setting the size of the matrix
    				size++;
    				model.setSize(size);
    			}
    		}
    		panel.setVisible(true);
    
    		return panel;
    	}
    Now in the controller class I pass the model and view.
    Java Code:
    Controller(View view, Model model){
    		
    		this.view = view;
    		this.model = model;
    		Actions action = new Actions();
    		//setting all Image to null
    		resetButtons();
    		button.addActionListener(new Actions());
    		
    		for(int i=0;i<25;i++){
    			for(int j=0;j<25;j++){
    		view.matrixBtn[i][j].addActionListener(action);
    			}
    		}
    		view.enterBtn.addActionListener(action);
    		view.resetBtn.addActionListener(action);
    		
    	}
    I am looking for advice on how I could make the Mybuttons class just visible in view class and not have to create a new instance of the Mybutton class in main.

    This post i cross posted at getting the index of a matrix of buttons

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: MVC design issue:

    First, why are you extending JButton? It seems you could do just as well with an enclosed instance. And I also don't understand why view is extending MyButtons. If you want view to get the instance of an existing MyButtons class, why not just provide a method where it can be retrieved?

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  3. #3
    KevinWorkman's Avatar
    KevinWorkman is offline Crazy Cat Lady
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    4,143
    Rep Power
    14

    Default Re: MVC design issue:

    You might have considered posting a separate thread instead of crossposting, but ah well, at least you linked to the crosspost.

    Your problem can be boiled down to this MCVE:

    Java Code:
    public class Test{
    	public static void main(String... args){
    		Child c = new Child();
    	}
    	
    	static class Parent{
    		public Parent(String s){
    			System.out.println("Constructing parent! " + s);
    		}
    	}
    	
    	static class Child extends Parent{
    		public Child(){
    			System.out.println("Constructing child!");
    		}
    	}
    }
    If you copy that code, you'll see the same error.

    That's because when you run the Child constructor, you **must** call the Parent constructor. And if you don't do that manually, there's an **implicit** call to the no-args constructor from the Parent class, that looks like this:

    Java Code:
    public class Test{
    	public static void main(String... args){
    		Child c = new Child();
    	}
    	
    	static class Parent{
    		public Parent(String s){
    			System.out.println("Constructing parent! " + s);
    		}
    	}
    	
    	static class Child extends Parent{
    		public Child(){
    			super();
    			System.out.println("Constructing child!");
    		}
    	}
    }
    The problem is, your Parent class **doesn't have** a no-args constructor! The only constructor the parent class has must be given a String argument.

    To fix this, you either have to provide a no-args constructor:

    Java Code:
    public class Test{
    	public static void main(String... args){
    		Child c = new Child();
    	}
    	
    	static class Parent{
    		
    		public Parent(){
    			System.out.println("Constructing parent!");
    		}
    		
    		public Parent(String s){
    			System.out.println("Constructing parent! " + s);
    		}
    	}
    	
    	static class Child extends Parent{
    		public Child(){
    			super();
    			System.out.println("Constructing child!");
    		}
    	}
    }
    Or call the constructor manually:

    Java Code:
    public class Test{
    	public static void main(String... args){
    		Child c = new Child();
    	}
    	
    	static class Parent{		
    		public Parent(String s){
    			System.out.println("Constructing parent! " + s);
    		}
    	}
    	
    	static class Child extends Parent{
    		public Child(){
    			super("testing");
    			System.out.println("Constructing child!");
    		}
    	}
    }
    I'm pretty surprised this advice wasn't in the results when you googled the error...
    Norm likes this.
    How to Ask Questions the Smart Way
    Static Void Games - GameDev tutorials, free Java and JavaScript hosting!
    Static Void Games forum - Come say hello!

  4. #4
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    Ok so I suppose I didn't need to extend Mybuttons in the view class but I do need to extend JButton in the Mybuttons class. I need o because I have to call methods like class actionListeners in the controller class. The Mybutton class is treated and button that hold values, i.e. boolean visited, unvisited etc which is why I extended JButton so I could accomplish this.

    Java Code:
    Controller(View view, Model model){
    		
    		this.view = view;
    		this.model = model;
    		Actions action = new Actions();
    		//setting all Image to null
    		resetButtons();
    		button.addActionListener(new Actions());
    		
    		for(int i=0;i<25;i++){
    			for(int j=0;j<25;j++){
    		view.matrixBtn[i][j].addActionListener(action);
    			}
    		}
    		view.enterBtn.addActionListener(action);
    		view.resetBtn.addActionListener(action);
    		
    	}
    This is where this issue started. I had everything working fine until I realized I need to set the buttons position in each button. I did this by passing in the x , y coordinate to its constructor.
    Java Code:
    Mybuttons(int x, int y){
    		node = new JButton();
    		model = new Model();
    		model.barrier = false;
    		model.startNode=false;
    		model.targetNode=false;
    		model.visted=false;
    		setState(null);
    		setxCoordinate(x);
    	}
    Now I am able to get program to run but have lost all functionality and get a run time error:

    Java Code:
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at path.finding.Controller.resetButtons(Controller.java:118)
    	at path.finding.Controller.<init>(Controller.java:28)
    	at path.finding.Main$1.run(Main.java:15)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    	at java.awt.EventQueue.access$200(EventQueue.java:103)
    	at java.awt.EventQueue$3.run(EventQueue.java:694)
    	at java.awt.EventQueue$3.run(EventQueue.java:692)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

  5. #5
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    20,001
    Rep Power
    33

    Default Re: MVC design issue:

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at path.finding.Controller.resetButtons(Controller.ja va:118)
    at path.finding.Controller.<init>(Controller.java:28)
    What variable at line 118 has a null value? When you find it, backtrack in the code to see why.
    If you don't understand my response, don't ignore it, ask a question.

  6. #6
    KevinWorkman's Avatar
    KevinWorkman is offline Crazy Cat Lady
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    4,143
    Rep Power
    14

    Default Re: MVC design issue:

    Quote Originally Posted by jocdrew21 View Post
    I do need to extend JButton in the Mybuttons class. I need o because I have to call methods like class actionListeners in the controller class.
    No, that doesn't sound right. Why does your Mybuttons class need to extend JButton, especially since it looks like your Mybuttons class contains a JButton:

    Quote Originally Posted by jocdrew21 View Post
    Java Code:
    Mybuttons(int x, int y){
    		node = new JButton();
    How to Ask Questions the Smart Way
    Static Void Games - GameDev tutorials, free Java and JavaScript hosting!
    Static Void Games forum - Come say hello!

  7. #7
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    Ahhhhh I understand.... Thank you so much!!!

    I'm pretty surprised this advice wasn't in the results when you googled the error...
    All I got was post from other forums but they did not help.

    Now i have the following error:
    Java Code:
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at path.finding.Controller.resetButtons(Controller.java:115)
    	at path.finding.Controller.<init>(Controller.java:28)
    	at path.finding.Main$1.run(Main.java:15)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    	at java.awt.EventQueue.access$200(EventQueue.java:103)
    	at java.awt.EventQueue$3.run(EventQueue.java:694)
    	at java.awt.EventQueue$3.run(EventQueue.java:692)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
    I wish eclipse would be more clear on where the error is.

    I am creating a new instance of the View and Model class in main
    Java Code:
    public class Main {
    	
    	public static void main(String args[]){
    		
    		 SwingUtilities.invokeLater(new Runnable()
    		 {
    		    View view =new View();
    		    Model model = new Model();
    		    public void run()
    		    {
    		       new Controller(view,model);
    		    }
    		    });
    		
    	}
    
    }
    In the view class I create a new instance of model
    Java Code:
    View(){
    		super();
    		model = new Model();
    		frame = new JFrame("See BFS and DFS in action");
    		frame.setSize(900,500);
    		frame.setLayout(new BorderLayout());
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		matrixPanel=matrixPan();
    		optionsPanel=optionsPan();
    		frame.add(matrixPanel,BorderLayout.EAST);
    		frame.add(optionsPanel,BorderLayout.LINE_END);
    		//frame.pack();
    		frame.setResizable(false);
    		frame.setVisible(true);
    	}
    And create a matrix of Mybuttons correctly so the null pointer cannot be there.
    Java Code:
    JPanel matrixPan(){
    		matrixBtn = new Mybuttons[25][25];
    		JPanel panel = new JPanel();
    		panel.setSize(550,550); 
    		panel.setLayout(new GridLayout(25,25));
    		//creating a 25x25 matrix of buttons
    		for(int i=0; i<25; i++){
    			for(int j=0;j<25;j++)
    			{	//use myButtons to create the matrix of buttons
    				
    				panel.add(matrixBtn[i][j] = new Mybuttons());
    				matrixBtn[i][j].setxCoordinate(i);
    				//setting the size of the matrix
    				size++;
    				model.setSize(size);
    			}
    		}
    		panel.setVisible(true);
    
    		return panel;
    	}
    The controller is aware of the model and view classes and set its action listeners
    Java Code:
    Controller(View view, Model model){
    		
    		this.view = view;
    		this.model = model;
    		Actions action = new Actions();
    		//setting all Image to null
    		resetButtons();
    		button.addActionListener(new Actions());
    		
    		for(int i=0;i<25;i++){
    			for(int j=0;j<25;j++){
    		view.matrixBtn[i][j].addActionListener(action);
    			}
    		}
    		view.enterBtn.addActionListener(action);
    		view.resetBtn.addActionListener(action);
    	}
    The program will run but the buttons have no functionality.... This is very frustrating, I have been wanting to make this program for such a long time and it seem to be kicking my butt sometimes.

  8. #8
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    20,001
    Rep Power
    33

    Default Re: MVC design issue:

    i have the following error:

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at path.finding.Controller.resetButtons(Controller.ja va:115)
    at path.finding.Controller.<init>(Controller.java
    Find the null value at line 115.
    If you don't understand my response, don't ignore it, ask a question.

  9. #9
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    Solved..... Thanks Norm the issue was

    i was doing this:
    Java Code:
    public class Controller {
    	/*The view class holds the GUI and creates a matrix of MyButtons.
    	 *Each of MyButtons will be treated as a node in the Controller Class
    	 *Consider MyButtons as the Model in the MVC design
    	 * */
    	View view;
    	Mybuttons button;
    but needed this
    Java Code:
    public class Controller {
    	/*The view class holds the GUI and creates a matrix of MyButtons.
    	 *Each of MyButtons will be treated as a node in the Controller Class
    	 *Consider MyButtons as the Model in the MVC design
    	 * */
    	View view;
    	Mybuttons button = new Mybuttons();

  10. #10
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: MVC design issue:

    I still don't understand why you are extending JButton in MyButtons. It seems you could do it with composition. But in any event, I recommend you get rid of your magic numbers. If you assign reasonable names to your constants and then reference them in your loops it will be easier to debug and change if necessary. It also adds to the documentation.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  11. #11
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    26

    Default Re: MVC design issue:

    If you're learning MVC then this is backwards.
    Your Controller should know next to nothing about the View.
    It should simply be registering itself as a listener so it can get relevant events and hold an instance (preferably an interface, rather than a concrete class) of the view so it can pass its own events into the GUI.

    So a button on the GUI will be something like:
    Java Code:
    JButton aButton = new JButton("Do Something");
    aButton.addActionListener(new ActionListener() {
        void cantRememberTheNameOfThisOne(event) {
            listener.handleRelevantEvent();
        }
    });
    Where your Controller is the listener having implemented a suitable interface.

    Note you will probably want that handleEvent call to be in a worker to prevent the GUI freezing.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  12. #12
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    I still don't understand why you are extending JButton in MyButtons. It seems you could do it with composition. But in any event, I recommend you get rid of your magic numbers. If you assign reasonable names to your constants and then reference them in your loops it will be easier to debug and change if necessary. It also adds to the documentation.
    Once I get home I am going to work on your advice. I now see it needs to be revised. I just posted another comment pertaining to this program and hopefully following your advice will help fix it.

    If you're learning MVC then this is backwards.
    Your Controller should know next to nothing about the View.
    It should simply be registering itself as a listener so it can get relevant events and hold an instance (preferably an interface, rather than a concrete class) of the view so it can pass its own events into the GUI.
    Currently as I posted the code there is a lot of debugging going on so but from what I am gathering you are saying not to call the class view method inside the actionListener? I choose to handle the actionListers with a nested Class because I felt I only needed one Listener and would use if statements to handle the logic. Are you saying this is bad practice? Is creating a listener for each button better? If so that is a little confusing.

    Note you will probably want that handleEvent call to be in a worker to prevent the GUI freezing.
    I am going to have to google that one. Not sure what you are talking about.

  13. #13
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    26

    Default Re: MVC design issue:

    Concurrency in Swing.

    That will give you a good grounding on how Swing works, and should help prevent the otherwise inevitable "freezing GUI" problem.

    As for the listeners, if the buttons all do something similar (ie 4 buttons, one to move left, one right, one up, one down) then one Listener makes some sense.
    If they do different things (even Save and Cancel are in my mind different things) then I'd attach anonymous ones.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  14. #14
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    That will give you a good grounding on how Swing works, and should help prevent the otherwise inevitable "freezing GUI" problem.
    Thank you

    As for the listeners, if the buttons all do something similar (ie 4 buttons, one to move left, one right, one up, one down) then one Listener makes some sense.
    If they do different things (even Save and Cancel are in my mind different things) then I'd attach anonymous ones.
    I am thinking I will leave the listener but the matrix of buttons because they simply turn green, red, or blue is it is currently being searched. As for the Enter and Reset button I will create its own actionListener for it. I also have a JDropdown that has different search algorithms options. Therefore I would have to check what search method was selected when the enter button is pressed.

  15. #15
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    Concurrency in Swing.
    What I gather is whenever you use the SwingUtilites.invokeLater(new Runnable) then later use the run() method that is the Swing Thread. Swing generates one thread for you. Therefore if you want to have the program connect to a database or have a longer connected you need to establish new threads for that connection. Would it look something like Thread thread = new Thread(); and somehow attach the connection to the tread when that method is invoked.

  16. #16
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    26

    Default Re: MVC design issue:

    You're right in that Swing operates on a single thread (the EDT, Event Dispatch Thread), and you need to therefore try and do any "business" logic in another thread.
    That's where this bit comes in. The worker I mentioned above.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  17. #17
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    So this is the logic behind the singleton design pattern. Example"

    Create some class that has a GUI, let just use MVC

    Then create a class class DataBase and make the constructor private (so the new operator cannot be used else where)

    Then create methods like connect, disconnect etc.

    In the connect method I will create a new thread and use a windowListener in the View class in the MVC design. Am I on the right track?

  18. #18
    jocdrew21 is offline Senior Member
    Join Date
    Jan 2014
    Posts
    137
    Rep Power
    0

    Default Re: MVC design issue:

    So it has been brought to my attention that MVC should be seperated into differant packages.

    Is this true?

  19. #19
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: MVC design issue:

    The packages are irrelevant. It has to do more with the implementation details hidden from each part.

    Model-view-controller - Wikipedia, the free encyclopedia

    You might also consider buying a book or reading some articles on software architectures.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

Similar Threads

  1. Replies: 1
    Last Post: 09-27-2014, 01:24 AM
  2. Problem design issue
    By coyne20 in forum New To Java
    Replies: 3
    Last Post: 10-26-2012, 09:11 PM
  3. Preview design vs Run design
    By diamonddragon in forum NetBeans
    Replies: 3
    Last Post: 02-06-2012, 08:11 AM
  4. Regular Expression issue and setName() method issue
    By geforce in forum New To Java
    Replies: 2
    Last Post: 01-30-2012, 03:33 AM
  5. Design Issue
    By naveenmails in forum Advanced Java
    Replies: 3
    Last Post: 07-29-2008, 03:32 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •