Java MVC project - either I cannot update the drawing, or I cannot see it

I have a project based on the Model-View-Controller paradigm, and I'm having trouble working correctly.

The program has 4 panels, which are supposed to allow me to change the oval pattern on the screen in various ways. It seems that they are working fine, and after serious troubles, I was able to show them in a JFrame that contains the whole shebang. I managed to display them, breaking away from the instructions provided, but when I do this, I can not get the oval to be updated. However, if I follow the directions to the letter, I see only an empty frame.

The project had rather specific directions, which I followed up to a certain point, but some of the documentation was unclear. I think that what I am missing should be something simple, since nothing pops up at me as if it makes no sense. I must admit that my Java experience is limited, and my experience with the GUI / paradigms is even greater.

In any case, I searched on the Internet, and this site widely tried to understand what was wrong, but this is a somewhat concrete example, and to be honest, I just don’t know enough about it to summarize any answers that I have find online and find out that is missing. I've been looking at this code for too long, so I really hope someone can help me.

public class Model { private Controller controller; private View view; private MvcFrame mvcFrame; private int radius = 44; private Color color = Color.BLUE; private boolean solid = true; //bunch of mutators and accessors for the above variables public Model() { controller = new Controller(this); view = new View(this); mvcFrame = new MvcFrame(this); } } 

Here is the model class. It seems pretty simple. I think that my understanding of what is happening here is solid and nothing seems wrong. Included mainly for context.

 public class Controller extends JPanel{ private Model model; public Controller(Model model) { this.model = model; setBorder(BorderFactory.createLineBorder(Color.GREEN)); setLayout(new GridLayout(4,1)); add(new RadiusPanel(model)); add(new ColorPanel(model)); add(new SolidPanel(model)); add(new TitlePanel(model)); } } 

This is the controller class. As far as I can tell, setBorder, setLayout and a series of additives do nothing here. I commented on them, but this is how the instructions said that I was doing something, so either there is an error or something in my setting is incorrect. However, when I did it this way, I would get an empty window (JFrame), but none of the panels appeared in it. What I did to fix this, add the add functions to the mvcFrame class:

 public class MvcFrame extends JFrame { private Model model; public MvcFrame(Model model){ this.model = model; //setLayout(new GridLayout(4,1)); //add(new RadiusPanel(model)); //add(new ColorPanel(model)); //add(new SolidPanel(model)); //add(new TitlePanel(model)); //add(new View(model)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setSize(800,600); setVisible(true); } } 

So, here, when everything starts to get weird. The first block of code with comments is the same as in the Controller class. The reason I commented on it was that it was just a good assumption - it should not be as indicated in the instructions. However, this worked in order to show the panels, but at that moment I was still tearing my hair, trying to display the oval.

Another commented line (add (new view (model));) was another attempt to make everything work. In this case, I put these add functions in the View class (see Code with comments below). This actually showed both the oval and the panels, but this method would not allow me to update the oval. In addition, although I only had an oval display, I cannot understand what exactly happened, and I cannot make it return.

 public class View extends JPanel{ private Model model; public View(Model model) { this.model = model; //setLayout(new GridLayout(4,1)); //add(new RadiusPanel(model)); //add(new ColorPanel(model)); //add(new SolidPanel(model)); //add(new TitlePanel(model)); repaint(); } @Override protected void paintComponent(Graphics g){ super.paintComponent(g); //center of view panel, in pixels: int xCenter = getWidth()/2; int yCenter = getHeight()/2; int radius = model.getRadius(); int xStart = xCenter - radius; int yStart = yCenter - radius; int xWidth = 2 * radius; int yHeight = 2 * radius; g.setColor(model.getColor()); g.clearRect(0, 0, getWidth(), getHeight()); if (model.isSolid()){ g.fillOval(xStart, yStart, xWidth, yHeight); } else { g.drawOval(xStart, yStart, xWidth, yHeight); } } } 

A similar idea, as before - commented code - is the material that I added to try to make everything work, but is not based on these directions. In case this material was excavated, I had an addition (new view (model)); line from mvcFrame line also without excavation.

Various panel classes (SolidPanel, ColorPanel, etc.) simply extend the ControlPanel class, which extends JPanel. All of them seem to work as expected, without having a lot of problems with them. There is also a driver that launches a graphical interface. This also works as expected.

The main problem I am facing is that I cannot get an oval to show it, and once I was able to display it, none of the options for changing it worked. I feel like I'm around, but I'm just at a loss for other things to try at this point.

Anyone who can help will receive my sincere thanks.

+4
source share
3 answers

Here's a very hasty rewrite of the thing, "just to make it work."

main.java

