2013-07-17 4 views
1

Я попытался переопределить метод paintComponent во внутреннем классе JPanel и нарисовать некоторое изображение. Но если я загружаю изображение в конструктор, метод paintComponent не вызывает. Если изображение загрузки в основном классе, то все в порядке. Что это? Вот код, который does'nt работастранная вещь с внутренним классом JPanel

import java.awt.Graphics; 
import java.awt.Image; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Main { 
JFrame window; 
//Image image=new ImageIcon("D://domik.png").getImage(); 

class JPanelExt extends JPanel { 
    Image image; 

    public JPanelExt(){    
    image=new ImageIcon("D://domik.png").getImage(); 
    System.out.println("constructor");   
    } 

    @Override 
    public void paintComponent(Graphics g) {    
     super.paintComponent(g); 
     System.out.println("paint"); 
     g.drawImage(image, 0, 0, this); 
     g.drawRect(0, 400, 100, 100);  
    } 
}  

public Main(){ 

    window=new JFrame("Flowers"); 
    window.setSize(430, 480); 
    window.setVisible(true); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    JPanelExt flower1 =new JPanelExt(); 
    flower1.setBounds(100, 100, 200, 200); 
    flower1.setToolTipText("House");     
    window.setLayout(null);    
    window.add(flower1);     
} 
public static void main(String[] args) { 

    Main main=new Main();  
} 
} 

И SYSOUT пишет только "конструктор"

Но если я изменить код таким образом

public class Main { 
JFrame window; 
Image image=new ImageIcon("D://domik.png").getImage(); 

class JPanelExt extends JPanel { 
    //Image image; 

    public JPanelExt(){ 

    //image=new ImageIcon("D://domik.png").getImage(); 
    System.out.println("constructor"); 
      } 

    @Override 
    public void paintComponent(Graphics g) { 

     super.paintComponent(g); 
     System.out.println("paint"); 
     g.drawImage(image, 0, 0, this); 
     g.drawRect(0, 400, 100, 100); 

    } 

И SYSOUT пишет "конструктор", "краски "

Я не могу этого понять))

+0

Начните с вызова 'setVisible' на вашем кадре последним - и воспользуйтесь соответствующим менеджером макетов – MadProgrammer

+1

Вы также должны проверить [Начальные потоки] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency /initial.html) – MadProgrammer

+0

Кроме того, вместо предоставления «Абсолютного пути», пожалуйста, обратитесь к этому [ответ] (http://stackoverflow.com/a/11372350/1057230), чтобы добавить изображения в приложение. –

ответ

3

Ваша„проблема“есть порядок в основном конструкторе.

Сначала вы создаете новый фрейм. Во-вторых, вы установите его видимым. На этом этапе он окрашивается, а также вызывает методы рисования на связанных панелях. Также в этот момент нет связанной панели. В-третьих, вы создаете новый JPanelExt и добавляете его в фрейм. Это не приведет к перерисовке кадра.

Поместите вызов

window.setVisible(true); 

в конце процесса строительства. Затем вы увидите свое изображение.

+0

[Параллелизм в Swing] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/), также является необходимостью часа, которому также необходимо присваивать вес, т. Е. Вкладывать все в основной метод, например этот 'EventQueue.invokeLater (новый Runnable() {public void run() {/ * Здесь идет основной * *)};), вместе с текущей информацией +1 –

+0

Спасибо большое! Но почему работает второй вариант и вызывается paintComponent? – user2588825

+0

@ user2588825: Потому что ваше 'окно' уже было видно, прежде чем вы добавили к нему' flower1', поэтому вызов 'repaint()' будет выполняться, IMHO, когда вы минимизируете свое окно, или перетащите на ' inc/dec' размер. Именно поэтому его считают хорошей практикой, чтобы сначала добавить все компоненты в родительский контейнер, а затем сделать его видимым и не раньше этого :-) –

Смежные вопросы