为什么我不能将JPanel添加到JFrame? [英] Why I cannot add a JPanel to JFrame?

查看:173
本文介绍了为什么我不能将JPanel添加到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;
 }

}

我应该看到请选择伙伴而我没有。为什么?

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

我想这是因为我没有看到Thread的run方法中的帧。

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

已添加:

可能我需要在事件发送线程中进行所有更新...我现在就检查它。

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

已添加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();
   }
      });
 }
 };

已添加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:

以下代码也不起作用。顺便说一句,为什么我要从 start 中删除​​ invokeLater ?我确实需要在事件派发线程中启动GUI并且 invokelater 这样做。

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

}

ADDED 5:

我解决了这个问题。


  1. 在我上课时开始 showWindow 方法。从主程序我调用了错误的方法( showWindow 而不是 start )。所以,我替换了 start 方法(以避免与线程开始混淆),然后我从中调用 startWindow 主类,它解决了这个问题。

  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.


推荐答案

您正在创建更新线程 invokeLater 调用。这不是您使用 invokeLater 的方式。 invokeLater 用于从单独的线程更新UI组件。调用 invokeLater ,传递一个 Runnable 来更新你的UI组件,你的单独线程。

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.

有关其他信息,请参阅 JavaDocs

For additional information, see the 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(); 
            } 
        });
    } 
}; 

这篇关于为什么我不能将JPanel添加到JFrame?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