Таймер качания и рисование на холсте - PullRequest
0 голосов
/ 05 февраля 2020

Привет, я хочу спросить о таймере свинга и холсте. Я делаю простую анимацию для изменения цвета объектов. Я сделал это с Thread.sleep, но JFrame не отвечал при перерисовке, поэтому я изменил его на Swing Timer. Но теперь, когда я запускаю анимацию, таймер ничего не делает, но объекты на холсте не меняют цвет. Вот моя функция, чтобы оживить изменение цвета, я использую его в overide, функция рисования canvas

    private void paintSearch(Vector<NodeGraph2D> vector,Graphics graphics2D) {
    if (!vector.isEmpty()) {
        final int[] k = {0};
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (repaint) {
                    if (k[0] == vector.size())
                        return;
                    if (vector == pruferTreeNodes) {
                        vector.elementAt(k[0]).draw((Graphics2D) graphics2D);
                    } else {
                        graphics2D.setColor(Color.GREEN);
                        ((Graphics2D) graphics2D).fill(vector.elementAt(k[0]));
                        graphics2D.setColor(Color.BLACK);
                        ((Graphics2D) graphics2D).drawString(vector.elementAt(k[0]).getNodeGraph().getName(), vector.elementAt(k[0]).getX1() + 15, vector.elementAt(k[0]).getY1() + 25);

                    }
                    k[0] += 1;
                }
            }
        });
        timer.start();
    }
}

Как вы думаете, мое использование таймеров плохо? Спасибо за ответ. :)

1 Ответ

2 голосов
/ 05 февраля 2020

При выполнении пользовательского рисования в Swing рекомендуется создать подкласс JPanel (это может быть анонимный класс) и хранить связанные с рисованием данные в атрибутах, доступных в панели.

Ваш таймер не будет сделать любую живопись, а скорее манипулировать данными, связанными с живописью. Никогда не пытайтесь рисовать графические объекты вне EventDispatcherThread of Swing или вне методов paintComponent JComponents. (обратитесь к документации этих методов для получения дополнительной информации)

Вот пример того, как может выглядеть пользовательское рисование с использованием цвета, управляющего таймером:

public static void main(String[] args) {
    EventQueue.invokeLater(Example::new);
}

// this is the painting-related data that is being manipulated by the timer
private int currentColorIndex;

public Example() {
    JFrame frame = new JFrame("Custom Painting");
    frame.setSize(640, 480);
    frame.setLocationRelativeTo(null);

    Color[] allColors = {Color.RED, Color.BLUE, Color.GREEN,
            Color.YELLOW, Color.ORANGE, Color.MAGENTA};

    JPanel myCustomPanel = new JPanel() {
        @Override
        protected void paintComponent(Graphics g) {
            // here the painting related data is being used by the custom JPanel implementation
            g.setColor(allColors[currentColorIndex]);
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    };
    frame.setContentPane(myCustomPanel);

    Timer timer = new Timer(100, e -> {
        // the timer does not use any graphics objects, etc, but rather manipulates our painting-related data
        currentColorIndex = (currentColorIndex + 1) % allColors.length;
        // whenever the painting-related data has changed we need to call repaint() on our custom JPanel implementation
        myCustomPanel.repaint();
    });
    timer.setRepeats(true);
    timer.start();

    frame.setVisible(true);
}
...