Простые интерактивные события мыши Swing 'grid' не кажутся точными

Я пытаюсь (на данный момент) создать сетку шириной 25 квадратов, на 12 квадратов вниз и заставить их переключаться между двумя цветами при нажатии (по умолчанию все квадраты синие, а нажатие на один сделает его красным. Еще один щелчок превратит он снова стал синим)

Я давно не занимался Swing, это будет очень простой инструмент для дизайна уровней для моего Android-приложения. Это «отчасти» работает, но положение мыши по какой-то причине кажется немного «неправильным».

Это скриншот:

введите здесь описание изображения

Указатель мыши, который вы можете видеть, находится там, где я щелкнул, а красный квадрат изменил цвет (положения x также отключены, но не так сильно, как «y»).

Почему это происходит? Помощь приветствуется.

Код (извиняюсь за путаницу, вызванную тем, что мои панели JPanel называются «myFrames» ;-))

public class GUI extends JFrame implements MouseListener{

JFrame myFrame = new JFrame();
JLabel myPanels[];

    public GUI(){

        super("Grid");
        setSize(1000,400);
        setResizable(false);
        setLayout(new GridLayout(12,25));
        addMouseListener(this);

        myPanels = new JLabel[300];

        for (int x = 0;x<myPanels.length;x++){

            myPanels[x]=new JLabel("");
            myPanels[x].setOpaque(true);
            myPanels[x].setBackground(Color.BLUE);
            myPanels[x].setBorder(BorderFactory.createLineBorder(Color.black));
        }
//Add all the squares (JLabels)
        for (int x = 0;x<myPanels.length;x++)
        add(myPanels[x]);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    //iterate through all JPanels to determine clicked one  
        for (int x = 0;x<myPanels.length;x++){
        if (e.getX()>myPanels[x].getX()&&e.getX()<(myPanels[x].getX()+myPanels[x].getWidth()))

        {

            if(e.getY()>myPanels[x].getY()&&e.getY()<(myPanels[x].getY()+myPanels[x].getHeight())){
        //Toggle colours    
        if (myPanels[x].getBackground()==Color.blue)
        myPanels[x].setBackground(Color.red);

        else {myPanels[x].setBackground(Color.blue);}
          }
        }
       }
     }



}

person Zippy    schedule 09.07.2013    source источник


Ответы (2)


Слушатель кликов добавляется для JFrame (т. е. окна), поэтому координаты мыши относятся к верхнему левому углу окна, а не к верхнему левому углу сетки.

Если вы хотите выяснить, какой элемент сетки был нажат, может быть проще просто добавить прослушиватели кликов на каждую панель сетки, а не на весь JFrame.

    for (int x = 0;x<myPanels.length;x++){

        myPanels[x]=new JLabel("");
        myPanels[x].setOpaque(true);
        myPanels[x].setBackground(Color.BLUE);
        myPanels[x].setBorder(BorderFactory.createLineBorder(Color.black));
        myPanels[x].addMouseListener(this); // <-- add same listener to each grid
    }

и измените слушателя на

@Override
public void mouseClicked(MouseEvent e) {
    JLabel clickedPanel = (JLabel) e.getSource();

    //Toggle colours    
    if (clickedPanel.getBackground()==Color.blue)
        clickedPanel.setBackground(Color.red);
    else 
        clickedPanel.setBackground(Color.blue);
}
person Samuel    schedule 09.07.2013
comment
Спасибо @Samual - это действительно была проблема, и это объясняет, почему Y был отключен больше, чем X (из-за строки заголовка) - я реализовал ваше решение, и оно отлично работает - ура! :-) - person Zippy; 09.07.2013

Я пытаюсь (на данный момент) создать сетку шириной 25 квадратов, на 12 квадратов вниз и заставить их переключаться между двумя цветами при нажатии (по умолчанию все квадраты синие, а нажатие на один сделает его красным. Еще один щелчок превратит он снова стал синим)

  • используйте JToggleButton.setBackground(Color.Xxx), если JToggleButton.isSelected()

  • добавить последний выбранный в локальную переменную (String),

  • все координаты для предыдущей точки основаны на get/putClientProperty(), затем выполните цикл внутри JComponents из контейнера и проверьте, находится ли String в локальная переменная содержит, если равна

  • кстати то же самое с JPanel, но с JToggleButton проще всего, без добавления Listener, без какой-либо строки кода, тем более, потому что эти два Colors для двух возможных состояний для JToggleButton можно определить в UIManager напрямую

person mKorbel    schedule 09.07.2013