Como adicionar uma auto-definida MouseMotionListener para um JPanel?

0

Pergunta

Eu escrevi uma MouseMotionListener para JPanel, mas eu fico confuso sobre como usá-lo.

O ouvinte classe funciona bem quando adicionado ao quadro usando aWindow.add(new MouseMotionEvents()), mas quando eu tento adicioná-lo ao painel usando content.add(new MouseMotionEvents()), ele não funciona. Eu sou novo para Balanço e JComponents, alguém poderia me dar algumas dicas?

public class test {

  public static void main(String[] args) {
    JFrame aWindow = new JFrame();
    aWindow.setBounds(600, 600, 600, 600);
    aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel content = new JPanel();
    content.add(new MouseMotionEvents());
    aWindow.add(content);
    
    aWindow.setVisible(true);
  }
}

class MouseMotionEvents extends JPanel implements MouseListener,
    MouseMotionListener {
  Point p;
  Point r;

  public MouseMotionEvents() {
    addMouseListener(this);
    addMouseMotionListener(this);
  }

  public void mouseClicked(MouseEvent me) {
    // p = me.getPoint();
    // repaint();
  }

  public void mouseEntered(MouseEvent me) {
  }

  public void mouseExited(MouseEvent me) {
  }

  public void mousePressed(MouseEvent me) {
    p = me.getPoint();
    // repaint();
  }

  public void mouseReleased(MouseEvent me) {
    r = me.getPoint();
    repaint();
  }

  public void mouseDragged(MouseEvent me) {
    r = me.getPoint();
    repaint();
  }

  public void mouseMoved(MouseEvent me) {
  }

  public void paint(Graphics g) {
    if (p != null && r != null) {
      Dimension d = getSize();
      int xc = d.width / 2;
      int yc = d.height / 2;
      if(p.getX()-r.getX()>0 && p.getY()-r.getY()>0){
        g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(p.getY()-r.getY()));
      }
      if(p.getX()-r.getX()>0 && p.getY()-r.getY()<0){
        g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(-p.getY()+r.getY()));
      }
      if(p.getX()-r.getX()<0 && p.getY()-r.getY()>0){
        g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(p.getY()-r.getY()));
      }
      if(p.getX()-r.getX()<0 && p.getY()-r.getY()<0){
        g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(-p.getY()+r.getY()));
      }
      
    }
  }
}
java jframe jpanel mousemotionlistener
2021-11-24 06:06:46
2

Melhor resposta

3

No código a sua pergunta, você está adicionando um JPanel para um JPanel desde MouseMotionEvents é um JPanel (uma vez que estende a classe JPanel). O padrão de layout manager para JPanel é FlowLayout que tenta apresentar seus componentes contidos no seu tamanho preferido. Então, quando você executar o GUI, você não pode realmente ver onde MouseMotionEvents aparece. Você pode adicionar uma borda adicionando o seguinte (no construtor da classe MouseMotionEvents)

setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.red));

Agora quando você executar o GUI, ele se parece com isso

original gui

Isto é porque um JPanel tem zero (preferencial) o tamanho, pois o seu tamanho é determinado pelos componentes que ele contém, mas em seu código MouseMotionEvents não contém componentes. Você pode corrigir isso explicitamente a definição de um tamanho preferido. Esta é a forma como ele se encontra após a definição de um adequado tamanho preferido.

preferred size

Agora você pode arrastar o mouse dentro da borda vermelha e retângulos serão sorteados.

Além disso, você deve substituir o método paintComponent e não método paint. Consulte a Realização de Pintura Personalizada.

