2015-10-04 5 views
1

Я пытаюсь закодировать простое Java-приложение, которое в основном предназначено для демонстрации, но по какой-то причине это не сработает. Основная его функция заключается в том, чтобы в основном отслеживать движения мыши и рисовать окно везде, где находится мышь. Я уже работал над некоторым кодом, и это то, что у меня есть. Я делаю что-то неправильно?Рисование видимых JComponents на MouseEvent

Это основной класс

package peter; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.MouseInfo; 
import java.awt.Rectangle; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Frame extends JPanel implements MouseMotionListener { 

    private final static JFrame window = new JFrame(); 

    public Frame(){ 
     addMouseMotionListener(this); 
     setPreferredSize(new Dimension(450, 450)); 
     setBackground(Color.GREEN); 
    } 

    private static int mouseX; 
    private static int mouseY; 
    public static void main(String[] args){ 
     //Create and set up the window. 
     JFrame frame = new JFrame("MouseMotionEventDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     JComponent newContentPane = new Frame(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 
    @Override 
    public void mouseDragged(MouseEvent e) 
    { 
     ; 
    } 
    @Override 
    public void mouseMoved(MouseEvent e) 
    { 
     JComponent P = new Paintings(); 
     window.add(P); 
     System.out.println("Mouse moved"); 
    } 

    public static int getMouseY() 
    { 
     return MouseInfo.getPointerInfo().getLocation().y; 
    } 
    public static int getMouseX() 
    { 
     return MouseInfo.getPointerInfo().getLocation().x; 
    } 

    public static Rectangle rectOnMouse() 
    { 
     Rectangle rect = new Rectangle(getMouseX(), getMouseY(), 10,10);  
     return rect; 
    } 
} 

Это класс картины

package peter; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import javax.swing.JComponent; 

public class Paintings extends JComponent{ 

    public void paintComponent(Graphics g) 
    { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.draw(Frame.rectOnMouse()); 
    } 
} 
+0

Ваш 'getMouseX()' возвращает 'y'. – leeor

+0

Я обновил код, чтобы исправить это. Спасибо за ваш ввод –

+0

Прочитайте учебники, поскольку вы делаете много неправильных предположений. За одно ваше повторное создание и добавление объектов Paint неправильно. Зачем создавать компоненты повторно? –

ответ

4

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

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class SimpleDraw extends JPanel { 
    private static final int PREF_W = 450; 
    private static final int PREF_H = PREF_W; 
    private static final Dimension RECT_DIM = new Dimension(10, 10); 
    private Rectangle rect = null; 

    public SimpleDraw() { 
     addMouseMotionListener(new MyMouse()); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     if (rect != null) { 
      g2.draw(rect); 
     } 
    } 

    // so this JPanel's is sized correctly 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class MyMouse extends MouseAdapter { 

     @Override 
     public void mouseMoved(MouseEvent e) { 
      // simply change the Rectangle 
      rect = new Rectangle(e.getPoint(), RECT_DIM); 
      repaint(); // and have the JVM re-paint this JPanel 
     } 
    } 

    private static void createAndShowGui() { 
     SimpleDraw mainPanel = new SimpleDraw(); 

     JFrame frame = new JFrame("SimpleDraw"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     // initialize our GUI on the Swing event thread 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGui(); 
      } 
     }); 
    } 
} 

Для более качание чертежа:

Другие проблемы с вашим кодом :

  • Вы хотите, чтобы ваши классы классов, например Frame, реализовали интерфейсы вашего слушателя, поскольку это может стать беспорядочным и не масштабируется.
  • Вы слишком сильно полагаетесь на статические методы, и, делая это, теряете преимущества ООП, в основном способность ООП помочь уменьшить сложность.
  • Снова ваш метод mouseMoved создает новые компоненты Paintings и непрерывно добавляет их в JFrame. Это не только необязательно, но и вредно, поскольку новые компоненты будут областями ресурсов и памяти, и до тех пор будут закрывать что-либо на JPrame contentPane, включая экземпляр Frame, у которого есть MouseMotionListener. Вы хотите добавить один компонент, являющийся компонентом чертежа, в окно верхнего уровня и добавить его только один раз, здесь, в моем коде, это экземпляр моего класса SimpleDraw. Метод mouseMoved должен быть предназначен для перемещения логического объекта, в моем коде, называемом rect, а затем для вызова repaint().
+0

Спасибо за всю эту информацию! Я очень ценю это! –

0

Я думаю, что вы также должны вызвать метод перекрасить() на какой-либо компонента после каждого обновления. Кроме того, вам нужно только добавить метод рисования один раз. То, что вы хотите сделать, это просто вызвать его из прослушивателя мыши. Создайте P и добавьте его в окно во время основной функции.
Звоните P.repaint(); от слушателя мыши. Прочтите документацию оракула на paintComponent() и MouseListeners.

+0

Я пробовал это, и это не сработало, никаких других предложений? –

+0

Этот ответ упрощает ваши проблемы и не затрагивает ваш ошибочный MouseMotionListener. –

Смежные вопросы