开发者

Points not being properly read by MouseListener

I'm having a problem where I can't properly access my instance Point data.

I create an multi-dimensional array of GridPanels, and instantiate each with a Point. When first created, everything works as expected.

pic1 http://img.skitch.com/20100218-fciwr7t73ci2gajafmfxa2yf9q.jpg

When I click on a GridPanel however, the Listener class always receives the Point from the last GridPanel that was created ( (3, 3) in this case.)

When I pass an int instead of a Point however, the int for the GridPanel that was clicked is shown (like you'd expect).

Anyone know what's going on here?

Thanks

import javax.swing.JFrame;

/**
 * Driver class.
 */
public class Test {
    /**
     * The main method.
     * @param args Command line arguments.
     */
    public static void main(String[] args) {
        JFrame frame = new JFrame("TEST");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TestPanel panel = new TestPanel();
        frame.getContentPane().add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

import java.awt.GridLayout;
import java.awt.Point;
import javax.swing.JPanel;

/**
 * Creates a 4 by 4 grid of GridPanels.
 */
public class TestPanel extends JPanel {
    static final int ROW_SIZE = 4;
    static final int COL_SIZE = 4;
    private GridPanel[][] g = new GridPanel[ROW_SIZE][COL_SIZE];

    public TestPanel() {
        Point coords = new Point();

        setLayout(new GridLayout(ROW_SIZE, COL_SIZE));

        for (int i = 0; i < ROW_SIZE; i++) {
            for (int j = 0; j < COL_SIZE; j++) {
                coords.setLocation(i, j);
                g[i][j] = new GridPanel(coords);
                add(g[i][j]);
            }
        }
    }
}

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * Contains the MouseListener.
 */
public class GridPanel extends JPanel {

    private JLabel label;
    private Point p;

    public G开发者_开发百科ridPanel(Point p) {
        this.p = p;
        label = new JLabel("" + p);

        add(label);

        setBackground(Color.WHITE);
        setPreferredSize(new Dimension(200, 50));

        addMouseListener(new SelectListener());
    }

    private class SelectListener extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
            label.setText("" + p);
        }
    }
}


The problem is that you are re-using the same point, stored in coords. You need to create a new point for each grid element. It looks to you as if each panel has a different point value stored in it because each panel has a different label. But in the line

label = new JLabel("" + p);

you are creating a String that contains the current value of p. But p can change later, and the label won't change with it.

So the easiest fix for your problem is to change the line

this.p = p;

to

this.p = new Point(p); // Create a defensive copy.

It looks like you may be currently somewhat confused about the difference between objects and fields. For example,

Point p = new Point(3, 4);
Point p2 = p;
p.x = 7;
System.out.println(p2.x);

will yield 7, as there is only one point being manipulated, though it's pointed to by two fields. Using = doesn't create a copy of the point.

(Apologies if I'm explaining things you already know!)


The point is and object so it is passed by reference. This means all your panels reference the same Point. Since you are changing the location on it all the time - the last will be shown.

You have to create new Point every time in the loop:

public TestPanel() {

    setLayout(new GridLayout(ROW_SIZE, COL_SIZE));

    for (int i = 0; i < ROW_SIZE; i++) {
        for (int j = 0; j < COL_SIZE; j++) {

            g[i][j] = new GridPanel(new Point(i, j));

            add(g[i][j]);
        }
    }

}


i change setPreferredSize(new Dimension(w, h)); this is done. but in my program i need change my frame size every time. so how can fit gridpanel in that case.... if frame size (1200,800) or (1170,920) i am not using JLabel here.


thankyou for answering

in place of this frame.pack(); i use frame.setSize(W,H);

in a gridpanel add setPreferredSize(new Dimension(x,y)); setBorder(BorderFactory.createLineBorder(Color.red)); i remove JLabel where x = w / col_size; y = h / row_size;

now when i run Test.java grid are not fitted in my frame;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