2010-12-14 57 views
0

我試圖寫是這樣一個應用程序:
- 顯示一個對話框
- 當用戶點擊OK,關閉對話框,轉到主應用程序的paintComponent不會被調用在正確的時間

以下是相關的代碼片段:

public class Owari extends JPanel implements ActionListener, MouseListener, Runnable { 

// FIELDS 
JFrame frame; 
JTextField IP; 
String IPAddress; 

static final int SERVER_MODE = 0; 
static final int CLIENT_MODE = 1; 
int mode; 

OwariBoard board; 

    public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Owari()); 
    } 

    Owari() { 
    setPreferredSize(new Dimension(WIDTH, HEIGHT)); 
    board = new OwariBoard(); 
    } 

    void main() { 
    this.addMouseListener(this); 
    frame.dispose(); 
    frame = new JFrame("Owari"); 
    frame.setContentPane(this); 
    frame.pack(); 
    frame.setVisible(true); 
    if (mode == SERVER_MODE) { 
     server(); 
    } 
    if (mode == CLIENT_MODE) { 
     client(); 
    } 
    } 

    public void run() { 
    frame = new JFrame("Owari"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    JPanel init = new JPanel(new GridBagLayout()); 
    frame.setContentPane(init); 

    add some components to the init panel including a button with 
    this as its actionListener and OK as its command. 
    frame.pack(); 
    frame.setVisible(true); 
    } 


    public void actionPerformed(ActionEvent e) { 
    if (e.getActionCommand().equals("Client")) { 
     mode = CLIENT_MODE; 
     IP.setVisible(true); 
    } 
    else if (e.getActionCommand().equals("Server")) { 
     mode = SERVER_MODE; 
     IP.setVisible(false); 
    } 
    else { 
     IPAddress = IP.getText(); 
     main(); 
    } 
    } 

    public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    System.out.println("painting"); 
    do some paintin 
    } 

    void server() { 
    frame.setTitle("Owari Server"); 
    try { 
    server = new ServerSocket(666); 
    socket = server.accept(); 
    initIO(); 
    } catch (IOException e) {} 
    yourTurn = true; 
    System.out.println("Got to end of server()"); // At this point, the window 
                 DOES get painted 

什麼情況如下:
最初的對話框顯示:
我點擊確定按鈕。 主窗口被調整到主應用程序的首選大小,但它不會畫,它只是透明的(此頁面爲背景這裏顯示,嘿嘿):
http://imgur.com/6Ssij.jpg

我可以告訴沒有調用paintComponent方法,因爲「繪畫」未打印到控制檯。 但是,「程序中的這一點」已經打印出來了,所以程序不會掛起,它只是不調用paintComponent。 然後,當我啓動一個客戶端並連接時,應用程序終於被繪製,並且「繪畫」和「獲得客戶端」被打印到控制檯。 稍後在應用程序中,對repaint()的調用也會被延遲(即paintComponent實際上會在調用repaint()時被調用)。

我還試圖使用替換沿sthing的

public void main 
    frame.getRootPane.removeAll() 
    frame.setContentPane(this) 
    frame.getRootPane().revalidate() 
    frame.pack() 

完全相同的結果的線的初始對話框。

tl; dr paintcomponent在我想要的時候沒有被調用,有什麼用?


碰碰更多的一些信息:調用重繪()被調用之前做sever.accept()那麼,爲什麼它不之前重繪()掛在server.accept()調用?

+0

你的牙套在哪裏? – jjnguy 2010-12-14 16:48:06

+0

請記住在EDT上運行所有Swing/AWT代碼,但不要阻止它。 /啊兩條主線。 ''openasocketandwaitforaclient'在美國東部時間,這是一件壞事。 – 2010-12-14 16:57:53

回答

2

openasocketandwaitforaclient

你的代碼是在事件調度線程中執行,因此阻止插座防止GUI重畫本身。

您需要爲套接字使用單獨的線程。請閱讀Swing教程Concurrency中的部分以獲取解釋和解決方案。

+0

非常感謝。 我知道所有的迴轉繪畫都必須在事件派發線程中完成,但並非必須在其外部完成非繪畫東西。 – Jonathan 2010-12-14 17:04:43

+0

碰到更多的信息:調用repaint()在調用服務器之前完成。accept() 那麼爲什麼在等待連接時掛起之前不重繪()? – Jonathan 2010-12-16 18:12:55

+1

重繪()不會導致組件被立即着色。它調用Repaint管理器,它可能合併多個重繪請求,然後將它們添加回EDT的末尾以進行繪畫。 – camickr 2010-12-16 19:04:58

0

您的代碼似乎可以正常工作,也許您應該在調整此框架的大小後嘗試調用您的幀的repaint()方法。

Anhuin