Aqui está o código.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MouseMotionEvents extends JPanel implements MouseListener, MouseMotionListener {
    Point p;
    Point r;

    public MouseMotionEvents() {
        addMouseListener(this);
        addMouseMotionListener(this);
        setBorder(BorderFactory.createLineBorder(Color.red));
        setPreferredSize(new Dimension(300, 300));
    }

    public void mouseClicked(MouseEvent me) {
        // p = me.getPoint();
        // repaint();
    }

    public void mouseEntered(MouseEvent me) {
    }

    public void mouseExited(MouseEvent me) {
    }

    public void mousePressed(MouseEvent me) {
        System.out.println("mousePressed");
        p = me.getPoint();
        // repaint();
    }

    public void mouseReleased(MouseEvent me) {
        System.out.println("mouseReleased");
        r = me.getPoint();
        repaint();
    }

    public void mouseDragged(MouseEvent me) {
        r = me.getPoint();
        repaint();
    }

    public void mouseMoved(MouseEvent me) {
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (p != null && r != null) {
            Dimension d = getSize();
            int xc = d.width / 2;
            int yc = d.height / 2;
            if (p.x - r.x > 0 && p.y - r.y > 0) {
                g.drawRect(p.x, p.y, (p.x - r.x), (p.y - r.y));
            }
            if (p.x - r.x > 0 && p.y - r.y < 0) {
                g.drawRect(p.x, p.y, (p.x - r.x), (-p.y + r.y));
            }
            if (p.x - r.x < 0 && p.y - r.y > 0) {
                g.drawRect(p.x, p.y, (-p.x + r.x), (p.y - r.y));
            }
            if (p.x - r.x < 0 && p.y - r.y < 0) {
                g.drawRect(p.x, p.y, (-p.x + r.x), (-p.y + r.y));
            }
        }
    }

    public static void main(String[] args) {
        JFrame aWindow = new JFrame();
        aWindow.setBounds(600, 600, 600, 600);
        aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel content = new JPanel();
        content.add(new MouseMotionEvents());
        aWindow.add(content);
        
        aWindow.setVisible(true);
    }
}

Note que x e y são membros públicos da classe Point assim não há necessidade de utilizar métodos getX e getY e, portanto, não há necessidade para a fundição.

Quando você adicionou MouseMotionEvents diretamente para o JFrame foram adição de MouseMotionEvents para um JPanel com BorderLayout e você estava adicionando-lo para o CENTRO. Uma vez que você deu o seu JFrame e tamanho explícito, o BorderLayout a certeza de que o tamanho do MouseMotionEvents tomou-se o máximo de espaço possível no JFrame. Portanto, MouseMotionEvents foi grande o suficiente para que você pode arrastar o mouse dentro dela.

2021-11-24 11:32:14
0

Para adicionar um MouseMotionListener para um JPanel, você tem que usar

myPanel.setMouseMotionListener ( myMouseListener );

e chamar diretamente no seu painel, como você fez no mouseMotionEvents classe. Tht é por isso que ele está trabalhando, quando você adicionar este diretamente para o seu JFrame.

Depois de corrigir o código, eu tenho esse, que deve funcionar perfeitamente bem. Eu divididas em duas classes, uma classe principal com JFrame e um para o JPanel (conteúdo).

Classe principal:

public class MouseMotionListenerTest {
    public static void main ( String[] args ) {
        JFrame aWindow = new JFrame();
        aWindow.setBounds( 600, 600, 600, 600 );
        aWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        ContentPanel content = new ContentPanel();
        aWindow.add( content );

        aWindow.setVisible( true );
    }
}

Painel de classe:

public class ContentPanel extends JPanel {
    private Point p;
    private Point r;

    public ContentPanel () {
        MouseMotionEvents mme = new MouseMotionEvents();
        addMouseListener( mme );
        addMouseMotionListener( mme );
    }

    public void paint ( Graphics g ) {
        if ( p != null && r != null ) {
            Dimension d = getSize();
            int xc = d.width / 2;
            int yc = d.height / 2;
            if ( p.getX() - r.getX() > 0 && p.getY() - r.getY() > 0 ) {
                g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( p.getX() - r.getX() ), ( int ) ( p.getY() - r.getY() ) );
            }
            if ( p.getX() - r.getX() > 0 && p.getY() - r.getY() < 0 ) {
                g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( p.getX() - r.getX() ), ( int ) ( -p.getY() + r.getY() ) );
            }
            if ( p.getX() - r.getX() < 0 && p.getY() - r.getY() > 0 ) {
                g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( -p.getX() + r.getX() ), ( int ) ( p.getY() - r.getY() ) );
            }
            if ( p.getX() - r.getX() < 0 && p.getY() - r.getY() < 0 ) {
                g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( -p.getX() + r.getX() ), ( int ) ( -p.getY() + r.getY() ) );
            }
        }
    }

    private class MouseMotionEvents extends MouseAdapter {
        public void mouseClicked ( MouseEvent me ) {
            // p = me.getPoint();
            // repaint();
        }

        public void mousePressed ( MouseEvent me ) {
            p = me.getPoint();
            // repaint();
        }

        public void mouseReleased ( MouseEvent me ) {
            r = me.getPoint();
            repaint();
        }

        public void mouseDragged ( MouseEvent me ) {
            r = me.getPoint();
            repaint();
        }
    }
}
2021-11-24 16:35:05

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................