Results 1 to 9 of 9
  1. #1
    Danieldcc is offline Member
    Join Date
    Sep 2010
    Posts
    83
    Rep Power
    0

    Default MouseeListener accessing paintcomponent help please

    Hey, so I'm generating a 10*10 board that generates random colour squares. If you click on a square, it's suppose to change color to a different random square. I'm almost done but my problem is when I use the MouseListener and find the rectangle I want to change, I don't know how to access the g2 object from where the mouselistener is in order to change that particular square....help please

    Java Code:
    public ColourGrid()
    {
        this.setPreferredSize(new Dimension(200,200));
        this.addMouseListener(new MyMouseListener());
        
        
    }
       public void paintComponent(Graphics g) {
    
        Graphics2D g2 = (Graphics2D)g;
    
       
        for(int i = 0; i < 10; i++) {
            for(int j = 0; j < 10; j++) {
            g2.setColor(new Color(generator.nextInt(255), generator.nextInt(255), generator.nextInt(255)));
            g2.fill(new Rectangle2D.Double(i * 20, j * 20, 20, 20));
    
            }
        }
    }
    
    class MyMouseListener implements MouseListener
    {
    public void mousePressed(MouseEvent event)
    {
    int x = event.getX();
    x = (x / 20) * 20;
    int y = event.getY(); 
    y = (y / 20) * 20;
    
    // Ok. found the rectangle I want to change...but how do I paint the rectangle I want now? I need to access the g2.fill but cannot access from this // location...help please
    
    }
    public void mouseReleased(MouseEvent event) {}
    public void mouseClicked(MouseEvent event) {}
    public void mouseEntered(MouseEvent event) {}
    public void mouseExited(MouseEvent event) {}
    }

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: MouseeListener accessing paintcomponent help please

    I'm generating a 10*10 board that generates random colour squares. If you click on a square, it's suppose to change color to a different random square.
    The following is a bit of a digression, but there's a point.

    What you say presupposes that the squares *have* a colour in some sense. (Otherwise you can't really talk about random colour squares or changing the colour of a square). The paint method, however, suggests that the squares don't have colour in any (semipermanent) sense.

    Java Code:
    public void paintComponent(Graphics g) {
     
        Graphics2D g2 = (Graphics2D)g;
     
        
        for(int i = 0; i < 10; i++) {
            for(int j = 0; j < 10; j++) {
                g2.setColor(new Color(generator.nextInt(255), generator.nextInt(255), generator.nextInt(255)));
                g2.fill(new Rectangle2D.Double(i * 20, j * 20, 20, 20));
     
            }
        }
    }
    What this code does is assign random colours to the squares every time the component gets repainted. So if you cover the component and then reveal it, the colours change etc.

    What should happen is that your class stores the colours of the 20x20 regions somewhere. The most natural would seem to be a double array of colours reflecting the 10x10 arrangement of the grid. Then when you paint it would look like this:

    Java Code:
    private Color[][] colorArray;
    public ColorGrid() {
        this.setPreferredSize(new Dimension(200,200));
        this.addMouseListener(new MyMouseListener());
        // create the colorArray and fill it with random colours
    }
    
    public void paintComponent(Graphics g) {
     
        Graphics2D g2 = (Graphics2D)g;
        
        for(int i = 0; i < 10; i++) {
            for(int j = 0; j < 10; j++) {
                g2.setColor(colorArray[i][j]);
                g2.fill(new Rectangle2D.Double(i * 20, j * 20, 20, 20));
             }
        }
    }
    With all this in place the mousePressed() method can be implemented as follows:

    Java Code:
    public void mousePressed(MouseEvent event) {
        // get the x/y of the region from the event
        // set colorArray[x][y] to a random value
        repaint();
    }
    It's the repaint() that does the magic. It tells the runtime that it should repaint the component and, when that happens the paintComponent() will use the newly assigned value in the array.

    -----

    In effect the two operations "set a colour" (which happens in response to a mouse click) and "use a colour" (which happens whenever the system decides to paint your component) are split apart so that they operate independently of one another. This is common with paintComponent(): you set the "state" of your component in response to user interaction, and paintComponent() uses the state that has been set to render the component on the screen. When you want to force a repaint so that newly made changes to state become visible you call repaint().
    Last edited by pbrockway2; 12-25-2011 at 07:00 AM.

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: MouseeListener accessing paintcomponent help please

    This is probably not what you want to hear, since most of your code is already written, but there's another way to solve this overall problem. Rather than use one JPanel that fills 10 x 10 Rectangles, you could create one JPanel that holds 100 other JPanels in a 10 x 10 grid using a GridLayout(10, 10). You could give each JPanel the same MouseListener that on mousePressed gets a random color, and calls setBackground(thisColor) on the JPanel that was pressed.

  4. #4
    Danieldcc is offline Member
    Join Date
    Sep 2010
    Posts
    83
    Rep Power
    0

    Default Re: MouseeListener accessing paintcomponent help please

    Thanks for all the information. You are very helpful and I'm learning a lot I think. Since I read the first reply and implemented it already, I'm gona stick with that. But, this exercise is just a pre-cursor for a minesweeper game I'm gona write and you gave me a great idea. Am I right to say that creating a grid of JPanels is gona be the right thing to do for a minesweeper game? I assume yes, since I'll be able to probably do more with a grid of jpanels than a grid of rectangles. And again...I really appreciate all the help.

    If anyone has a minute you can critique the code I wrote as per your previous suggestions....

    Java Code:
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    import java.awt.geom.*;
    import java.util.*;
    
    public class ColourGrid extends JPanel
    {
    
    final int ROWS = 10;
    final int COLUMNS = 10;
    final int Cell = 20;
    Random generator = new Random();
    private Color[][] colorArray = new Color[10][10];
    
    public ColourGrid()
    {
        
        this.setPreferredSize(new Dimension(200,200));
        this.addMouseListener(new MyMouseListener());
        for(int i = 0; i < ROWS; i++) {
            for(int j = 0; j < COLUMNS; j++) {
            colorArray[i][j] = new Color(generator.nextInt(255), generator.nextInt(255), generator.nextInt(255));
            
        }}
            }
        
    
       public void paintComponent(Graphics g) {
    
        Graphics2D g2 = (Graphics2D)g;
    
        for(int i = 0; i < ROWS; i++) {
            for(int j = 0; j < COLUMNS; j++) {
            g2.setColor(colorArray[i][j]);
            g2.fill(new Rectangle2D.Double(i * Cell, j * Cell, Cell, Cell));
            
            }
        }
    }
    
    class MyMouseListener implements MouseListener
    {
    public void mousePressed(MouseEvent event)
    {
    int x = event.getX();
    x = x / Cell;
    int y = event.getY(); 
    y = y / Cell;
    colorArray[x][y] = new Color(generator.nextInt(255), generator.nextInt(255), generator.nextInt(255));
    repaint();
    
    }
    public void mouseReleased(MouseEvent event) {}
    public void mouseClicked(MouseEvent event) {}
    public void mouseEntered(MouseEvent event) {}
    public void mouseExited(MouseEvent event) {}
    }
    
        public static void Main(String[] args)
        {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new FlowLayout());
            frame.add(new ColourGrid());
            frame.pack();
            frame.setVisible(true);
        }
    }

  5. #5
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: MouseeListener accessing paintcomponent help please

    It compiles and runs OK - once you change Main() to main().

    Initial Threads (The Java™ Tutorials > Creating a GUI With JFC/Swing > Concurrency in Swing) recommends that you create and show the GUI on the event dispatch thread. So the end of the code would look like:

    Java Code:
    private static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add(new ColourGrid());
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
    As - or if - you add greater complexity to the grid elements, the case for making a separate class for them as Fubarable suggests becomes greater and greater. As a general rule people try to have their classes model a specific type of thing.

  6. #6
    Danieldcc is offline Member
    Join Date
    Sep 2010
    Posts
    83
    Rep Power
    0

    Default Re: MouseeListener accessing paintcomponent help please

    tks.....ok. so i started to writed my minesweeper game and as usual running into problems.....

    Java Code:
    public MineSweeperGUI()
        {
         this.setLayout(new GridLayout(10,10));   
         for(int i = 0; i < ROWS; i++) {
            for(int j = 0; j < COLUMNS; j++) {
                cell = new JPanel();
                cell.setPreferredSize(new Dimension(40,40));
                cell.setBorder(BorderFactory.createLineBorder(Color.RED));
                cover = new JButton();
                cover.setPreferredSize(new Dimension(40,40));
                cell.add(cover);
                this.add(cell);        
        }}}
    When I ran the above code, it doesn't seem like the buttons fully cover the individual JPanels. Why? They're same size. Also, how do I avoid writing the setPreferredSize method for the JButton? Can't I just make it so it covers the whole JPanel box without having to determine the size for it?

  7. #7
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: MouseeListener accessing paintcomponent help please

    If you give cell a BorderLayout then add the button it will be sized to fit the panel. Further more cell itself need not have a preferred size set on it because the GridLayout will divide the size available (whatever it is) into 100 equal subdivisions.

  8. #8
    Danieldcc is offline Member
    Join Date
    Sep 2010
    Posts
    83
    Rep Power
    0

    Default Re: MouseeListener accessing paintcomponent help please

    cool...that worked...tks

    Java Code:
    public MineSweeperGUI()
        {
         this.setLayout(new GridLayout(10,10));
         this.setPreferredSize(new Dimension(400, 400));
         for(int i = 0; i < ROWS; i++) {
            for(int j = 0; j < COLUMNS; j++) {
                cell = new JPanel();
                cell.setLayout(new BorderLayout());
                cell.setBorder(BorderFactory.createLineBorder(Color.RED));
                cover = new JButton();
                cell.add(cover);
                this.add(cell);        
            }}
        }

  9. #9
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: MouseeListener accessing paintcomponent help please

    Great. It's a common error to begin with to want to set the size of everything in sight. But the best solution usually involves judicious use layout managers.

Similar Threads

  1. paintComponent
    By zock70 in forum AWT / Swing
    Replies: 1
    Last Post: 11-16-2011, 04:19 AM
  2. paintComponent problem
    By luke in forum New To Java
    Replies: 5
    Last Post: 04-02-2011, 03:07 PM
  3. geting value from paintComponent
    By gedas in forum New To Java
    Replies: 3
    Last Post: 03-21-2011, 08:56 PM
  4. Help with paintComponent!
    By joeyea in forum Java 2D
    Replies: 6
    Last Post: 12-27-2010, 02:59 PM
  5. JPanel PaintComponent
    By capiono in forum AWT / Swing
    Replies: 5
    Last Post: 10-31-2010, 03:36 AM

Posting Permissions

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