2010-03-22 305 views
2

下面是代碼:爲什麼我無法將Janel添加到JFrame?

import javax.swing.SwingUtilities; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import java.awt.event.*; 
import java.awt.*; 

public class GameWindow { 

private String[] players; 
private JFrame frame; 

// Constructor. 
public GameWindow(String[] players) { 
    this.players = players; 
} 

// Start the window in the EDT. 
public void start() { 
    SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
    showWindow(); 
    controller.start(); 
    } 
    }); 
} 

// Defines the general properties of and starts the window. 
public void showWindow() { 
    frame = new JFrame("Game"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(600,400); 
    frame.setVisible(true); 
} 

// The thread controlling changes of panels in the main window. 
private Thread controller = new Thread() { 
    public void run() { 
     frame.add(generatePartnerSelectionPanel()); 
     frame.invalidate(); 
     frame.validate(); 
    } 
}; 

// Generate the panel for the selection of a partner. 
private JPanel generatePartnerSelectionPanel() { 
    JPanel panel = new JPanel(); 
    panel.add(new JLabel("Pleas select a partner:")); 
    return panel; 
} 

} 

我應該能看到「普萊斯選擇的合作伙伴」,我不知道。爲什麼?

我想這是因爲我沒有看到線程運行方法的框架。

新增:

可能是我需要做在事件調度線程的所有更新。我將馬上檢查。

ADDED 2:

我試圖修改代碼的控制器。它並沒有幫助:

private Thread controller = new Thread() { 
public void run() { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     frame.getContentPane().add(generatePartnerSelectionPanel()); 
     frame.invalidate(); 
     frame.validate(); 
    } 
     }); 
} 
}; 

附加的3:

確定。這裏是代碼的完整版本(不工作):

import javax.swing.SwingUtilities; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import java.awt.event.*; 
import java.awt.*; 

public class GameWindow { 

    private String[] players; 
    private JFrame frame; 

    // Constructor. 
    public GameWindow(String[] players) { 
     this.players = players; 
    } 

    // Start the window in the EDT. 
    public void start() { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       showWindow(); 
       controller.start(); 
      } 
     }); 
    } 

    // Defines the general properties of and starts the window. 
    public void showWindow() { 
     frame = new JFrame("Game"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
     frame.setSize(600,400); 
     frame.setVisible(true); 
    } 

    // The thread controlling changes of panels in the main window. 
    private Thread controller = new Thread() { 
     public void run() { 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        frame.getContentPane().add(generatePartnerSelectionPanel()); 
        frame.invalidate(); 
        frame.validate(); 
       } 
      }); 
     } 
    }; 

    // Generate the panel for the selection of a partner. 
    private JPanel generatePartnerSelectionPanel() { 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel("Pleas select a partner:")); 
     return panel; 
    } 

} 

新增4:

下面的代碼也不起作用。順便說一下,爲什麼我應該從start刪除invokeLater?我確實需要在事件派發線程中啓動GUI,並且invokelater這樣做。

import javax.swing.SwingUtilities; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import java.awt.event.*; 
import java.awt.*; 

public class GameWindow { 

    private String[] players; 
    private JFrame frame; 

    // Constructor. 
    public GameWindow(String[] players) { 
     this.players = players; 
    } 

    // Start the window in the EDT. 
    public void start() { 
//  SwingUtilities.invokeLater(new Runnable() { 
//   public void run() { 
       showWindow(); 
       controller.start(); 
//   } 
//  }); 
    } 

    // Defines the general properties of and starts the window. 
    public void showWindow() { 
     frame = new JFrame("Game"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
     frame.setSize(600,400); 
     frame.setVisible(true); 
    } 

    // The thread controlling changes of panels in the main window. 
    private Thread controller = new Thread() { 
     public void run() { 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        frame.getContentPane().add(generatePartnerSelectionPanel()); 
        frame.invalidate(); 
        frame.validate(); 
       } 
      }); 
     } 
    }; 

    // Generate the panel for the selection of a partner. 
    private JPanel generatePartnerSelectionPanel() { 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel("Pleas select a partner:")); 
     return panel; 
    } 

} 

加入5:

我解決了這個問題。

  1. 在班級我有startshowWindow方法。從主程序中我調用了錯誤的方法(showWindow而不是start)。因此,我替換了start方法(以避免與線程的開始混淆),然後我從主類中調用startWindow並解決了問題。
+0

回覆:您的更新。我是否按照我的建議更改了「開始」? – Randolpho 2010-03-22 13:47:54

+0

您仍然需要從'start'方法中刪除'invokelater'調用。 – Randolpho 2010-03-22 13:50:41

+0

是的,我刪除了'invokeLater'。該代碼仍然不起作用。順便說一句,我認爲自從它在事件派發線程中啓動GUI(因爲它應該是這樣)之後,我不應該從一開始就刪除'invokeLater'。 – Roman 2010-03-22 13:54:01

回答

4

您正在創建更新線程調用invokeLater。這不是你如何使用invokeLaterinvokeLater用於從單獨的線程更新UI組件。撥打invokeLater,傳遞一個Runnable更新您的UI組件,您的單獨線程。

有關更多信息,請參閱JavaDocs

例如:

// Start the window in the EDT. 
public void start() { 
    showWindow(); 
    controller.start(); 
} 

// Defines the general properties of and starts the window. 
public void showWindow() { 
    frame = new JFrame("Game"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    frame.setSize(600,400); 
    frame.setVisible(true); 
} 

// The thread controlling changes of panels in the main window. 
private Thread controller = new Thread() { 
    public void run() { 

     // some long running process, I assume, but at 
     // some point you want to update UI: 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       frame.add(generatePartnerSelectionPanel()); 
       frame.invalidate(); 
       frame.validate(); 
      } 
     }); 
    } 
}; 
+0

你是對的。我同意我需要使用invokeLater更新GUI的組件。我在代碼中做了這些修改(我在修正問題時也提到了它)。但它並沒有解決問題。 – Roman 2010-03-22 13:45:17

+0

您是否按照我的建議更改了「開始」? – Randolpho 2010-03-22 13:48:42

+0

嗯,我從'start'中刪除了'invokeLater',它沒有幫助。此外,我認爲我們應該在那裏使用'invokeLater'。據我所知,GUI應該在事件派發線程中啓動,並且invokeLater執行它。 – Roman 2010-03-22 13:52:50

相關問題