I am trying to build an application that finds all possible ways of arranging 8 queens on a chess board in such a way that no two of them are on either the same row, column, or diagonal. I am also trying to do this applying what I think is supposed to be MVC architecture. However, I am a little confused and am having hard time with my view component.

here I have my view component:

import javax.swing.*;
   import java.awt.*;

   public class Eksi extends JPanel{
   
   //this field variable holds 64 squares of a chess board
   //that is, 64 instances of my Kutia class
      private Kutia[][] k;
      private Model doc;

      public Eksi(){
         RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
         JFrame x = new JFrame();
         x.getContentPane().add(this);
         x.setSize(500, 500);
         x.setVisible(true);
      }
   
      public void paintComponent(Graphics g){
      
         for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
               if((i+j)%2 == 0){
                  g.setColor(Color.black);
               }
               else{
                  g.setColor(Color.red);
               }
               g.fillRect(50 + i*20, 50 + j*20, 20, 20);
            }
         
         }
         if(k != null){
            for(int i = 0; i < 8; i++){
               for(int j = 0; j < 8; j++){
                  if(k[j][i].occupied()){
                     g.setColor(Color.white);
                     g.drawString(k[i][j].figura(), i*20 + 52, j*20 + 70);
                     try { Thread.sleep(3000); }
                        catch (InterruptedException e) { }					
                  }
               
               }			
            }
            try { Thread.sleep(300); }
               catch (InterruptedException e) { }
         }
      }
   
      public void ndihmesePaint(Kutia[][] ituk){
         k = ituk;
      	
         for(int i = 0; i < k.length; i++){
            for(int j = 0; j < k.length; j++){
               System.out.print(k[i][j].figura() + " " );
            }
            System.out.println();
         }
         repaint();      	
      }
   
   
   
   
   }

I expect that every time I call method ndihmesePaint() in my controller class, as long as I update the parameter I pass on to the method, the view should repaint() and show me a different result. However, calling this method causes no effect on my view. what am I missing? anyone?

I think posting my other two classes is unnecessary. if need be, I will post the two classes also.

Recommended Answers

All 12 Replies

Looks reasonable to me. How are you calling ndihmesePaint() ? If you are calling it from the event dispatch thread, such as from a button click, then your repaints() may be getting blocked on the queue.

nothing to your topic (because there nothing about Model and Controler), but questions

1/ why are you using RepaintManager and for disable DoubleBuffering, btw isn't correct play with opacity

