2014-01-10 24 views
0

据我所知(我是java noob),当我调整窗口大小或更改其内容时,应该自动调用paintComponent()方法。它重绘了一切,所以当我用一个空方法重写它时,什么都不应该重绘......但它是。为什么?可能我错过了一些东西。什么是由paintComponent()重绘,一切?或者一些背景或不适合?当我用空的paintComponent(g)方法覆盖时为什么重绘组件?

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

public class TextFrame extends JFrame { 
     public TextFrame(String text, String fontName) { 
     super("Show Font"); 
     setSize(725, 150); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     TextFramePanel sf = new TextFramePanel(text, fontName); 
     JButton ok = new JButton("i hate disappearing"); 
     sf.add(ok); 

     add(sf); 
     setVisible(true); 
} 

public static void main(String[] arguments) { 
    if (arguments.length < 1) { 
     System.out.println("Usage: java TextFrame message font"); 
     System.exit(-1); 
    } 
    TextFrame frame = new TextFrame(arguments[0], arguments[1]); 
} 

} 

class TextFramePanel extends JPanel { 
    String text; 
    String fontName; 

    public TextFramePanel(String text, String fontName) { 
    super(); 
    this.text = text; 
    this.fontName = fontName; 
    } 

public void paintComponent(Graphics comp) { 
    //super.paintComponent(comp); 
    /*Graphics2D comp2D = (Graphics2D)comp; 
    comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
     RenderingHints.VALUE_ANTIALIAS_ON); 
    Font font = new Font(fontName, Font.BOLD, 18); 
    FontMetrics metrics = getFontMetrics(font); 
    comp2D.setFont(font); 
    int x = (getSize().width - metrics.stringWidth(text))/2; 
    int y = getSize().height/2; 
    comp2D.drawString(text, x, y); 
    System.out.println("vlad");*/ 
} 
} 
+1

出于好奇,也用空方法重写paint方法。 – christopher

+0

究竟是在画什么,这是意想不到的? –

+0

克里斯,是的,当我用一个空方法重写paint时,什么都不重绘;但是paintComponent呢?这些方法是否与特定组件相关?当我调整框架,painComponent也被称为。 – StackExploded

回答

0

“......所以,当我用一个空方法重写它,没有什么应该重绘......但,为什么?”

因此,它看起来像你从命令行运行该程序。如果您正在运行该程序,并且仍然在paintComponent方法内部绘制内容(即使在您将其内容注释掉之后),最有可能的是您再次编译时运行该程序。所以程序仍然从相同的.class文件运行。

当我按原样运行程序时,除了一个按钮,我什么都看不到,也没有画字。

C:\stack>java TextFrame Hello World


“到底是由的paintComponent(),一切吗?还是一些背景或不便重绘什么?”

paintComponent只是油漆的成分本身,它只是你的情况JPanel。它不会绘制添加到其中的任何其他组件。该画由授权paintComponent方法。每个JComponent都有自己的paintComponent方法。所以如果你想知道为什么这个按钮仍然出现,这是因为在JPanel中调用paintComponent只会影响JPanel,而不是其他子组件添加到它。

+0

nono,我从blueJay运行它。而我的问题是在JButton正在重新绘制后,我说,最小化窗口,然后再次打开它 – StackExploded

+0

我正在测试你的程序,我真的不知道你在说什么。 –

2

我建议您阅读Custom Painting的官方文档:http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html,更重要的是在下仔细查看Paint机制

这里是一个的直接关系到你的问题的一部分:

[...]该方法的paintComponent是所有的你的绘图代码应放置。确实,这个方法在绘制时会被调用,但绘画实际上以类方法开始更高,用paint方法(由java.awt.Component定义)。这个方法将由绘画子系统每当执行一次你的组件需要被渲染。它的签名是:

public void paint(Graphics g) 

[...]的API也无法抑制对你的代码覆盖的paintBorder 和paintChildren,但总的来讲,没有任何理由让你 这样做。对于所有实际用途,paintComponent将是唯一需要覆盖的 方法。


所以,当你正在声明:

public void paintComponent(Graphics comp) {} 

实际上做什么都不。这是因为从文档中可以看出,这幅画不是从paintComponent()开始的,而是从paint()开始的,这很早就被调用了。现在


,如果你声明它是这样的:

public void paint(Graphics g){} 

则不做调整大小和等后重绘,无论你有你的paintComponent()什么代码,因为涂料的层次结构的开始刚被定义为空例程。

+0

很好的答案! ;) –

+0

@victorantunes thx的答案!我读过这篇文章,但我唯一能理解的是有一些机器具有所有这些UIDelegates和一些方法层次结构。此外,paintComponent负责更新背景,但是paintChildren负责更新容器中的组件。同时,我有+100个问题,请在这里说明代码:docs.oracle.com/javase/tutorial/uiswing/painting/step3.html。您对这两种重绘方法的工作方式有任何想法吗?他们如何确定何时绘制正方形,何时用背景色绘制它?但无论如何,thx很多 – StackExploded

相关问题