首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JComponent不显示文本-- Swing让我很生气!

JComponent不显示文本-- Swing让我很生气!
EN

Stack Overflow用户
提问于 2010-01-11 09:32:13
回答 3查看 636关注 0票数 0

我是一名高中AP计算机科学专业的学生,正在用Java做一个独立的学习项目。我选择为初学钢琴的学生编写一个应用程序,在该应用程序中,计算机显示键盘的图片,并突出显示注释。然后,用户选择与突出显示的键相对应的音符的名称,并使用计时器计数到零,然后报告用户的分数。

我的视图已基本完成,但在屏幕上显示计时器时遇到问题。

计时器由模型创建,并在单独的线程中运行,每秒指示控制器更新计时器,该计时器调用视图中的方法,然后在对象TimerUpdateComponent中设置一个值,然后进行验证以显示新文本。

至少,这是理论上的。计时器工作得很好-每秒打印到控制台,就像我要求的那样-但当我运行视图时,什么也没有出现。因此,考虑到我应该做主程序所做的事情并找出区别,我直接从Horstmann和Cornell的ICore Java - Volume /I复制了这段代码,它应该显示字符串"Hello,World!“在面板的中心:

代码语言:javascript
运行
复制
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文件,它工作得很好。

请帮帮我!

另外,这是我的原始方法体,如果你想看一下的话:

代码语言:javascript
运行
复制
    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>
EN

回答 3

Stack Overflow用户

发布于 2010-01-11 09:44:27

在第一次重新绘制之后,您将在灰色背景上绘制灰色文本。

但为什么不使用JLabel并在每次计时器触发时调用setText,而是自己来完成所有这些工作呢?

票数 1
EN

Stack Overflow用户

发布于 2010-01-11 09:42:20

您可能应该在绘制文本之前设置文本的颜色值。还要确保在每次更新时使用SwingUtilities.invokeLater()在组件上调用重绘

票数 0
EN

Stack Overflow用户

发布于 2010-01-11 09:45:49

关键的短语是

计时器在单独的线程上运行。

您只能从事件调度线程更新Swing GUI。

解决方案是使用SwingUtilities.invokeLater()运行更新代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2039436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档