2/ for why reason you slept 3sec (that's aminations)

3/ are you tried what's hapends if you refuse MFC(if at the beginning you will not use MFC) and directly write runnable App, thenafter spent

a/ using LayoutManager:

- don't extends any class with Container if contains TopLayoutContainer
- standard for placing JCOmponents is JFrame -> JSchrollPane -> JPanel (with BorderLayout)
- sure in this case JFrame -> JPanel with GridLayout(8,8,2,2)

b/ or everything with 2D painting, good, maybe excelent way, but so hard way too (not basic algebra)

c/ in this form no idea, because I never paint chessBoard,

My System.out is working fine. However, the painting in my paintComnponent is not taking place.
here is my controller class (read it from bottom up, as for experimenting I call ndihmesePaint() method at the end of this file):

public class Kontroller{
   
      public static void main(String[] args){
      
         Kutia[][] x = new Kutia[8][8];
         VeproMeMatrica vm = new VeproMeMatrica();
      //------------------------------------------------------
      
      /*         String[] perm = vm.permutim("8");
         for(int i = 0; i < vm.Factoriel(8); i++){
            System.out.println(perm[i]);
         }
      */    
      
      //------------------------------------------------------
      	//kjo pjese e ben inicializimin e objekteve Kuti me mbretereshat e vendosura
      	//sipas vlerave te i-ve dhe j-ve ne kushtin if
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 1) || (i == 1 & j == 3) || (i == 2 & j == 5) || (i == 3 & j == 7) || (i == 4 & j == 2) || (i == 5 & j == 0)|| (i == 6 & j == 6) || (i == 7 & j == 4)){
                  x[i][j] = new Kutia(i, j, "M");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
      //-------------------------------------------------------
      //pasi te jete inicializu 'situata', apo pasi te jene vendose mbretereshat ne tabele
      //situata x i pasohet klases model, ne menyre qe ajo t'i shenjoj kutite qe preken nga
      //mbreteresha (por jo edhe kutite qe jane te zena me mbretereshat)
         Model y = new Model(x);
         Eksi ek = new Eksi();
      //-------------------------------------------------------
      //keta dy cikle for bejn afishimin e figurave qe tabela e shahut mbane
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               System.out.print(x[i][j].figura() + " " );
            }
            System.out.println();
         }
      //--------------------------------------------------------
      //kjo pjese e rifreskon tabelen duke e zevendesuar me tabelen qe mbane
      //te shenjuara kutite qe jane te arritshme nga se paku njera mbretereshe
      //duke vendosur numer me te madh se zero ne kutite qe jane te arritshme
      //numri qe secila kuti mbane eshte i barabart me numrin e mbretereshave qe
      //e arijne ate kuti
         x = y.modeled();
      
      	//--------------------------
         if(y.valido(x) == 8){
            System.out.println("HELLO HELLO HELLO HELLO HELLO HELLO HELLO");
            for(int i = 0; i < x.length; i++){
               for(int j = 0; j < x.length; j++){
                  System.out.print(x[i][j].vl() + " " );
               }
               System.out.println();
            }
         }
      	
      	//---------------------------
      	
      	
      	
      	
      
      	
      	
      //------------------------------------------------------
      	//kjo pjese e ben inicializimin e objekteve Kuti me mbretereshat e vendosura
      	//sipas vlerave te i-ve dhe j-ve ne kushtin if
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 2) || (i == 1 & j == 4) || (i == 2 & j == 6) || (i == 3 & j == 0) || (i == 4 & j == 3) || (i == 5 & j == 1)|| (i == 6 & j == 7) || (i == 7 & j == 5)){
                  x[i][j] = new Kutia(i, j, "M");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
         y.touch(x);
         x = y.modeled();
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               System.out.print(x[i][j].figura() + " " );
            }
            System.out.println();
         }
      	
      //-------------------------------------------------------
      
      	      
         System.out.println();
      //--------------------------------------------------------
      //keta dy cikle for e bejn afishimin e kutive te tabeles duke treguar
      //se cila kuti eshte e zene e cila jo. nese nje kuti eshte e zene
      //ajo shenjohet me true, dhe perndryshe me false
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               //System.out.print(x[i][j].occupied() + " " );
            }
            //System.out.println();
         }
      //---------------------------------------------------------
         System.out.println();
      
      //keta dy cikle for e afishojne tabelen, me kutite e shenjuara sipas numrit
      //te mbretereshave qe e arijne ate kuti
      
         if(y.valido(x) == 8){
            System.out.println("HELLO HELLO HELLO HELLO HELLO HELLO HELLO");
            for(int i = 0; i < x.length; i++){
               for(int j = 0; j < x.length; j++){
                  System.out.print(x[i][j].vl() + " " );
               }
               System.out.println();
            }
         }
         
      	//---------------------------------------------------
      		//ek.ndihmesePaint(x);
      	//---------------------------------------------------
      	
      	
      //---------------------------------------------------------
         System.out.println();
      //KJO PJESE E BEN AFISHIMIN E FIGURAVE QE SECILA KUTI NE NJE TABELE PERMBANE
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               //System.out.print(x[i][j].figura() + " " );
            }
            //System.out.println();	
         }
      	
         ek.ndihmesePaint(x);
      		
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 2)){
                  x[i][j] = new Kutia(i, j, "M");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
      	
         System.out.println("---------------------------------------");					
         ek.ndihmesePaint(x);
      	
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 2) || (i == 1 & j == 4) || (i == 2 & j == 6)){
                  x[i][j] = new Kutia(i, j, "M");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
         System.out.println("---------------------------------------");		
         ek.ndihmesePaint(x);
      		
      }
   
   }

a note to Ezzaral,
the for loops preceding ek.ndihmesePaint(x) lines update the variable x.

