2013-10-02 3 views
1

Я следую учебнику, и окно вывода печатает «Hello World!». там. Мой вопрос: из метода paint() не вызывается нигде, тогда как он печатает «Hello World!». ?Почему этот вид вывода появляется?

Вот код ..

package javagame; 

import java.awt.Graphics; 

import javax.swing.JFrame; 


public class JavaGame extends JFrame{ 

    public JavaGame(){ 

     setTitle("sadid java game");  
     setSize(500, 500); 
     setResizable(false); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    public void paint(Graphics g){ 
     g.drawString("Hello world !!!!",30,30); 
    } 

    public static void main(String[] args) { 
     new JavaGame(); 

    } 

} 

В учебнике он печатает нормально окно с "Hello World!" но когда я запускаю тот же код, появляется этот ужасный output. Как это может выглядеть и почему? Есть ли какие-либо проблемы в коде ..?

+5

Пожалуйста, включите код в блок кода, а не как снимок экрана. – kiheru

+0

Я планировал опубликовать код. но я не знаю, как я пропустил это ... для этого .. @kiheru –

ответ

5

Это графический интерфейс Swing, размещенный класс расширяет JFrame и переопределяет метод рисования (что вам не следует делать).

Чтобы ответить на ваш вопрос, переопределение всех компонентов Swing методом Paint автоматически вызывается JVM всякий раз, когда компонент визуализируется. Компонент отображается при запуске приложения, если компонент видим, когда он изменяется, и когда операционная система считает, что окно с компонентом «грязно» и его необходимо перекрасить.

Компонент может быть окрашен, если вы предложите, чтобы он был перекрашен путем вызова repaint() на компоненте или на любом контейнере над ним в его иерархии. Обратите внимание, что я говорю «предлагаемый», так как вы можете только спросить, что диспетчер перекраски рисует компонент, но обычно не «требует», чтобы он это сделал, поэтому вы можете дать менеджеру repaint возможность не перекрашивать регион, если repaint запрашивает стек вверх.

Таким образом, это означает, что метод краски никогда не под вашим прямым контролем и может быть вызван много раз или нечасто.

Причина, по которой этот код не хороший код, чтобы следовать в том, что:

  • Их краски пример не вызывается метод super.paint(g), и поэтому вы перекрывая метод рисования JFrame на не сообщая ему делать его обычный покраска.
  • Метод краски отвечает за рисование дочерних элементов компонента и границ, а для JFrame это очень важно. Не называя супер метод, вы рискуете испортить эти части JFrame по-королевски.
  • Метод по умолчанию не выполняет двойную буферизацию по умолчанию, и если вы пытаетесь сделать анимацию с ней, вы гарантированно будете иметь прерывистую анимацию, если вы не удвоите буфер вручную.

Таким образом, в сумме, не переопределяют метод рисования JFrame на, если только вы не очень уверены, что вы делаете (который автор видео был не) и знать риски. Чтобы правильно рисовать, ознакомьтесь с официальным номером Painting in Swing Tutorials и следуйте их примерам. Для более подробного объяснения, пожалуйста, прочтите Painting in AWT and Swing.

Лучший пример того, что учебник пытается показать бы:.

import java.awt.*; 
import javax.swing.*; 

// draw in a JPanel, not in a JFrame 
public class JavaGame2 extends JPanel { 
    private static final int PREF_W = 500; 
    private static final int PREF_H = PREF_W; 

    public JavaGame2() { 

    } 

    // draw within the JPanel's paintComponent method 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); // be sure to first call the super's method 
     g.drawString("Hello world !!!!", 30, 30); 
    }; 

    // better to set size this way 
    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private static void createAndShowGui() { 
     JavaGame2 mainPanel = new JavaGame2(); 

     // no need to extend JFrame. Instead just use one when needed 
     JFrame frame = new JFrame("sadid java game"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     // be sure to start your Swing GUI in a thread-safe way 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
0

Сначала вы должны сказать, что это родитель, что вы хотите сделать что-то (super.paint (г)) Я думаю, что это будет работать:

import java.awt.Graphics; 

import javax.swing.JFrame; 

public class JavaGame extends JFrame{ 

    public JavaGame(){ 

     super("sadid java game"); 
     setSize(500, 500); 
     setResizable(true); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     g.drawString("Hello world !!!!",200,300); 


    } 

    public static void main(String[] args) { 
     new JavaGame(); 

    } 

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