Точки не читаются должным образом MouseListener - PullRequest
3 голосов
/ 18 февраля 2010

У меня проблема с тем, что я не могу правильно получить доступ к своим данным Point.

Я создаю многомерный массив GridPanels и создаю каждый экземпляр с помощью Point. При первом создании все работает как положено.

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

Однако, когда я щелкаю GridPanel, класс Listener всегда получает Point от last GridPanel, который был создан ((3, 3) в этом случае.)

Однако, когда я передаю int вместо Point, показывается int для GridPanel, на который щелкнули (как и следовало ожидать).

Кто-нибудь знает, что здесь происходит?

Спасибо

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 ]

2 голосов
/ 18 февраля 2010

Проблема в том, что вы повторно используете одну и ту же точку, сохраненную в 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 голос
/ 18 февраля 2010

Точка и объект, поэтому он передается по ссылке. Это означает, что все ваши панели ссылаются на одну и ту же точку. Поскольку вы меняете местоположение на нем все время - будет показано последнее.

Вы должны создавать новую точку каждый раз в цикле:

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

}
0 голосов
/ 12 марта 2010

Спасибо, что ответили

вместо этого 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, сетка не помещается в моем кадре;

0 голосов
/ 10 марта 2010

я меняю setPreferredSize (новое измерение (ш, ч)); готово. но в моей программе мне нужно каждый раз менять размер кадра. Так как же в этом случае уместится сетка? Если размер кадра (1200 800) или (1170 920) я здесь не использую JLabel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...