MouseListener无法正确读取点

时间:2010-02-18 20:37:01

标签: java swing

我遇到了无法正确访问我的实例Point数据的问题。

我创建了一个GridPanels的多维数组,并使用Point实例化每个数组。 首次创建时,一切都按预期工作。

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

但是,当我单击GridPanel时,Listener类始终从创建的 last GridPanel接收Point(在这种情况下为(3,3))。

当我传递一个int而不是一个Point时,会显示所点击的GridPanel的int(就像你期望的那样)。

任何人都知道这里发生了什么?

由于

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 GridPanel(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);
        }
    }
}

4 个答案:

答案 0 :(得分:2)

问题是您正在重新使用存储在coords中的相同点。您需要为每个网格元素创建一个新点。它看起来好像每个面板都存储了不同的点值,因为每个面板都有不同的标签。但是在行

label = new JLabel("" + p);

您正在创建一个包含当前值p的字符串。但p可以稍后更改,标签也不会随之改变。

因此,解决问题的最简单方法是更改​​行

this.p = p;

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

看起来您可能对目标和字段之间的差异感到有些困惑。例如,

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

将产生7,因为只有一个点被操纵,尽管它被两个字段指向。使用=不会创建该点的副本。

(如果我要解释你已经知道的事情,请道歉!)

答案 1 :(得分:1)

点是和对象,所以它通过引用传递。这意味着所有面板都引用相同的Point。由于您一直在更改它的位置 - 将显示最后一个。

每次在循环中都必须创建新的Point:

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]);
        }
    }

}

答案 2 :(得分:0)

我改变了setPreferredSize(new Dimension(w,h));这个完成了。 但在我的程序中,我每次都需要更改框架大小。那么如何在这种情况下适合gridpanel ....如果帧大小(1200,800)或(1170,920)我在这里没有使用JLabel。

答案 3 :(得分:0)

谢谢你回答

代替这个frame.pack();我使用frame.setSize(W,H);

在网格面板中添加 setPreferredSize(new Dimension(x,y)); setBorder(BorderFactory.createLineBorder(Color.red)); 我删除JLabel 其中x = w / col_size; y = h / row_size;

现在当我运行Test.java网格时,我的框架中没有安装;