簡體   English   中英

JComponent不顯示文本-Swing正在為我鋪墊!

[英]JComponent not displaying text - Swing is pwning me!

我是一名高中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);
    }
}

令我驚訝的是,這段代碼也沒有顯示字符串! 我認為該字符串對於較小的面板可能太大了,所以只顯示空白,但是我嘗試將類型大小更改為10,但這也不起作用。

所以現在我真的是:chomp:ing。 我唯一能想到的是這本書已經過時了(Sun改變了Swing自2008年以來的工作方式嗎?我對此表示懷疑。)還是犯了一個嚴重的編碼錯誤(在第八版中?),所以我創建了一個單獨的文件並復制了本書中的整個.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>

第一次重繪后,您正在灰色背景上繪制灰色文本。

但是,為什么不每次計時器觸發時都使用JLabel並調用setText,而是自己做所有這些呢?

在繪制文本之前,您可能應該設置文本的繪制。 還要確保在每次更新時使用SwingUtilities.invokeLater()在組件上調用重新繪制

關鍵是

計時器在單獨的線程上運行。

您只能從事件分派線程(可使用該GUI的一個)更新Swing GUI。

解決方案是使用SwingUtilities.invokeLater()運行更新代碼。

javax.swing.Timer一項便利功能是,動作事件處理程序在事件分配線程(EDT)上執行。 Sun的教程討論如何使用定時器以這種方式,和其他的例子 比比皆是

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM