为什么会出现这种输出?

时间:2013-10-02 21:09:04

标签: java swing

我正在关注教程,输出窗口打印出“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出现了。这种输出怎么出现?为什么?代码中是否有任何问题..?

2 个答案:

答案 0 :(得分:5)

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

要回答您的问题,只要呈现组件,JVM就会自动调用所有Swing组件的paint方法重写。应用程序启动时,如果组件可见,调整大小时以及操作系统认为组件窗口“脏”并需要重新绘制时,将呈现组件。

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

所以这意味着paint方法永远不会被你直接控制,可以多次调用或不经常调用。

此代码不适合遵循的原因是:

  • 他们的绘图示例不会调用super.paint(g)方法,因此您将覆盖JFrame的绘制方法,而不会告诉它进行正常绘制。
  • 绘制方法负责绘制组件的子项和边框,对于JFrame,这是非常重要的。通过不调用super方法,你可能会冒失望地搞砸JFrame的这些部分。
  • 默认情况下,paint方法不会进行双缓冲,如果你尝试用它做动画,除非你手动双重缓冲,否则你可以保证有不稳定的动画。

总而言之,除非你非常确定你正在做什么(你的视频的作者是)并且知道所涉及的风险,否则不要覆盖JFrame的paint方法。要正确绘制,请查看官方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();
         }
      });
   }
}

答案 1 :(得分: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();

    }

}