0

我正在学习教程,输出窗口打印“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!”的窗口。但是当我运行相同的代码时,会出现这个可怕的输出。这种输出怎么会出现,为什么?代码有什么问题吗..?

4

2 回答 2

5

这是一个 Swing GUI,发布的类扩展了 JFrame 并覆盖了 paint 方法(你不应该这样做)。

为了回答您的问题,每当呈现组件时,JVM 都会自动调用所有 Swing 组件的paint 方法覆盖。组件在应用程序启动、组件是否可见、调整大小以及操作系统感觉带有该组件的窗口“脏”需要重新绘制时渲染。

如果您建议通过调用repaint()组件或在其层次结构中高于它的任何容器来重新绘制组件,也可以绘制组件。请注意,我说“建议”,因为您只能要求重绘管理器绘制组件,但通常不会“要求”它这样做,因此您可以为重绘管理器提供在重绘请求堆栈时不重绘区域的选项向上。

所以这意味着paint方法永远不会在你的直接控制之下,并且可以被多次或不频繁地调用。

这段代码不是好的代码的原因是:

  • 他们的绘画示例不调用该super.paint(g)方法,因此您在不告诉它进行正常绘画的情况下覆盖了 JFrame 的绘画方法。
  • paint 方法负责绘制组件的子项和边框,对于 JFrame,这非常重要。如果不调用 super 方法,您可能会严重破坏 JFrame 的这些部分。
  • paint 方法默认不做双缓冲,如果你尝试用它做动画,除非你手动双缓冲,否则肯定会出现断断续续的动画。

所以总而言之,除非您非常确定自己在做什么(视频的作者不是)并且知道所涉及的风险,否则不要覆盖 JFrame 的绘制方法。要正确绘制,请查看Swing 教程中的官方绘画,并按照他们的示例进行操作。有关更详细的解释,请阅读AWT 和 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();
         }
      });
   }
}
于 2013-10-02T21:13:29.203 回答
0

首先你必须告诉它的父母你想画一些东西(super.paint(g))。我认为它会起作用:

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

    }

}
于 2013-10-02T21:23:29.430 回答