 public class main { public static void main(String[] args) { // The JFrame could be created here, since it lasts the life // of the program. //...then, later, the model. Model mdl = new Model(); // ...and then move on to applying the view and control to the frame. } } 

Controller.java

 // Nothing interesting here, added for consistency. public class Controller { private final Model model; public Controller(Model model) { // The frame is shown automatically in the model here. this.model = model; // The frame setVisible is a control issue, should be called // from in here, not automatically in the model. } } 

Mvcframe.java

 import javax.swing.JFrame; public class MvcFrame extends JFrame { private final Model model; public MvcFrame(Model model){ this.model = model; // Anytime you add anything to a JFrame, use the content pane. this.getContentPane().add(model.getView()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // This line centers the frame on your screen. setLocationRelativeTo(null); setSize(800,600); // The frame won't paint until it visible. // This means if you check dimensions, everything will be 0 x 0 // until this line is called. setVisible(true); } } 

Model.java

 import java.awt.Color; public class Model { private final Controller controller; // Not used yet private final View view; private final MvcFrame mvcFrame; // Not used yet // Mutators and accessors needed for these guys (set/get) private final int radius = 44; private final Color color = Color.BLUE; private final boolean solid = true; public Model() { controller = new Controller(this); view = new View(this); mvcFrame = new MvcFrame(this); } public View getView() { return view; } public int getRadius() { return radius; } public Color getColor() { return color; } public boolean isSolid() { return solid; } } 

View.java

 import java.awt.Graphics; import javax.swing.JPanel; public class View extends JPanel{ private final Model model; public View(Model model) { this.model = model; } @Override protected void paintComponent(Graphics g){ super.paintComponent(g); //center of view panel, in pixels: int xCenter = getWidth()/2; int yCenter = getHeight()/2; int radius = model.getRadius(); int xStart = xCenter - radius; int yStart = yCenter - radius; int xWidth = 2 * radius; int yHeight = 2 * radius; g.setColor(model.getColor()); g.clearRect(0, 0, getWidth(), getHeight()); if (model.isSolid()){ g.fillOval(xStart, yStart, xWidth, yHeight); } else { g.drawOval(xStart, yStart, xWidth, yHeight); } } } 
+2
source

Your question is a bit confusing and long, and I'm not sure why you commented on the critical parts of the code, but the first question is:

 //add(new View(model)); 

Are you adding a view to the frame? The oval can be drawn just fine, but the view is not added.


The most likely problem in this code is:

 public class MvcFrame extends JFrame { ... public MvcFrame(Model model){ ... //setLayout(new GridLayout(4,1)); //add(new RadiusPanel(model)); ... } } 

When you call add directly, it refers to a superclass (JFrame). Unfortunately, JFrames are hidden because they have a contentPane that contains the layout. Further stealth: this content area is a null layout and can only be changed by entering your own panel.

So you should probably do something like this. Even if you don’t follow exactly, the methods should help you a lot:

 ... JPanel pnl = new JPanel(new GridLayout(4, 1)); this.setContentPane(pnl); pnl.add(new RadiusPanel(model)); ... 

If you do not want to explicitly set the content area, you can use this.getContentPane().add(foo) .

A null layout error can also affect your oval drawing, because when you add a JPanel, its size is not specified, so the default is (0,0) .


Also, you don't know why your controller extends JPanel. Your presentation should be accessible to the controller and should be the only thing with any swing components.

+1
source

Although I had another problem, a line in sight:

g.clearRect (0, 0, getWidth (), getHeight ());

Solved everything for me in my project because it did not erase the previous Oval, so I could only see the changes if I did it anymore. Thanks.

0
source

All Articles