2015-07-12 87 views
0

感謝您的幫助。我是一個嘗試相當簡單的新手。 我想要一個窗口(面板),每隔幾秒鐘更改一次文本(JLabel)。除了正在更新的JLabel(文本確實發生了變化)之外,整個應用程序都可以正常工作,但不會顯示在窗口(面板)上。該窗口始終保持相同的文本,即使我有檢查點告訴我JLabel的文本正在更新和更改。我在各地都在尋找相同的問題,並發現了一些評論,但沒有任何幫助。有人說是ActionListener,但是當我擺脫它時,沒有什麼區別。有人說線程中的循環不會讓JLabel刷新,所以我嘗試使用JLabel,它的更新正在一個單獨的線程上,並且也不起作用。我沒有嘗試過的唯一的事情是使用swingWorker(不太清楚如何)。線程嘗試使用帶有可運行方法的線程類。再說一次,一切都很完美,除了JLabel沒有重新繪製。JPanel上的JLabel在其他方法的setText不更新時

這裏是沒有線程的代碼。全部在一個班級。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.event.WindowListener; 

import javax.swing.*; 





public class SWUI extends JFrame implements ActionListener { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    private JPanel panel; 
    JLabel label; 
    private Font font; 


    //Set up the interface. SWUI is working perfectly 
SWUI() { 

     System.out.println("run started");  //just to check that the method gets called. 
     panel = new JPanel(); 
     panel.setLayout(new BorderLayout(1, 1)); 
     panel.setPreferredSize(new Dimension(1000, 400)); 
     panel.setBackground(Color.white); 
     getContentPane().add(panel); 

     label = new JLabel("Ready");     //These four statements are working 
     label.setHorizontalAlignment(JLabel.CENTER); 
     font = new Font("Comic Sans MS", Font.PLAIN, 70); 
     label.setFont(font); 

     panel.add(label, BorderLayout.CENTER); 

     System.out.println("run done and draw to start"); 

     label.setText("label is updatable");  //Checks that the whole method gets done and that the label is indeed able to get updated. It works. 

    } 


// draw() mostly sets the Frame up, names it, sets closing behavior. It's working. 
    public void draw() { 

     System.out.println("draw started");   //To check that the method is getting invoked. 

     SWUI frame = new SWUI(); 
     frame.setTitle("Sight Words Rock"); 

     WindowListener l = new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
     }; 
     frame.addWindowListener(l); 

     frame.pack(); 
     frame.setVisible(true); 

     System.out.println("draw done");  //To check that the whole method went through. It's all working. 

    } 



    //Should change the label to 4 sentences every 1 second. The text of the label does change, but it doesn't show on the interface (panel). 
    private void updateLabel(String word){ 

     label.setText(word); 

     //label.revalidate();  //I tried these three statements one at a time and both together and they made no difference. 
     //label.updateUI(); 
     //label.repaint(); 

     System.out.println("The label now is: "+ label.getText()); //This confirms that the setText() is indeed changing the text 
                    // of the label, but it doesn't show on the interface. 
    } 


    //Main gets the draw() started to initiate the interface and gets the sentences changed and sent to updateLabel() every second. 
    public static void main(String args[]) 

     throws InterruptedException { 

     SWUI ui = new SWUI(); 
     ui.draw(); 


     String importantInfo[] = { 
      "Mares eat oats", 
      "Dogs eat oats", 
      "Little lambs eat ivy", 
      "A kid will eat ivy too" 
     }; 

     for (int i = 0; 
      i < importantInfo.length; 
      i++) { 
      //Pause for 1 second 
      Thread.sleep(1000); 

      //Print a message 
      System.out.println(importantInfo[i]); 

      ui.label.setText(importantInfo[i]); 
      ui.updateLabel(importantInfo[i]); 
     } 

    } 

    //This will come later once I figure how to fix the label. Someone else suggested that the problem were the listeners not letting the thread 
    // do the repainting(), but I tried getting rid of the "implements ActionListener" and the actionPerformed methods and it didn't make a 
    // difference. It still didn't work. 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     // TODO Auto-generated method stub 

    } 
} 
+0

那麼你調用'setText'哪個線程?請記住,擺動組件的所有更新都必須在EDT上進行,如果需要從另一個線程觸發更新,請使用'SwingUtilities.invokeLater'。 –

+0

1)使用縮進代碼行和塊的邏輯一致形式。縮進旨在使代碼的流程更易於遵循! 2)源代碼中的單個空白行是所有需要的。 '{'之後或'}'之前的空行通常也是多餘的。 –

回答

0

而你更新到這是從來沒有真正看到設置初始幀你在SWUIdraw方法創建一個全新的框架。要解決這個問題,你的繪圖方法應該看起來更像這樣。

public void draw() { 

     System.out.println("draw started");   //To check that the method is getting invoked. 

     setTitle("Sight Words Rock"); 

     WindowListener l = new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
     }; 
     addWindowListener(l); 

     pack(); 
     setVisible(true); 
    System.out.println("draw done");  //To check that the whole method went through. It's all working. 

} 
+0

非常感謝你提供了一個全面而清晰的解釋。它工作完美。 –

+0

System.exit(0);在windowClosing == JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) – mKorbel

+0

隨意添加一個編輯@mKorbel。我並沒有真正搞亂它,縮進很糟糕,可能最好不要將JFrame繼承爲開頭,有很多方法可以更好。 – pvg