paintComponent does not work if its called by the recursive function?

前端 未结 2 1558
后悔当初
后悔当初 2020-11-27 23:54
  1. I want to see all the Points one after another but I see only able to see 1 point. What shold I change to see all the Points ?
  2. In the
相关标签:
2条回答
  • 2020-11-28 00:25

    *SIMPLE EXPLANATION AS TO WHY YOU COULD ONLY SEE THE LAST UPDATE : *

    A quote taken from Filthy Rich Clients by Chet Haase and Romain Guy

    It is important to note that repaint requests get “coalesced,” or combined. 
    So, for example, if you request a repaint and there is already one on the 
    queue that has not yet been serviced, then the second request is ignored 
    because your request for a repaint will already be fulfilled by the earlier 
    request. This behavior is particularly helpful in situations where many
    repaint requests are being generated, perhaps by very different situations 
    and components, and Swing should avoid processing redundant requests and 
    wasting effort.
    

    Try your hands on this, and ask what is not clear to you :

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    public class PointsExample
    {   
        private CustomPanel contentPane;
        private Timer timer;
        private int x = 1;
        private int y = 1;
        private ActionListener timerAction = new ActionListener()
        {   
            public void actionPerformed(ActionEvent ae)
            {
                contentPane.set(x, y);
                x++;
                y++;
                if (x == 450)
                    timer.stop();
            }
        };
        /*
         * This is just JFrame, that we be 
         * using as the Base for our Application.
         * Though here we are calling our
         * JPanel (CustomPanel), whose
         * paintComponent(...) method, we had
         * override.
         */
        private void createAndDisplayGUI()
        {
            JFrame frame = new JFrame("Locate Mouse Position");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            contentPane = new CustomPanel();
            frame.setContentPane(contentPane);  
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
            timer = new Timer(100, timerAction);
            timer.start();
        }
    
        public static void main(String\u005B\u005D args)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    new PointsExample().createAndDisplayGUI();
                }
            });
        }
    }
    
    class CustomPanel extends JComponent
    {
        private int x;
        private int y;
    
        public void set(int a, int b)
        {
            x = a;
            y = b;
            repaint();
        }   
    
        @Override
        public Dimension getPreferredSize()
        {
            return (new Dimension(500, 500));
        }
    
        @Override
        public void paintComponent(Graphics g)
        { 
            g.clearRect(0, 0, getWidth(), getHeight());
            Graphics2D g2 =(Graphics2D) g;
            g2.fillOval(x, y, 4, 4);        
        }
    }
    

    Here is the code, that will allow you to have a look at your points while iterating inside a for loop, though this approach is highly discouraged, for many cons associated with it. Though try your hands on this instead of calling repaint() call paintImmediately(int ...) or paintImmediately(Rectangle rect)

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    public class PointsExample
    {   
        private CustomPanel contentPane;
        private Timer timer;
        private int x = 1;
        private int y = 1;
    
        /*
         * This is just JFrame, that we be 
         * using as the Base for our Application.
         * Though here we are calling our
         * JPanel (CustomPanel), whose
         * paintComponent(...) method, we had
         * override.
         */
        private void createAndDisplayGUI()
        {
            JFrame frame = new JFrame("Locate Mouse Position");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            contentPane = new CustomPanel();
            frame.setContentPane(contentPane);  
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
    
            for (int i = 0; i < 500; i++)
            {
                contentPane.set(x, y);
                x++;
                y++;
                if (x == 450)
                    break;
            }
        }
    
        public static void main(String\u005B\u005D args)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    new PointsExample().createAndDisplayGUI();
                }
            });
        }
    }
    
    class CustomPanel extends JComponent
    {
        private int x;
        private int y;
    
        public void set(int a, int b)
        {
            x = a;
            y = b;
            paintImmediately(0, 0, getWidth(), getHeight());
    
        }   
    
        @Override
        public Dimension getPreferredSize()
        {
            return (new Dimension(500, 500));
        }
    
        @Override
        public void paintComponent(Graphics g)
        { 
            super.paintComponent(g);
            g.fillOval(x, y, 4, 4);         
        }
    }
    
    0 讨论(0)
  • 2020-11-28 00:34

    1: first line of paintComponent() should be your super.paintComponent()

    2: why are you calling super.repaint(), make it simply repaint()

    Your Drow should be like this.

    public class drow extends JPanel {
     ...........
    @Override
    public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 =(Graphics2D) g;
    
    }
    public void set_list(LinkedList <point> p){
    Points =p;     
    repaint();
    }
    

    try with this. i hope this is simply a structure, your paintComponent() isn't drawing anything.

    EDIT

    public void set_list(LinkedList <point> p){
    Points =p;     
    System.out.println("set_ist");// 1:First this line will be displayed then..
    repaint();//2: Then this is called, which in turn calls your `paintComponent()`
    }
    

    Now when your paintComponent() is called it has

    system.out.println("paintComponent");
    //3: so now this will be displayed.
    

    Where is the problem here?

    EDIT- SWING TIMER

    Your code was ok, but the function processing is way faster than GUI updation, thats why you were unable to see the changes in front of you. The way you were doing, of calling thread.sleep() between function calls to slow down it's call, was not a good approach. For any timing thing's in swing, use swing timer, i changed your code for swing timer.

    Using Swing Timer:

    public class exampe extends JPanel implements ActionListener {
    
        int x;
        int y;
        int temp = 0;
    
        public void paintComponent(Graphics g) {
    
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.fillOval(x - 2, y - 2, 4, 4);
        }
    
        public void set(int X, int Y) {
    
            x = X;
            y = Y;
        }
    
        public static void main(String args[]) {
    
            JFrame frame = new JFrame("TEST");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            exampe ex = new exampe();
            JScrollPane scroll = new JScrollPane(ex);
            frame.getContentPane().add(scroll);
            frame.setSize(400, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            Timer PointTimer = new Timer(1000, ex);
            PointTimer.setInitialDelay(1000);
            PointTimer.start();
            System.out.println("started");
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
    
           // set(rand.nextInt(350), rand.nextInt(350));
              set(temp+10,temp+10);
              temp=temp+2;
              repaint();
        }
    }
    
    0 讨论(0)
提交回复
热议问题