简体   繁体   English

没有使用mouseMoved()调用PaintComponent()方法

[英]PaintComponent() method not being called with mouseMoved()

I am trying to write a program that allows the user to create squares or circles by clicking on a JButton in a window, and then by clicking somewhere in the window (not on the button). 我正在尝试编写一个程序,该程序允许用户通过单击窗口中的JButton,然后单击窗口中的某个位置(而不是按钮)来创建正方形或圆形。

I currently am using two actionListeners for the different buttons that add a Square or Circle to an arrayList of type Shape (an interface that both square and circle implement). 我目前正在为两个不同的按钮使用两个actionListeners,这些按钮将Square或Circle添加到Shape类型的一个arrayList(正方形和圆形都实现的接口)上。 I have a class called frameListener which implements MouseListener and MouseMotionListener, which updates the location of the square or circle when the mouse is moved, deletes the square or circle if the mouse leaves the window, or stops updating it when the mouse is clicked (making it permanent). 我有一个叫做frameListener的类,该类实现了MouseListener和MouseMotionListener,它们在移动鼠标时更新正方形或圆形的位置,如果鼠标离开窗口则删除正方形或圆形,或者在单击鼠标时停止更新(制作它永久)。

I also have a class called MyPanel, which extends JPanel, and uses the paintComponent(Graphics g) method to paint the squares and circles on the background. 我还有一个名为MyPanel的类,该类扩展了JPanel,并使用paintComponent(Graphics g)方法在背景上绘制正方形和圆形。

package smys01;

import java.util.ArrayList;
import java.text.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;




public class SMYS01 extends JFrame {

    private Color c = new Color(0, 0, 0);
    private static ArrayList<Shape> shapes = new ArrayList();
    private static ArrayList<Shape> deleted = new ArrayList();

    private Point a;
    private boolean makeSquare = false, makeCircle = false, makeSquiggle = false;

    public static void main(String[] args) {
        SMYS01 window = new SMYS01();

    }
    //good main

    //0 is empty for making things, 1 is having a square selected to change, 2 is background;

    private JButton makeSquareB = new JButton("New Square" /*, add icon later*/);

    private JButton makeCircleB = new JButton("New Circle");

    private Color background = new Color(0, 150, 0);



    public SMYS01() {
        makeSquareB.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("making square");
                if(!makeCircle&&!makeSquare){
                    makeSquare = true;

                    shapes.ensureCapacity(shapes.size());
                    shapes.add(new Square((int) a.getX(), (int) a.getY(), c));
                }else if(makeSquare){

                }else if(makeCircle){
                    makeCircle=false;
                    makeSquare=true;
                    shapes.remove(shapes.size()-1);
                    shapes.ensureCapacity(shapes.size());
                    shapes.add(new Square((int) a.getX(), (int) a.getY(), c));
                }
            }
        });


        makeCircleB.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("making circle");
                if(!makeCircle&&!makeSquare){
                    makeCircle = true;
                    shapes.ensureCapacity(shapes.size());
                    shapes.add(new Circle((int) a.getX(), (int) a.getY(), c));
                }else if(makeCircle){

                }else if(makeSquare){
                    makeSquare=false;
                    shapes.remove(shapes.size()-1);
                    shapes.ensureCapacity(shapes.size());
                    shapes.add(new Circle((int) a.getX(), (int) a.getY(), c));
                }
            }
        });
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane();
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        MyPanel thing = new MyPanel();


        frame.addMouseListener(new FrameListener());
        frame.setContentPane(thing);

        frame.setSize(thing.getPreferredSize());

        frame.setTitle("Art!");

        frame.addMouseMotionListener(new FrameListener());
    }


    private class MyPanel extends JPanel {

        public MyPanel() {

            GroupLayout layout = new GroupLayout(this);
            layout.setHorizontalGroup(
                    layout.createSequentialGroup()
                    .addComponent(makeCircleB)
                    .addComponent(makeSquareB)
            );
            layout.setVerticalGroup(
                    layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                            .addComponent(makeCircleB)
                            .addComponent(makeSquareB)
                    )
            );

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(background);
            g.drawRect((int)g.getClipBounds().getX(),(int)g.getClipBounds().getY(),(int)g.getClipBounds().getWidth(),(int)g.getClipBounds().getHeight());
            g.fillRect((int)g.getClipBounds().getX(),(int)g.getClipBounds().getY(),(int)g.getClipBounds().getWidth(),(int)g.getClipBounds().getHeight());


            System.out.println(shapes.size());
            for (Shape i : shapes) {

                int[] a = i.getDim();
                g.setColor(new Color(a[4], a[5], a[6], a[7]));

                if(i instanceof Square){
                    g.drawRect(a[0], a[1], a[2], a[3]);
                    g.fillRect(a[0], a[1], a[2], a[3]);
                }else if(i instanceof Circle){
                    g.drawOval(a[0], a[1], a[2], a[3]);
                    g.fillOval(a[0], a[1], a[2], a[3]);
                }

            }

        }
    }


    class FrameListener implements MouseListener, MouseMotionListener {


        public void mousePressed(MouseEvent e) {
            System.out.println("pressed");
            a = new Point(e.getPoint());
            if (makeSquare) {
                makeSquare = false;
                System.out.println("square made!");
            }
            if (makeCircle) {
                makeCircle = false;
                System.out.println("cirlce made!");
            }

            //use this for sliders, nothing else. 

        }

        public void mouseReleased(MouseEvent e) {
            System.out.println("released");
            a = new Point(e.getPoint());
            //use for sliders, nothing else.

        }

        public void mouseClicked(MouseEvent e) {
            System.out.println("clicked");
            a = new Point(e.getPoint());
            //don't need this
            //makeSquare = false;
            //makeCircle = false;

            //makeSquiggle too.
        }

        public void mouseMoved(MouseEvent e) {

            //showing up as false atm
            a = new Point(e.getPoint());
            System.out.println(a);
            if (makeSquare||makeCircle) {
                Shape b = shapes.get(shapes.size()-1);
                b.updateLocation((int) a.getX(), (int) a.getY());

            }


        }

        public void mouseDragged(MouseEvent e) {
            //only check if over a JSlider
        }

        //complete methods:
        public void mouseEntered(MouseEvent e) {
            System.out.println("entered");
            //nothing, Mouse re-entering doesn't effect the program. 
        }

        public void mouseExited(MouseEvent e) {
            System.out.println("exited");
            makeSquare = false;
            makeCircle = false;
            makeSquiggle = false;
            //if mouse leaves the window while trying to make one of these, stop it. 

        }
    }



}

