简体   繁体   中英

Java: Calling repaint() in static context (Or how to avoid it)

I am working on a simple app Java/Swing, which involves having the user click on a box and drag it around. I am having troubles with understanding how the repaint method can be used. I created this example of the problem, in which a square is drawn and then on mousePressed it gets the x cordinates of the click, and displaces the original drawing by however much the pointer is moved.

I have read the commonly referred guides on drawing in Swing, but I haven't seen any answers to the question on how to write a program that incorporates both mouseMotion and mouseListener (which as far as I can tell means that the mouseListener must be implemented as its own class, as opposed to the common solution of incorporating it into the custom JPanel class) and also calls repaint() based on mouse actions.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.MouseInputAdapter;


class drawTest extends JPanel {
    static int xpos_square = 200; 
    static int ypos_square = 200; 
    int width = 100;  
    int height = 100;

    static int x_init;
    static int y_init;

    public drawTest(){
        addMouseListener(new mouseListener());
        addMouseMotionListener(new mouseListener());
        setBackground(Color.BLACK); 
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawSquare(g);
    }

    public void drawSquare(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(xpos_square, ypos_square, height, width);            
    }   

    public static void moveShape(int x, int y){
        xpos_square += x-x_init;
        ypos_square += y-y_init;
        repaint();
    }
    public static void getChord(int x, int y){
        x_init = x;
        y_init = y;     
    }
}   

class mouseListener extends MouseInputAdapter{

    public void mousePressed(MouseEvent e){     
        drawTest.getChord(e.getX(),e.getY());
    }   

    public void mouseDragged(MouseEvent e){
        drawTest.moveShape(e.getX(),e.getY());
    }       
}

public class myTest {

    JFrame myFrame = new JFrame();
    JPanel myDrawing = new drawTest();

    public myTest () {
        myFrame.add(myDrawing);
        myFrame.setSize(500,500);
        myFrame.setVisible(true);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }   

    public static void main(String []args){
        new myTest(); 
    }   
}

The issue is of course that repaint() cannot be called in a static context. However, I don't see how I can avoid this, since if I want the position to smoothly update, it has to be called via the mouseDragged method.

How else could I use the repaint() method to redraw based on mouse movements?

So I figured out a way around it, using anonymous methods in addMouseListener. This bypasses the need for static methods in the call to repaint. If anyone else has a similar question, maybe they will find it helpful.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.MouseInputAdapter;


class DrawTest extends JPanel {
    static int xpos_square = 200; 
    static int ypos_square = 200; 
    int width = 100;  
    int height = 100;

    static int x_init;
    static int y_init;

    public DrawTest(){
        addMouseListener(new mouseListener(){   public void mousePressed(MouseEvent e){     
            getClick(e.getX(),e.getY());
        }});
        addMouseMotionListener(new mouseListener(){ public void mouseDragged(MouseEvent e){
            moveShape(e.getX(),e.getY());   
        }});
        setBackground(Color.BLACK); 
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawSquare(g);
    }

    public void drawSquare(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(xpos_square, ypos_square, height, width);            
    }   

    public void moveShape(int x, int y){
        if((x >= xpos_square)&&(x <= xpos_square + width)&&(y >= ypos_square)&&(y <= ypos_square + height)){
            xpos_square += x-x_init;
            ypos_square += y-y_init;
            x_init = x;
            y_init = y; 
            repaint();
        }
    }
    public void getClick(int x, int y){
        x_init = x;
        y_init = y;     
    }
}

public class MyTest {

    JFrame myFrame = new JFrame();
    JPanel myDrawing = new DrawTest();

    public MyTest () {
        myFrame.add(myDrawing);
        myFrame.setSize(500,500);
        myFrame.setVisible(true);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }   

    public static void main(String []args){
        new MyTest(); 
    }   
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM