开发者

Why I cannot add a JPanel to JFrame?

Here is the code:

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;
 }

}

I should see "Pleas select the partner" and I don't. Why?

I suppose that it's because I do not see frame from the run method of the Thread.

ADDED:

May be I need to do all updates in the event dispatch thread... I will check it right now.

ADDED 2:

I tried to modify the code for the controller. It did not help:

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

ADDED 3:

OK. Here is the complete version of the code (which does not work):

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;
    }

}

ADDED 4:

The following code also does not work. By the way, why should I remove invokeLater from the start? I do need to start the GUI in the event dispatch thread and invokelater does it.

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;开发者_JAVA百科
    }

}

ADDED 5:

I solved the problem.

  1. In the class I had start and showWindow methods. From the main program I called the wrong method (showWindow instead of the start). So, I replaces the start method (to avoid confusions with the start of thread) and then I called startWindow from the main class and it solved the problem.


You are creating your update thread from the invokeLater call. This is not how you use invokeLater. invokeLater is for updating UI components from a separate thread. Call invokeLater, passing a Runnable that updates your UI components, from your separate thread.

For additional information, see the JavaDocs

For example:

// 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