How to change Graphics2d objects off paintComponent

Asked

Viewed 220 times

2

I wonder how to change the color of a drawRectangle() of Graphics2d java, out of the way @Override paintComponent().

It turns out that this change should be temporary, only when the mouse pointer passes over the drawn area and when it leaves that area, it should return to the default color of the drawing. In the algorithm I used, I can’t change the color of the rectangle the way I described it. If you wish to attempt to recompile my code, it may be easier to understand the problem.

package desenhoteste;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class DesenhoTeste extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    protected int xi;
    protected int xf;
    protected int yi;
    protected int yf;
    public Graphics2D g1;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    DesenhoTeste frame = new DesenhoTeste();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public DesenhoTeste() {
        setTitle("Desenho Teste");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel areaDeEdicao = new AlteraGrafico();
        contentPane.add(areaDeEdicao, BorderLayout.CENTER);
        areaDeEdicao.setLayout(null);

        addMouseMotionListener(new MouseMotionListener() {
            // MouseMotionListener
            @Override
            public void mouseMoved(MouseEvent e) {
                // Essas coordenadas, que são as mesmas do metodo drawRectangle, servem para simular uma área sensível em areaDeEdicao
                xi = 150;
                xf = 250;
                yi = 150;
                yf = 250;
                // Esse teste verifica se os valores de x e y, captados do mouse, estão dentro das coordenadas do retângulo, ou seja,
                // se e.getX() E e.getY() estão entre xi e xy; que equivale a: xi <= e.getX() <= xf ao mesmo tempo que yi <= e.getY() <= yf.
                while ((xi <= e.getX() && e.getX() <= xf) && (yi <= e.getY() && e.getY() <= yf)) {
                    // Uma tentativa de mudar o valor do campo g1 fora do metodo override paintComponent.
                    g1.setColor(Color.RED);
                    areaDeEdicao.repaint();
                    // System.out.println verifica se o while está funcionando, monitorando os valores de e.getX() E e.getY().
                    System.out.println("Mouse passou dentro do retângulo: " + "e.getXd(): " + e.getX() + " " + "e.getY(): " + e.getY());
                    break;
                }
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                // TODO Auto-generated method stub  
            }
        });
    }

    public class AlteraGrafico extends JPanel {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        // Override gerado pelo atalho ctrl + space e clicando em paintComponent 
        @Override
        protected void paintComponent(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponent(g);
            g1 = (Graphics2D) g;
            g1.drawRect(150, 150, 100, 100);
        }
    }
}

1 answer

1


It turns out that the method paintComponent is responsible for rendering the component on the screen, you have to leave the part of drawing logic always within this method.

What I did was delegate Listener from mouse movement to JPanel, since the drawing lies on it, and when the mouse moves inside this panel, I capture the current pointer coordinates.

The method paintComponent is called constantly within the swing thread, so I played the validation of the mouse’s position into it, and whenever the mouse moves within the coordinates that the if validates, the rectangle will have its background color changed to red because of the repaint() within the method mouseMoved, and when the mouse leaves these coordinates, return to normal color, as the area will be redrawn with default values and will not enter this if.

See the updated code:

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class DesenhoTeste extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    DesenhoTeste frame = new DesenhoTeste();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public DesenhoTeste() {
        setTitle("Desenho Teste");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel areaDeEdicao = new AlteraGrafico();
        contentPane.add(areaDeEdicao, BorderLayout.CENTER);
        areaDeEdicao.setLayout(null);
    }

    public class AlteraGrafico extends JPanel implements MouseMotionListener {

        protected int xi;
        protected int xf;
        protected int yi;
        protected int yf;
        //estas variaveis guardam as coordenadas atuais quando o 
        // mouse mover por sobre este componente
        private int mX, mY;
        private static final long serialVersionUID = 1L;

        public AlteraGrafico() {
            xi = 150;
            xf = 250;
            yi = 150;
            yf = 250;
            addMouseMotionListener(this);
        }

        @Override
        protected void paintComponent(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponent(g);
            Graphics2D g1 = (Graphics2D) g;
            g1.drawRect(150, 150, 100, 100);

            if ((xi <= mX && mX <= xf) && (yi <= mY && mY <= yf)) {
                g1.setColor(Color.red);
                g1.fillRect(150, 150, 100, 100);
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {

        }

        @Override
        public void mouseMoved(MouseEvent e) {

            mX = e.getX();
            mY = e.getY();
           repaint();
        }
    }
}
  • diegofm, thanks for your help!

  • @Did Phrank work? If yes, you can accept the answer by clicking on v the left. Thus it will serve as an example for other people with similar problem :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.