Java JComponent不显示文本-Swing正在折磨我!

Java JComponent不显示文本-Swing正在折磨我!,java,user-interface,swing,Java,User Interface,Swing,我是一名高中AP计算机科学的学生,正在用Java做一个独立的研究项目。我选择为初学钢琴的学生编写一个应用程序,在这个应用程序中,计算机会显示键盘的图片,并突出显示一个音符。然后,用户选择与突出显示的键对应的注释名称,计时器计数为零,然后报告用户的分数 我的视图即将完成,但在屏幕上显示计时器时遇到问题 计时器由模型创建并在单独的线程中运行,每秒指示控制器更新计时器,计时器在视图中调用一个方法,该方法在对象TimerUpdateComponent中设置一个值,然后验证以显示新文本 至少,这是理论。计

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

我的视图即将完成,但在屏幕上显示计时器时遇到问题

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

至少,这是理论。计时器工作得很好——就像我问的那样,每秒都会打印到控制台上——但是当我运行视图时,什么也没有出现。因此,我想我会像大师那样做并找出区别,我直接从Horstmann和Cornell的[I]Core Java-Volume I[/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);
    }
}
public组件(图形g){
图形2d g2=(图形2d)g;
String message=“你好,世界!”;
Font f=新字体(“衬线”,字体粗体,36);
g2.setFont(f); //测量消息的大小 FontRenderContext上下文=g2.getFontRenderContext(); 矩形2D边界=f.getStringBounds(消息、上下文); //将(x,y)设置为文本的左上角 双x=(getWidth()-bounds.getWidth())/2; 双y=(getHeight()-bounds.getHeight())/2; //将上升添加到y以达到基线 双上升=-bounds.getY(); 双基y=y+上升; //传达信息 g2.抽绳(信息,(整数)x,(整数)y); g2.setPaint(颜色:浅灰色); //画基线 绘制(newline2d.Double(x,baseY,x-bounds.getWidth(),baseY)); //绘制封闭矩形 Rectangle2D rect=新的Rectangle2D.Double(x,y,bounds.getWidth(),bounds.getHeight()); g2.绘制(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>
String message=time/60+:“+time%60
图形2d g2=(图形2d)g
FontRenderContext上下文=g2.getFontRenderContext()
Rectangle2D bounds=g2.getFont().getStringBounds(消息、上下文)
双x=(getWidth()-bounds.getWidth())/2
双y=(getHeight()-bounds.getHeight()/2)
g2.抽绳(信息,(整数)x,(整数)y)

您可能应该在绘制文本之前设置文本的绘制。另外,确保在每次更新时使用SwingUtilities.invokeLater()调用组件上的repaint,在第一次重新绘制后,您将在灰色背景上绘制灰色文本

但是为什么不在每次定时器启动时使用JLabel和call setText,而自己完成所有这些呢?

关键短语是

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

您只能从事件调度线程更新Swing GUI,该线程运行GUI


解决方案是使用
SwingUtilities.invokeLater()

运行更新代码。我将绘制颜色更改为红色,但仍然没有得到任何结果。我没有使用JLabel,因为我可能希望格式化文本、更改大小、颜色等,而且JLabel限制太多。那么,您的非工作文件与书本中的工作文件有什么不同?如果您添加一些println/日志,从pain方法中转储组件的宽度和高度,它们是什么?