repaint() не работает при вызове из метода слушателя мыши

Я делаю пасьянс как побочный проект, и у меня проблемы с окном, которое я сделал.

В программе у меня есть начало строки в одной точке, которая заканчивается в позиции моего щелчка мыши. Когда я нажимаю на окно, оно успешно читает мои клики и изменяет xcor а также ycor Переменные в моей позиции щелчка мыши, но не может перерисовать линию, используя новые координаты.

public class Game_Play extends JFrame {

public int xcor = 0;
public int ycor = 0;
public void setup() { //sets up JFrame
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());
    frame.addMouseListener(new MouseHandler());
    frame.addMouseMotionListener(new MouseHandler());
    frame.setVisible(true);
}

          //listener and painting subclass
class MouseHandler extends JPanel implements MouseListener, MouseMotionListener {
              //when mouse pressed, the Xcor and Ycor
              //will be changed to the current mouse 
              //x and y cords, then it will call 
              //repaint() to repaint the line using the
              //new Xcor and Ycor locations
    public void mousePressed(MouseEvent me) {
        System.out.println("mouse pressed");
        xcor = me.getX();
        ycor = me.getY();
                  //prints out new cords
        System.out.println(xcor + " xcor");
        System.out.println(ycor + " ycor");
        repaint();
    }

    public void mouseReleased(MouseEvent me) { //tests to make sure listener is working
        System.out.println("mouse released");
    }

    public void mouseClicked(MouseEvent me) {}
    public void mouseEntered(MouseEvent me) {}
    public void mouseMoved(MouseEvent me) {}
    public void mouseExited(MouseEvent me) {}
    public void mouseDragged(MouseEvent me) {}

              //paints the line with the Xcor and Ycor values
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("repaint check"); //test to see if repaint has been called
        g.drawLine(100, 100, xcor, ycor);
    }
}
}

Замечания: repaint() вызывается из MouseListener метод mousePressedЯ также попытался назвать это из разных MouseListener а также MouseMotionListener методы безрезультатны.

Обратите внимание paintComponent метод уведомляет меня, если он был успешно вызван, и когда я нажимаю, paintComponent метод не выполняется.

Примечание: я заметил, что если я нажму на экран, чтобы установить новые шнуры, а затем нажму на кнопку "Развернуть" в окне, он успешно вызовет метод перекраски с перерисованной линией, используя новые шнуры.

Обратите внимание setup() метод вызывается из другого класса в другом файле, код выглядит следующим образом:

public static void main(String[] args) throws IOException {
  deck_Create();
  deck_Shuffle();
  game_setup();
  BufferedImage_array_Setup();
  //being called here
  Game_Play a = new Game_Play();
  a.setup();
  //
}

Последнее примечание: я искал все выше и ниже для решения этой проблемы, только придумывая похожие проблемы, которые мне не помогли. Любая обратная связь с благодарностью.

Если есть какие-либо вопросы, дайте мне знать, и я рассмотрю их для вас в нескольких.

Спасибо!

1 ответ

Решение

Некоторые комментарии к вашему коду:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());// your panel
    frame.addMouseListener(new MouseHandler()); // your listener, also a panel, but not the one you added to your frame
    frame.addMouseMotionListener(new MouseHandler()); // yet another listener, also not the panel you added to your frame
    frame.setVisible(true);
}

Вы, вероятно, хотели написать:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    JPanel p = new MouseHandler();
    frame.add(p);
    frame.addMouseListener(p);
    frame.addMouseMotionListener(p);
    frame.setVisible(true);
}

Обратите внимание, что использование компонентов пользовательского интерфейса для реализации интерфейсов слушателя не очень хорошая идея. Что если вы хотите, чтобы на панели было два слушателя мыши для разных компонентов? Вы не можете иметь обоих слушателей на панели.

Лучший способ состоит в том, чтобы интерфейсы слушателя были реализованы анонимными классами, следуя принципу разделения проблем.

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

И, наконец, вы должны установить панель в качестве панели содержимого, используя setContentPane, Обычно лучше, чтобы панель диктовала, какой должен быть ее размер, переопределив setPreferredSize, В этом случае вам не нужно устанавливать размер содержащего фрейма, скорее вы вызываете pack изменить размер кадра до предпочтительного размера его подкомпонентов.

Другие вопросы по тегам