Вопрос о быстрой перерисовке (объект Canvas)

Новые детали:

Метод перерисовки моего объекта JPanel не работает при вызове из события actionPerformed моего основного класса. Он работает внутри метода ImageViewer основного класса ImageViewer, но не работает внутри метода actionPerformed этого класса.

Это основные части моего кода, которые не работают должным образом (часть перерисовки):

Основной класс:

/**
 * @(#)NeatImageViewer.java
 *
 * NeatImageViewer application
 *
 * @author
 * @version 1.00 2010/11/1
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;


public class NeatImageViewer extends JFrame implements ActionListener {

    GraphicsPanel gp;

    NeatImageViewer() {
               //... window components ...
    }

    public static void main(String[] args) {

        NeatImageViewer niv = new NeatImageViewer();
        niv.setSize(500,500);
        niv.setLocationRelativeTo(niv);
        niv.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
            //...
                gp = new GraphicsPanel();
                gp.img = img;
                gp.repaint(); //<!--- Not Working!
                this.add(gp);
            //...
    }

}

Класс GraphicsPanel:

/**
 * @(#)GraphicsPanel.java
 *
 *
 * @author
 * @version 1.00 2010/11/1
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;


public class GraphicsPanel extends JPanel {
    BufferedImage img;

    GraphicsPanel() {
        super();
    }

    protected void paintComponent(Graphics g) {
        //paint method isn't executed???
        super.paintComponent(g);
        System.out.println("Paint!");
    }

}

person Skyfe    schedule 01.11.2010    source источник
comment
не работает внутри метода actionPerformed этого класса. ничего не значит для нас. Опубликуйте свой SSCCE (sscce.org), демонстрирующий проблему.   -  person camickr    schedule 01.11.2010


Ответы (3)


В Swing вы не используете Canvas. Вы делаете пользовательское рисование на JPanel или JComponent и переопределяете метод paintComponent(...), как уже было сказано. Прочтите учебное пособие по Swing на странице Custom Painting для получения дополнительной информации и рабочих примеров. .

Кроме того, с Swing нет необходимости создавать пользовательские компоненты для отображения изображения. Вы просто используете JLabel с ImageIcon. Прочтите раздел «Как использовать значки».

Добавьте в закладки учебник по всем основам Swing.

Редактировать:

Когда вы добавляете компонент в видимый графический интерфейс, основной код должен быть:

panel.add( ... );
panel.revalidate();
panel.repaint();
person camickr    schedule 01.11.2010
comment
Спасибо, что разъяснили это. Я немного запутался с Swing и AWT, используя их вместе. Однако теперь я следовал руководству, и теперь я использую JPanel, но имею точно такую ​​​​же проблему: перерисовка не работает при вызове из метода actionPerformed, но работает при вызове из метода ImageViewer основного класса ImageViewer. Я думаю, что я все еще делаю что-то не так? - person Skyfe; 01.11.2010
comment
@Skyfe, см. комментарии к редактированию. Вы до сих пор не опубликовали SSCCE. - person camickr; 01.11.2010
comment
Я обновил свой пост своим кодом, который не работает (gp.repaint()) так, как я разместил его в своем основном посте (ниже EDIT2). Что касается метода add, его также можно опустить, потому что метод paintComponent на самом деле еще ничего не рисует, но я просто попытался позволить ему вообще выполняться (чего вообще не произошло при использовании метода repaint для объекта). - person Skyfe; 01.11.2010
comment
Размер 0, значит красить нечего? Последний шанс. ГДЕ НАХОДИТСЯ SSCCE? Я трачу свое время на догадки!!!!!! - person camickr; 02.11.2010
comment
Исправлено... this.validate() заработало. Каким-то образом даже вывод System.out.println() метода рисования не отображался до повторной проверки кадра (звучит странно для меня, потому что я думаю, что будет обновлен только отображаемый графический интерфейс). Но в любом случае это исправлено, спасибо.. - person Skyfe; 02.11.2010
comment
@Skyfe, это то, что я предложил сделать. Разве я не говорил, что вам нужно перепроверить() панель, в которую вы добавляете компонент? Кроме того, вы используете revalidate() в Swing, а не validate(). Кроме того, я объяснил, почему метод paint() не был вызван, так почему вы так удивлены? Почему ответ не принимается? - person camickr; 02.11.2010
comment
Я знаю, что вы использовали, я просто сказал вам, что это не так, как обычно. Именно так вы бы сделали это, используя AWT, а НЕ Swing. Я думал, вы пытаетесь изучить Swing? - person camickr; 03.11.2010

Вы должны переопределить paintComponent(Graphics g) вместо paint(Graphics g).
Таким образом, опубликованный вами метод следует переименовать в paintComponent.

EDIT: Вы pack() изменили свой фрейм после завершения инициализации?

EDIT: Метод repaint() ничего не делает, когда компонент не виден. Итак, вы должны сначала добавить его в JFrame, pack() во фрейм. После упаковки перекрашивать больше не нужно.

person Martijn Courteaux    schedule 01.11.2010
comment
Я переименовал имя метода в paintComponent, но он все еще не работает. - person Skyfe; 01.11.2010
comment
Когда я упаковываю кадр, например: niv.pack(), я получаю окно только с заголовком и строкой меню, и оно все еще не работает. - person Skyfe; 02.11.2010

(Я Skyfe, но с другого IP-адреса, поэтому я не «залогинен» и не могу комментировать)

Извините, но я не понимаю, в чем проблема???

Я предложил свой код, и он НЕ выполняет функцию paintComponent при вызове перерисовки из метода actionPerformed. Просто скопируйте и вставьте мой код и скомпилируйте его с помощью java-компилятора, и он НЕ выполняет метод paintComponent при выполнении действия, которое я могу сказать, потому что я использовал метод System.out.println() внутри метода рисования. И нет, он ничего не рисует, потому что я просто пытаюсь проверить, вызывает ли он метод рисования ВООБЩЕ, потому что я помещаю системный вывод в метод paintComponent, который не выполняется при использовании перерисовки. Это был просто тест, и он не сработал.

Итак, что вы имеете в виду под SSCCE, это весь код, который у меня есть. Я скомпилировал именно тот код, который разместил в своем основном посте, и проблема с ним в том, что он не показывает никакого системного вывода, когда было выполнено действие (и было вызвано событие перерисовки). Я не вижу, чего не хватает в моем посте?

person skyfe    schedule 02.11.2010
comment
Я дал вам ссылку о том, как написать SSCCE в комментарии к вашему первоначальному вопросу! Я также предоставил вам ссылку, когда отвечал на ваш другой вопрос 2 дня назад: stackoverflow.com/questions/4060006/. У вас нет причин не знать, что такое SSCCE, вас спрашивали не раз. Мало того, что вы можете поискать в Интернете, чтобы узнать, что такое SSCCE! - person camickr; 02.11.2010
comment
Да, он говорит, что это: короткий, автономный, правильный (компилируемый), пример. Какой мой пост, так что я до сих пор не понимаю, почему мой пост не будет SSCCE. Я разместил правильный код, который использовал, проблему и краткое... - person Skyfe; 04.11.2010