【发布时间】:2013-08-30 17:32:22
【问题描述】:
我编写了一个快速测试程序,它接受字符串输入并将其绘制在 JFrame 上。超级简单。但是由于某种原因,该程序的绘制不一致。例如,一旦输入,它并不总是将字符串绘制到屏幕上。为了尝试调试,我添加了一个 repaint();到paintComponent(它反复要求输入绘制,因此我添加了双缓冲区)。当程序决定不绘制到框架时,它没有让它 repaint();并且没有出现新的输入对话框。我很难理解为什么。
package test;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Main extends JFrame {
private Image dbImage;
private Graphics dbg;
public Main() {
setTitle("Test Project");
setSize(300, 300);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g) {
g.drawString(input(), 140, 130);
}
public static String input() {
String x = ((String)JOptionPane.showInputDialog (
null, "Enter a string", "Test Project",
JOptionPane.QUESTION_MESSAGE,
null, null, null));
return x;
}
public static void main(String[] args) {
Main main = new Main();
}
}
请注意:最初,输入法位于一个单独的类中,因为我正在测试它的项目中将位于该类中。为了简洁起见,我把它移到了这里,因为无论方法在哪里,问题仍然会弹出。
【问题讨论】:
-
使用
JPanel进行绘图,默认为Double Buffered,并覆盖它的paintComponent()方法,而不是在JFrame上绘图:-)此外,请不要尝试过分聪明,在其他地方更改状态并从该位置调用repaint(),而不是从paintComponent()方法中的asking for/changing状态:-) 换句话说,尝试在某处获取String值否则,立即调用repaint()使新状态可见。通过调用模态JOptionPane... 而不是阻塞绘制过程 -
我只有一个问题,paint() 的文档使它看起来像是必须从paintComponent、paintBorder 或paintChildren 中调用repaint。公平地说,可能很重要的是要提到我是 Swing 和 awt 的新手,而且我对 Java 还很陌生。我只是想弄清楚什么是有效的,什么是愚蠢的。
-
请参阅有关Solving Common Painting Problems 的Java 教程,第一个问题及其解决方案将以最恰当的方式回答您的问题 :-) 不,
repaint()不会被调用在paintComponent()内部,而不是paint()本身调用paintComponent()以及paintBorder() and paintChildren()方法。在paintComponent()中添加repaint()将导致递归行为。
标签: java swing jframe awt joptionpane