Your repaints() are going to take a long time since you are pausing 3 seconds between each element drawn and I would agree with mKorbel that doing the animation in your paintComponent() method is probably not the best idea. repaint() can be called for many reasons by the system and should be as lightweight as possible.

Another forum member told me that paintComponent is not good for animation, but that is all I know right know. however, I do not have in my actual code that 3 second pause in between each iteration of my loops. I have removed them - I thought that I did that prior to posting the code. anyways. my code ndihmesePaint method is System.out-ing updated versions of k variable, but it wont paint it.

if you want to play with that there is my "stupid example for Forums" how you can ignore EDT (as mentioned Ezzaral) and with thread.sleep(int value) in Swing, your painting must be synchronous, f.e. each line, pause, next line pause,

back to thread.sleep, that's killing panting in Swing, because lock current instance, but never hand up, never surrender

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class ShakeComponents1 {

    private JFrame frame = new JFrame();
    private final String items[] = {"One", "Two", "Three"};
    private Timer timer;
    private JPanel panel = new JPanel();
    private JPanel buttonPanel = new JPanel();
    private JButton button = new JButton("  Exit  ");
    private boolean repeats = true;
    private boolean runs = false;
    private Color clr[] = {Color.red, Color.blue, Color.magenta};
    private Insets initMargin;

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ShakeComponents1().makeUI();
            }
        });
    }

    public void makeUI() {
        buttonPanel = new JPanel();
        buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        buttonPanel.setLayout(new BorderLayout());
        button.setPreferredSize(new Dimension(100, 45));
        button.setForeground(Color.darkGray);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {
                Runnable doRun = new Runnable() {

                    @Override
                    public void run() {
                        System.exit(0);
                    }
                };
                SwingUtilities.invokeLater(doRun);
            }
        });
        button.addMouseListener(new java.awt.event.MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                if (runs) {
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            runs = false;
                            timer.stop();
                            changePnlBorder(new EmptyBorder(5, 5, 5, 5));
                            changeBtnForegroung(Color.darkGray);
                        }
                    });
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
                if (!runs) {
                    timer.start();
                    runs = true;
                }
            }
        });
        buttonPanel.add(button);
        final Insets margin = button.getMargin();
        panel.add(buttonPanel);
        for (int i = 0; i < 2; i++) {
            JComboBox combo = new JComboBox(items);
            combo.setMinimumSize(new Dimension(50, 25));
            combo.setMaximumSize(new Dimension(150, 25));
            combo.setPreferredSize(new Dimension(100, 25));
            combo.addActionListener(new ShakeAction());
            panel.add(combo);
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setLocation(50, 50);
        frame.setVisible(true);
        timer = new Timer(500, new ShakeAction());
        timer.setRepeats(repeats);
        initMargin = button.getMargin();
    }

    private class ShakeAction extends AbstractAction {

        private static final long serialVersionUID = 1L;
        private int noColor = 0;
        private Border border;
        private int count = 0;

        @Override
        public void actionPerformed(ActionEvent e) {
            timer.start();
            if (count > 5) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(750);
                            changeBtnForegroung(Color.darkGray);
                            Thread.sleep(750);
                            count = 0;
                            Thread.sleep(750);
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                    }
                }).start();
            } else {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            runs = true;
                            if (noColor < 2) {
                                noColor++;
                                changeBtnForegroung(clr[noColor]);
                            } else {
                                noColor = 0;
                                changeBtnForegroung(clr[noColor]);
                            }
                            changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10));
                            border = new EmptyBorder(0, 5, 10, 5);
                            changePnlBorder(border);
                            Thread.sleep(100);
                            changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10));
                            border = new EmptyBorder(0, 0, 10, 10);
                            changePnlBorder(border);
                            Thread.sleep(100);
                            changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10));
                            border = new EmptyBorder(5, 10, 5, 0);
                            changePnlBorder(border);
                            Thread.sleep(100);
                            changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10));
                            border = new EmptyBorder(10, 10, 0, 0);
                            changePnlBorder(border);
                            Thread.sleep(100);
                            changeBtnMargin(new Insets(initMargin.top, initMargin.left, initMargin.bottom, initMargin.right));
                            border = new EmptyBorder(5, 5, 5, 5);
                            changePnlBorder(border);
                            Thread.sleep(100);
                            count++;
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                    }
                }).start();
            }
        }
    }

    private void changePnlBorder(final Border b) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                buttonPanel.setBorder(b);
                buttonPanel.revalidate();
                buttonPanel.repaint();
            }
        });
    }

    private void changeBtnForegroung(final Color c) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                button.setForeground(c);
            }
        });
    }

    private void changeBtnMargin(final Insets margin) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                button.setMargin(margin);
            }
        });
    }
}

