Leaving a trace while painting on a transparent JP

2019-03-05 02:43发布

问题:

I am relatively new graphics programmer in Java and here is a simple program I was trying. Here is the full code: broken into 3 classes.

Class 1:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyPanelB extends JPanel
{
 int x=0;
    int y=0;
    public void paintComponent(Graphics g)
    {

    x=x+1;
    y=y+1;

   setOpaque(false);
   //setBackground(Color.cyan);


    g.setColor(Color.red);
    g.fillRect(x,y,x+1,y+1);



    }
}

Class 2:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyFrameB implements ActionListener
{
MyPanelB p1;

    public void go()
    {

    JFrame f1= new JFrame();
    f1.setLocation(150,50);
    f1.setSize(800,700);
    f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel p0= new JPanel();
    p0.setBackground(Color.yellow);
    p0.setLayout(new BorderLayout());
    f1.add(p0);

    p1= new MyPanelB();
    p0.add(p1);

    f1.setVisible(true);

    Timer t = new Timer(200,this);
    t.start();

    }

    public void actionPerformed(ActionEvent ev)
    {

    p1.repaint();


    }
}

Class 3(Main Class):

public class MyBMain
{
    public static void main(String[] args)
    {

    MyFrameB m1= new MyFrameB();
    m1.go();

    }
}

If I comment out the staement setOpaque(false); in class 1, I get a trace(of red expanding rectangles) but not a yellow background. Otherwise I do not get a trace, but I do get a yellow background. I want both the yellow background and the trace. Please feel free to modify my code so that I get both a trace and a yellow background. I provided the full code so one can easily check out the output.

回答1:

Basically you need to repaint the entire component every time the paintComponent() method is called. This means you need to start from 0 and iterate up to the current value of x.

So your paintComponent() method should look something like:

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

    x=x+1;
    y=y+1;

    for    (int i = 0; i < x; i++)
    {

        g.setColor(getForeground());
        //g.fillRect(x,y,x+1,y+1);
        g.fillRect(i,i,i+1,i+1);
    }
}

This means you don't need your panel0. I also change the code for creating panel1:

p1= new MyPanelB();
p1.setForeground(Color.RED);
p1.setBackground(Color.YELLOW);
f1.add(p1);

Even this code I posted for you is not correct. The x/y values should NOT be updated in the paintComponent() method. Try resizing the frame while your code is executing to see why?

Your ActionListener should invoke a method in your panel1 class to update property of the class to tell the paintComponent() how many times to iterate and paint the square when it is invoked. The the paintComponent() method should reference this property in the loop that I created.