Home > Back-end >  I want to redraw my oval as the mouse enters it
I want to redraw my oval as the mouse enters it

Time:06-16

public void mouseEntered(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        m_View = new View(m_Mod);
        int maxY = m_Mod.y1   m_Mod.oheight;
        int maxX = m_Mod.x1   m_Mod.owidth;
        if (x > m_Mod.x1 & x < maxX & y > m_Mod.y1 & x < maxY) {
            Graphics g = m_Mod.frame.getGraphics();
            m_View.draw(g);
            System.out.print("IM KREIS");
        }
    }

Somehow my math does not work here. I want to redraw my oval as soon as the mouse enters it. So my graphics object "g" is my oval here. m_Mod.x1 / M_Mod.y1 is x and y of my oval and m_Mod.width / m_Mod.heigth are width and heigth of my oval.

CodePudding user response:

As mentioned in comments, the key to a solution is to:

  • Do all drawing, all graphics and mouse listening within a single drawing JPanel
  • To specifically draw within the JPanel's paintComponent method override
  • To give your GUI a boolean field that is set to true
  • To use an Ellipse2D object to define your oval
  • To add a MouseMotionListener to the drawing JPanel
  • Within this MouseMotionListener, check if the mouse point is within the ellipse
  • Then set the boolean field with this result and call repaint()
  • The paintComponent method will then determine what to draw based on the state of the boolean

For example, in the code below I have an Ellise2D field,

private Ellipse2D myOval = new Ellipse2D.Double(OVAL_X, OVAL_Y, OVAL_W, OVAL_H);

Then there is a boolean field, private boolean insideOval = false; that is set to false and that is changed within a MouseMotionListener to true if the mouse point is within the ellpise (here called myOval):

addMouseMotionListener(new MouseAdapter() {         
    @Override
    public void mouseMoved(MouseEvent e) {
        
        // true if the mouse point is within the oval. Otherwise false
        insideOval = myOval.contains(e.getPoint());
        
        // redraw the JPanel to draw the state of insideOval
        repaint();
    }
});

Then the paintComponent method will use the state of insideOval to determine what color to fill the oval with, an "active color" if the boolean is true and a clear color if not:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g); // does house-keeping drawing
    Graphics2D g2 = (Graphics2D)g;
    // allow for smooth curves
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    // vary the oval fill color depending on the state of the insideOval field
    Color c = insideOval ? ACTIVE_COLOR : INACTIVE_COLOR;
    g2.setColor(c);
    
    // fill the oval
    g2.fill(myOval);
    
    // then draw the oval's border
    g2.setColor(OVAL_BORDER);
    g2.setStroke(BORDER_STROKE);
    g2.draw(myOval);
}

For example:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class DrawingPanel extends JPanel {
    // main JPanel dimensions
    private static final int PREF_W = 600;
    private static final int PREF_H = 600;
    
    // oval dimensions
    private static final double OVAL_X = 100;
    private static final double OVAL_Y = OVAL_X;
    private static final double OVAL_W = 400;
    private static final double OVAL_H = OVAL_W;
    
    // oval colors
    private static final Color INACTIVE_COLOR = new Color(0, 0, 0, 0); // clear
    private static final Color ACTIVE_COLOR = Color.PINK;
    private static final Color OVAL_BORDER = Color.LIGHT_GRAY;
    
    // thickness of mouse border
    private static final Stroke BORDER_STROKE = new BasicStroke(4f);
    
    // Oval to draw and boolean to tell if mouse within the oval
    private Ellipse2D myOval = new Ellipse2D.Double(OVAL_X, OVAL_Y, OVAL_W, OVAL_H);
    private boolean insideOval = false;
    
    public DrawingPanel() {
        // add a mouse motion listener to this same drawing JPanel
        // and inside of it, check if the mouse point is inside or outside
        // of the oval.
        addMouseMotionListener(new MouseAdapter() {         
            @Override
            public void mouseMoved(MouseEvent e) {
                
                // true if the mouse point is within the oval. Otherwise false
                insideOval = myOval.contains(e.getPoint());
                
                // redraw the JPanel to draw the state of insideOval
                repaint();
            }
        });
    }
    
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return getPreferredSize();
        } else {
            return new Dimension(PREF_W, PREF_H);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // does house-keeping drawing
        Graphics2D g2 = (Graphics2D)g;
        // allow for smooth curves
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        // vary the oval fill color depending on the state of the insideOval field
        Color c = insideOval ? ACTIVE_COLOR : INACTIVE_COLOR;
        g2.setColor(c);
        
        // fill the oval
        g2.fill(myOval);
        
        // then draw the oval's border
        g2.setColor(OVAL_BORDER);
        g2.setStroke(BORDER_STROKE);
        g2.draw(myOval);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            DrawingPanel mainPanel = new DrawingPanel();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}
  • Related