because

Another forum member told me that paintComponent is not good for animation

paintComponent is for JComponents, and your code doesn't show any, there is paint

note: back to my question about RepaintManager, be sure that you'll calculated with basic Native Os latency for thread.sleep(int value), as I know for Wins platform is in miliseconds > 63, otherwise you get error from RepaintManager

that's it for today here is one hour a.m.

it's here too one a.m. I'm from Kosovo. anyways. that milliseconds thing... I'm confused man. I'm not a pro. I put that RepaintManager line because if I don't, when I use try-catch for animation purposes, it works better with RepaintManager.

thanks for trying though. good night to you.

a newer, simpler, shorter version of my controller class. please check it.

public class Anot{
   
   
      public static void main(String[] args){
      
         Kutia[][] x = new Kutia[8][8];
      	//here I initialize 64 objects of type Kutia;
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 1) || (i == 1 & j == 3) || (i == 2 & j == 5) || (i == 3 & j == 7) || (i == 4 & j == 2) || (i == 5 & j == 0)|| (i == 6 & j == 6) || (i == 7 & j == 4)){
                  x[i][j] = new Kutia(i, j, "M");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
      	//here I instantiate my view component
         Eksi ek = new Eksi();
      	//here I pass the 64 objects of Kutia to ndihmesePaint method of
      	//my view component
      	//the method ndihmesePaint assigns the 64 objects to the field variable k
      	//of the view component. the method then System.out's the chess piece each
      	//of 64 objects holds, and then it calls method repaint().
         ek.ndihmesePaint(x);
      	
      	//i change the 64 Kutia objects in these two for loops
         for(int i = 0; i < x.length; i++){
            for(int j = 0; j < x.length; j++){
               if((i == 0 & j == 2) || (i == 1 & j == 4) || (i == 2 & j == 6) || (i == 3 & j == 0) || (i == 4 & j == 3) || (i == 5 & j == 1)|| (i == 6 & j == 7) || (i == 7 & j == 5)){
                  x[i][j] = new Kutia(i, j, "K");
               }
               else{
                  x[i][j] = new Kutia(i, j, "");
               }
            }
         }
      	
      	//i make the application wait three seconds before I pass the new 64 Kutia objects
      	//to ndihmesePaint() method
         try { Thread.sleep(3000); }
            catch (InterruptedException e) { }
      		//-------------
         ek.ndihmesePaint(x);
      //if I leave it the way it is now, my application's behavior is such that this last
      //version of my 64 Kutia objects is painted twice with a three second pause in between.
      //I expect that I'd two diferent situations painted with a three second pause in between
      //HOWEVER, if I comment out the last two for loops, and the last ek.ndimesePaint(),
      //the application paints the first version as expected.
      	
      
      }
   
   
   
   
   
   }

Going back to the original MVC question, which seems to have got submerged in all these issues about waits and repaints...
A simple way to do this as MVC goes as follows:
1. Model class - has 8x8 array modelling the logic of the chessboard and populating it with the possible queen moves etc
2. View class - a Swing window that gets an instance of Model passed into its constructor, and displays the contents of the model on request
2. Controller class - creates a new instance of Model, creates a new instance of View, instructs the Model to populate with Queen moves, instructs the View to display, repeats last two steps in loop (with delays if you want) to find solutions.

An better, but optional, enhancement is to link the View to its Model via an Observable pattern (AKA change Listener) so that the View will update automatically every time the Model is changed.

thanks a lot for trying to help friends. I have solved my initial problem. I don't know what exactly solved it, but it is working.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.