我是一名高中AP计算机科学专业的学生,正在用Java做一个独立的学习项目。我选择为初学钢琴的学生编写一个应用程序,在该应用程序中,计算机显示键盘的图片,并突出显示注释。然后,用户选择与突出显示的键相对应的音符的名称,并使用计时器计数到零,然后报告用户的分数。
我的视图已基本完成,但在屏幕上显示计时器时遇到问题。
计时器由模型创建,并在单独的线程中运行,每秒指示控制器更新计时器,该计时器调用视图中的方法,然后在对象TimerUpdateComponent中设置一个值,然后进行验证以显示新文本。
至少,这是理论上的。计时器工作得很好-每秒打印到控制台,就像我要求的那样-但当我运行视图时,什么也没有出现。因此,考虑到我应该做主程序所做的事情并找出区别,我直接从Horstmann和Cornell的ICore Java - Volume /I复制了这段代码,它应该显示字符串"Hello,World!“在面板的中心:
public void paintComponent(Graphics g){<br>
Graphics2D g2 = (Graphics2D) g;<br>
String message = "Hello, World!";<br>
Font f = new Font("Serif",Font.BOLD,36);<br>
g2.setFont(f);
//measure the size of the message
FontRenderContext context = g2.getFontRenderContext();
Rectangle2D bounds = f.getStringBounds(message, context);
//set (x,y) to top-left corner of text
double x = (getWidth() - bounds.getWidth())/2;
double y = (getHeight() - bounds.getHeight())/2;
//add ascent to y to reach the baseline
double ascent = -bounds.getY();
double baseY = y + ascent;
//draw the message
g2.drawString(message, (int)x, (int)y);
g2.setPaint(Color.LIGHT_GRAY);
//draw the baseline
g2.draw(new Line2D.Double(x, baseY,x - bounds.getWidth(), baseY));
//draw the enclosing rectangle
Rectangle2D rect = new Rectangle2D.Double(x,y,bounds.getWidth(), bounds.getHeight());
g2.draw(rect);
}
}
令我惊讶的是,这段代码也没有显示字符串!我认为字符串对于相当小的面板来说可能太大了,所以它只显示空白,但我尝试将字体大小更改为10,这也不起作用。
所以,现在我真的是:咬人。我唯一能想到的就是这本书已经过时了( Sun是不是从2008年开始改变了Swing的工作方式?我对此表示怀疑。)或者犯了一个严重的编码错误(在它的第八版?)所以我创建了一个单独的文件,并从书中复制了整个.java文件,它工作得很好。
请帮帮我!
另外,这是我的原始方法体,如果你想看一下的话:
String message = time/60+":"+time%60;<br>
Graphics2D g2 = (Graphics2D) g;<br>
FontRenderContext context = g2.getFontRenderContext();<br>
Rectangle2D bounds = g2.getFont().getStringBounds(message, context);<br>
double x = (getWidth() - bounds.getWidth()) / 2;<br>
double y = (getHeight() - bounds.getHeight() / 2);<br>
g2.drawString(message,(int)x,(int)y);<br>
发布于 2010-01-11 09:44:27
在第一次重新绘制之后,您将在灰色背景上绘制灰色文本。
但为什么不使用JLabel并在每次计时器触发时调用setText,而是自己来完成所有这些工作呢?
发布于 2010-01-11 09:42:20
您可能应该在绘制文本之前设置文本的颜色值。还要确保在每次更新时使用SwingUtilities.invokeLater()在组件上调用重绘
发布于 2010-01-11 09:45:49
关键的短语是
计时器在单独的线程上运行。
您只能从事件调度线程更新Swing GUI。
解决方案是使用SwingUtilities.invokeLater()
运行更新代码。
https://stackoverflow.com/questions/2039436
复制相似问题