code for the Shape interface: Shape接口的代码:

package smys01;

public interface Shape {
    public void updateLocation(int newXPos, int newYPos);
    public void updateDimensions(int newXDim, int newYDim);
    public void delete();
    public void purge();
    public void restore();
    public int[] getDim();
}

Code for Square: Note! 正方形代码:注意! this code was written a bit back, and has some parts that are not relevant at all or even complete (but are completely unused). 这段代码写得有点回溯,其中有些部分根本不相关,甚至不完整(但完全没有使用)。 This is for the constructor, updateDimensions() method, and the updateLocation() method 这是用于构造函数,updateDimensions()方法和updateLocation()方法的

package smys01;
import java.awt.Color;
public class Square implements Shape{
    //tbr=to be returned.
    boolean deleted=false;
    boolean purged=false;
    private int xPos, yPos, xDim, yDim;
    private int saveXPos, saveYPos, saveXDim, saveYDim, saveR, saveG, saveB, saveA;
    private Color fill;
    public Square(int initX, int initY, Color a){
        xPos=initX;
        yPos=initY;
        xDim=50;
        yDim=50;
        fill=a;
    }
    public void updateDimensions(int newXDim, int newYDim){
        if(purged||deleted)
            return;
        if(newXDim<=2){
            xDim=2;
        }else{
            xDim=newXDim;
        }
        if(newYDim<=2){
            yDim=2;
        }else{
            yDim=newYDim;
        }

    }
    public void updateLocation(int newXPos, int newYPos){
        if(purged){
            return;
        }
        if(newXPos<=5){
            xPos=5;


        }else{
            xPos=newXPos;

        }
        if(newYPos<=25){
            yPos=25;
        }else{
            yPos=newYPos;
        }


                }
        public void delete(){
        if(!deleted){
            saveXPos=xPos;
            saveYPos=yPos;
            saveXDim=xDim;
            saveYDim=yDim;
            saveR=fill.getRed();
            saveB=fill.getBlue();
            saveG=fill.getGreen();
            saveA=fill.getAlpha();
            deleted=true;
            xPos=-5;
            yPos=-5;
            xDim=1;
            yDim=1;
                        }
    }
    public void purge(){
        saveXPos=-10;
        saveYPos=-10;
        saveXDim=3;
        saveYDim=3;
        //use in an if statement, and if true (will be, set the square value to null, so this reference will go away, preventing data overflow
    }
    public void restore(){
        xPos=saveXPos;
        yPos=saveYPos;
        xDim=saveXDim;
        yDim=saveYDim;
        deleted=false;
    }
    public int[] getDim(){
        int[] tbr={xPos,yPos, xDim, yDim,fill.getRed(), fill.getBlue(), fill.getGreen(), fill.getAlpha()};
        return tbr;
    }
    public String toString(){
        String tbr="Square: ("+xPos+", "+yPos+"); ("+xDim+", "+yDim+"); ("+fill.toString();
        return tbr;
    }

}

The code for the Circle class is the exact same, but the object type allows the paintComponent method to distinguish them. Circle类的代码完全相同,但是对象类型允许paintComponent方法区分它们。

I am trying to get this to call paintComponent when mouseMoved is called, however I cannot seem to get it to do this. 我试图让它在调用mouseMoved时调用paintComponent,但是我似乎无法做到这一点。 I have tried using repaint(), and I have looked for a few hours trying to figure this out. 我尝试使用repaint(),并且已经花了几个小时试图弄清楚这一点。

So far, I have seen that, basically, Swing will call paintComponent when it needs to (when window size is changed, or window is minimized and re-opened). 到目前为止,我已经看到,基本上,Swing会在需要时(当更改窗口大小或最小化并重新打开窗口时)调用paintComponent。

However, I am unsure how to call it upon pressing the button or moving the mouse, and repaint() won't work for this. 但是,我不确定如何在按下按钮或移动鼠标时调用它,并且repaint()对此无效。

I apologize if some of the code is sloppy, I have rewritten it a few times, and some parts are unnecessary but still there. 如果某些代码草率,我已经道歉,我已经重写了几次,有些部分是不必要的,但仍然存在。

Is there a way to actively call the paintComponent method from within the anonymous action classes or the FrameListener class? 有没有办法从匿名操作类或FrameListener类中主动调用paintComponent方法?

After some input from @MadProgrammer, I figured out what was not working. 从@MadProgrammer输入一些信息后,我弄清楚了什么不起作用。 The mouseListener was attached to the JFrame rather than the JPanel, so the events were being triggered, but paintComponent (by repaint()) was not. mouseListener被附加到JFrame而不是JPanel上,因此事件被触发了,但是paintComponent(由repaint())没有被触发。 I added it to the panel and added repaint() to the end of the mouseMoved() method, and it is working perfectly. 我将其添加到面板中,并在mouseMoved()方法的末尾添加了repaint(),它运行良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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