How to change Graphics2d objects out paintComponent

2

I would like to know how to change the color of a drawRectangle() of Graphics2d of java, outside the @Override paintComponent() method.

It turns out that this change should be temporary, only when the mouse pointer passes over the drawn area, and when you leave that area, it should return to the pattern's default color. In the algorithm I used, I can not change the color of the rectangle in the way I described. If you wish to try 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);
        }
    }
}
    
asked by anonymous 01.03.2017 / 15:56

1 answer

1

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

What I did was to delegate the mouse movement listener to JPanel , since the drawing is in it, and when the mouse moves within this panel, I capture the coordinates of the pointer.

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

See 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();
        }
    }
}
    
01.03.2017 / 17:14