Вопрос по java, swing – paintComponent не работает, если он вызывается рекурсивной функцией?

-5
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 ? In the System.out you can see 10 times "set" and then 2 times "paintComponent". what should I change that after each time set is called it change the "paintComponente" ?

==================================================================================

public class exampe extends JPanel  
{
    int x; 
    int y;

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

        Graphics2D g2 = (Graphics2D) g;
        g2.fillOval(x-2,y-2,4,4);
        System.out.println("paintComponent");        
    }

    public void set(int X, int Y)
    {
        x = X;
        y = Y;
        System.out.println("set");
        super.repaint();
    }

    public static void main(String args[]) 
    {   
        int e=1;

        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);

        for(int i=0; i< 10; ++i)
            ex.set(e+i,e+i);         
    }
}
Ему уже сказалиall этого вcross-post. Hovercraft Full Of Eels
Для лучшей помощи, отправьтеSSCCE. Andrew Thompson
Я описал в своем ответе, почемуrepaint() вы не смогли получить свои очки на экране, пока вы итерируетеList, посколькуrepaint() запросы носят асинхронный характер, следовательно, если уже есть один запрос наrepaint() в очереди, поэтому любой новый запрос будет отклонен Swing, следовательно, вы видите только последнее обновление на вашем экране, чтобы достичь желаемого, вы должны использоватьpaintImmediately() вместоrepaint(). nIcE cOw
использованиеjavax.swing.Timerне использоватьThread.sleep(...), который заморозит ваш графический интерфейс и обязательно даст вам такие результаты :( nIcE cOw

Ваш Ответ

2   ответа
2

1: первая строкаpaintComponent() должен быть вашимsuper.paintComponent()

2: почему вы вызываете super.repaint (), сделайте это простоrepaint()

Твой дроу должен быть таким.

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();
}

попробуй с этим. я надеюсь, что это просто структура, ваш paintComponent () ничего не рисует.

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()`
}

Теперь, когда вашpaintComponent() называется это имеет

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

Где здесь проблема?

EDIT- SWING TIMER

Ваш код был в порядке, но обработка функций намного быстрее, чем обновление графического интерфейса, поэтому вы не смогли увидеть изменения перед вами. Способ, которым вы выполняли вызов thread.sleep () между вызовами функций для замедления его вызова, не был хорошим подходом. Для любой временной привязки используйте свинг-таймер, я изменил код для свинг-таймера.

Использование 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();
    }
}
Информация хороша, но чтобы проголосовать за это, мне нужно подождать 6 часов, так как мой дневной лимит исчерпан :(
В этом коде я вижу set_list, но после него нет paintCoponement. Ты можешь сказать мне, почему? & Lt; & код GT; открытый класс дроу расширяет JPanel {........... @Override public void paintComponent (Graphics g) {super.paintComponent (g); Graphics2D g2 = (Graphics2D) g; System.out.println (& Quot; paintCoponement & Quot;); } public void set_list (LinkedList & lt; point & gt; p) {System.out.println (& quot; set_list & quot;); Очки = р; перекрасить (); } & lt; / code & gt; user1359266
Тогда нам нужно больше кода, как сказал Андрей, опубликоватьSSCCE.
@nIcEcOw lol ...
Это ничего не меняет. Я делаю печать в set_list и в paintComponent я вижу печать в set_list, но не в paintComponent, что мне делать? user1359266
6

*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.

Попробуйте это и спросите, что вам не понятно:

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);        
    }
}

Вот код, который позволит вам взглянуть на ваши точки во время итерации внутри цикла for, хотя этот подход крайне нежелателен, поскольку многие недостатки связаны с ним. Хотя попробуйте это вместо звонкаrepaint() вызовнемедленно закрасить (int ...) или женемедленно покрасить (прямоугольник)

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);         
    }
}
@nIcE COw не могу вспомнить, но я думаю, чтоpaintImmediately(x, y, getWidth(), getHeight()); должно быть сделано на EDT, +1
нет, у меня последний вопрос, я могу поместить новое значение в actionPerformed, но если вы хотите, чтобы набор for (int i = 0; i & lt; 10; ++ i) (temp + 10 * i, temp + 10 * я); и увидеть каждую точку user1359266
Подождите, пожалуйста, дайте мне 15 минут :-)
@mKorbel: Вы так правы насчет EDT, так косвенно, что этот звонок - EDT, мой главный вызовcreateAndDisplayGUI() и в том, что у меня было это для вызова циклаset()так что это на EDT :-)
@ user1359266 Вы все еще застряли на своемfor петля. почему вы не понимаете, вам нужно дать время для обновления GUI. Цикл for будет обрабатываться очень быстро, т. Е. У вас был thread.sleep (), использование thread.sleep не очень хороший подход, поэтому мы сказали вам использоватьswing.timer, it is used to do regular gui updation, Теперь снова вы хотите для! у тебя намного лучшеswing.timer, в вашем цикле for вы передаете set () новое значение каждый раз, делаете что-то подобное вactionPerformed(), у вас есть temp = 0, возьмите i = 0. тогда позвони вactionPerformed set(temp+10*i,temp+10*i); и увеличить i.

Похожие вопросы