0

I have a very simple program that ask user to click one of four panels that match its background color to that of the bigger panel(aka displaypanel), which randomly set its background color as one of the four.If the wrong panel is clicked Joptionpane comes out; displaypanels background is temporarily set to black. If clicked yes, displaypanel should re set its background color. The problem is I dont alway see the background being updated.Instead sometimes the background stays black. ...and what is more confusing is while it stays black if you drag another window over the window of this program if you see color partially being updated as moves over the display panel or just switching to a different window and refoucs then you see the complete updated background color.

so why is the setMethod called but only occasionally executed by whatever the paint method is behind the scenes? and why casting other windows or frames make it visible? does it have anything to do with the mouse click event being processed?

I appreciate any explanation for all of this,thanks guys

public class MainPanel extends JPanel{


    Subpanel panel1;
    Subpanel panel2;
    Subpanel panel3;
    Subpanel panel4;
    Subpanel displaypanel;

    Color[] color; //stores all the  colors that display on the subpanels


    public static void main(String[] args) {
        JFrame window=new JFrame("This is a test");
        window.setContentPane(new MainPanel());
        window.setLocation(100,30);
        window.setSize(600,500);
        window.setVisible(true);

    }


    public MainPanel(){


        setLayout(new FlowLayout(FlowLayout.CENTER,80,30));


        panel1= new Subpanel();
        panel2= new Subpanel();
        panel3= new Subpanel();
        panel4= new Subpanel();

        //the big sub panel
        displaypanel= new Subpanel();

        color=new Color[4];
        color[0]=Color.BLUE;
        color[1]=Color.RED;
        color[2]=Color.YELLOW;
        color[3]=Color.GREEN;



        setBackground(Color.GRAY);
        displaypanel.setBackground(displayRandomColor());
        panel1.setBackground(color[0]);
        panel2.setBackground(color[1]);
        panel3.setBackground(color[2]);
        panel4.setBackground(color[3]); 

        displaypanel.setPreferredSize(new Dimension(400,250));
        panel1.setPreferredSize(new Dimension(70,70));
        panel2.setPreferredSize(new Dimension(70,70));
        panel3.setPreferredSize(new Dimension(70,70));
        panel4.setPreferredSize(new Dimension(70,70));

        add(displaypanel);
        add(panel1);
        add(panel2);
        add(panel3);
        add(panel4);





    }


    public void paintComponent(Graphics g){
        super.paintComponent(g);



    }

    public Color displayRandomColor(){
            Color i=Color.WHITE;
        switch ((int)(Math.random()*4)+1){
            case 1:
            i= Color.YELLOW;
            break;

            case 2:
            i= Color.BLUE;
            break;

            case 3:
            i= Color.GREEN;
            break;

            case 4:
            i= Color.RED;
        }   
        return i;
    }


    public class Subpanel extends JPanel{

        public Subpanel(){
                this.addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent evt){
                    Component source=(Component)evt.getSource();

                        if((source.getBackground()).equals(displaypanel.getBackground())){
                            //do nothing for this test..
                    }
                        else{
                                displaypanel.setBackground(Color.BLACK);

                                //ask user to reset the background color
                                //**the following 2 lines introduces the problem
                            if(JOptionPane.showOptionDialog(null,"click Yes to see a new Color","Incorrect",JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,null,null)==JOptionPane.YES_OPTION){
                                displaypanel.setBackground(displayRandomColor());

                            }
                        }

                        }





        });
        } //end of constructor
        public void paintComponent(Graphics g){
            super.paintComponent(g);

        }

    }

}
Scottie
  • 1
  • 1
  • 1
    Use white space sparingly. [Don't use `setPreferredSize()` when you really mean to override `getPreferredSize()`](http://stackoverflow.com/q/7229226/230513). See also [*Initial Threads*](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Feb 26 '16 at 23:14
  • I'm not able to reproduce your problem. What version of Java are you using? On what OS are you running? – VGR Feb 27 '16 at 00:10
  • Im running java 8 on Max OS X 10.7.5. sometimes It takes 4 or 5 wrong clicks to see that problem . Did u give that many tries and you dont see the background stuck in black? – Scottie Feb 27 '16 at 04:15
  • I ran the Program in Windows and did not have this problem at all!! any thoughts?? @trashgod – Scottie Feb 28 '16 at 21:38
  • Works great with `EventQueue.invokeLater()`. – trashgod Feb 29 '16 at 00:36

1 Answers1

1

Your program works reasonably well when synchronized correctly. A few notes:

  • Initialize objects once, as early in program execution as practical.

  • Use an instance of Random to get random integers; note the much simpler implementation of displayRandomColor().

    private Color displayRandomColor() {
        return color[r.nextInt(color.length)];
    }
    
  • Swing GUI objects should be constructed and manipulated only on the event dispatch thread.

  • Don't use setPreferredSize() when you really mean to override getPreferredSize()], as suggested here.

  • Use layouts and pack() the enclosing window.

image

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class MainPanel extends JPanel {

    private static final Random r = new Random();
    private final JPanel displayPanel;
    private Color[] color = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
    private Subpanel panel1 = new Subpanel(color[0]);
    private Subpanel panel2 = new Subpanel(color[1]);
    private Subpanel panel3 = new Subpanel(color[2]);
    private Subpanel panel4 = new Subpanel(color[3]);

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame window = new JFrame("This is a test");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                window.add(new MainPanel());
                window.pack();
                window.setLocationRelativeTo(null);
                window.setVisible(true);
            }
        });
    }

    public MainPanel() {
        setLayout(new BorderLayout());
        setBackground(Color.GRAY);

        //the big sub panel
        displayPanel = new JPanel() {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(320, 240);
            }
        };
        displayPanel.setBackground(displayRandomColor());

        //the control panel
        JPanel p = new JPanel();
        p.add(panel1);
        p.add(panel2);
        p.add(panel3);
        p.add(panel4);

        add(displayPanel, BorderLayout.CENTER);
        add(p, BorderLayout.SOUTH);
    }

    private Color displayRandomColor() {
        return color[r.nextInt(color.length)];
    }

    public class Subpanel extends JPanel {

        public Subpanel(Color color) {
            this.setBackground(color);
            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent evt) {
                    Component source = (Component) evt.getSource();
                    if ((source.getBackground()).equals(displayPanel.getBackground())) {
                        System.out.println(source.getBackground());
                    } else {
                        displayPanel.setBackground(Color.BLACK);
                        if (JOptionPane.showOptionDialog(null,
                            "Click Yes to see a new Color", "Incorrect",
                            JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE,
                            null, null, null) == JOptionPane.YES_OPTION) {
                            displayPanel.setBackground(displayRandomColor());
                        }
                    }
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(70, 70);
        }
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045