Java JFrame pack()和requestFocus()不工作

Java JFrame pack()和requestFocus()不工作,java,swing,jpanel,paintcomponent,preferredsize,Java,Swing,Jpanel,Paintcomponent,Preferredsize,我的主要问题是在设置JFrame时出现以下代码: 为什么面板没有显示我是否使用pack()以及如何使其工作 为什么第一个requestFocusInWindow()不起作用,使用它的原则是什么 如果删除setLayout(),为什么JPanel的默认布局管理器不工作 公共类SoundGUI扩展了KeyAdapter{ 公共静态void main(字符串[]args){ SoundGUI sGUI=新的SoundGUI(); sGUI.setUp(); } 公共无效设置(){ JFrame=新J

我的主要问题是在设置
JFrame
时出现以下代码:

  • 为什么面板没有显示我是否使用
    pack()
    以及如何使其工作

  • 为什么第一个
    requestFocusInWindow()
    不起作用,使用它的原则是什么

  • 如果删除
    setLayout()
    ,为什么
    JPanel的默认布局管理器不工作


  • 公共类SoundGUI扩展了KeyAdapter{
    公共静态void main(字符串[]args){
    SoundGUI sGUI=新的SoundGUI();
    sGUI.setUp();
    }
    公共无效设置(){
    JFrame=新JFrame(“关键测试”);
    frame.setSize(1000300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    面板p=新面板();
    p、 setLayout(new BorderLayout());//为什么这句话是必需的FlowLayout不填充容器,而是让组件大小调整到其首选大小。
    p、 addKeyListener(此);
    p、 requestFocusInWindow();//这里没有用
    //requestFocus仅适用于显示的可聚焦组件。
    MyDrawPanel dp=新的MyDrawPanel();
    dp.后退背景(颜色:暗灰色);
    JLabel试验=新的JLabel(“试验”);
    JButton t=新JButton(“b”);
    dp.添加(t);
    dp.add(测试);
    p、 添加(dp);
    frame.getContentPane().add(p);
    p、 requestFocusInWindow();
    //frame.pack();//为什么它不工作
    //frame.setVisible(true);
    }
    类MyDrawPanel扩展了JPanel{
    公共组件(图形g){
    图形2d g2=(图形2d)g;
    g2.设置颜色(颜色为白色);
    对于(int i=0;i<1000;i+=42){
    g2.fill3DRect(i,100,20,80,true);
    }
    g2.设置颜色(颜色为黑色);
    对于(int i=21;i<1000;i+=42){
    g2.fill3DRect(i,100,20,80,true);
    }
    }
    }
    } 
    
    建议:

    • 在调用
      pack()
      之后调用
      setVisible(true)
      。有道理,不是吗
    • BorderLayout将告诉MyDrawPanel填充p容器,因为组件是以默认方式添加的(意思是BorderLayout.CENTER),BorderLayout就是这样工作的
    • FlowLayout不填充容器,而是允许组件按照其首选大小调整大小
    • 不要将Swing与AWT组件混合使用。i、 例如,不要使用面板,而是使用JPanel
    • requestFocus仅适用于显示的可聚焦组件
    • 使用键绑定比使用键侦听器更好
    • 如果可能,最好避免设置任何东西的大小

    根据您的新代码,您的问题是由于您正在调用
    setSize()
    。大多数布局经理并不尊重这一点,而是尊重首选的尺寸。如果你的画JPanel需要这么大,那么就让它这么大。例如,请尝试:

    class MyDrawPanel extends JPanel {
      private static final int PREF_W = 1000;
      private static final int PREF_H = 300;
    
      public void paintComponent(Graphics g) {
         super.paintComponent(g); //!!   ******** don't forget this!!! *********
         Graphics2D g2 = (Graphics2D) g;
         g2.setColor(Color.white);
         for (int i = 0; i < 1000; i += 42) {
            g2.fill3DRect(i, 100, 20, 80, true);
         }
         g2.setColor(Color.black);
         for (int i = 21; i < 1000; i += 42) {
            g2.fill3DRect(i, 100, 20, 80, true);
         }
      }
    
      // the getPReferredSize will make this JPanel preferentially be this size
      @Override
      public Dimension getPreferredSize() {
         return new Dimension(PREF_W, PREF_H);
      }
    }
    
    但也要注意,应该避免使用KeyListener。改为使用密钥绑定。

    建议:

    • 在调用
      pack()
      之后调用
      setVisible(true)
      。有道理,不是吗
    • BorderLayout将告诉MyDrawPanel填充p容器,因为组件是以默认方式添加的(意思是BorderLayout.CENTER),BorderLayout就是这样工作的
    • FlowLayout不填充容器,而是允许组件按照其首选大小调整大小
    • 不要将Swing与AWT组件混合使用。i、 例如,不要使用面板,而是使用JPanel
    • requestFocus仅适用于显示的可聚焦组件
    • 使用键绑定比使用键侦听器更好
    • 如果可能,最好避免设置任何东西的大小

    根据您的新代码,您的问题是由于您正在调用
    setSize()
    。大多数布局经理并不尊重这一点,而是尊重首选的尺寸。如果你的画JPanel需要这么大,那么就让它这么大。例如,请尝试:

    class MyDrawPanel extends JPanel {
      private static final int PREF_W = 1000;
      private static final int PREF_H = 300;
    
      public void paintComponent(Graphics g) {
         super.paintComponent(g); //!!   ******** don't forget this!!! *********
         Graphics2D g2 = (Graphics2D) g;
         g2.setColor(Color.white);
         for (int i = 0; i < 1000; i += 42) {
            g2.fill3DRect(i, 100, 20, 80, true);
         }
         g2.setColor(Color.black);
         for (int i = 21; i < 1000; i += 42) {
            g2.fill3DRect(i, 100, 20, 80, true);
         }
      }
    
      // the getPReferredSize will make this JPanel preferentially be this size
      @Override
      public Dimension getPreferredSize() {
         return new Dimension(PREF_W, PREF_H);
      }
    }
    

    但也要注意,应该避免使用KeyListener。改为使用键绑定。

    并使用轻而不是重的组件。注意:Swing组件通常以J开头。我想你最终会找到它;)非常感谢。但是设置哪个组件是可见的?看来那个包还是不好work@user2870532:您可能需要为我们创建并发布一个,以便我们完全了解您的问题。并使用轻而不是重的组件。注意:Swing组件通常以J开头。我想您最终会找到它;)非常感谢。但是设置哪个组件是可见的?看来那个包还是不好work@user2870532:您可能需要创建并发布一个供我们充分了解您的问题的面板。如果您没有将面板添加到屏幕上实际显示的任何内容中,并且用户可以使用,为什么
    requestFocus
    可以工作…或者您只是不喜欢您的用户…为什么应该
    requestFocus
    在您没有实际将面板添加到屏幕上实际显示的任何内容以及用户可以使用的内容时工作……或者您只是不喜欢您的用户。。。
      JPanel p = new JPanel(); //!! This should be a JPanel, not a Panel
      p.setFocusable(true); //!! This is needed
      p.setLayout(new BorderLayout());
      p.addKeyListener(this);
      p.requestFocusInWindow();