JFrame pack()和requestFocus()不起作用

Ton*_*ony 1 java swing jpanel paintcomponent preferredsize

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

  1. 为什么面板不显示我是否使用它pack()以及如何使其工作?

  2. 为什么第一个requestFocusInWindow()不起作用,使用它的原理是什么?

  3. JPanel如果我删除了默认布局管理器为什么不起作用setLayout()


public class SoundGUI extends KeyAdapter{

public static void main(String[] args) {
    SoundGUI sGUI = new SoundGUI();
    sGUI.setUp();
}
public void setUp () {
    JFrame frame = new JFrame ("Key test");
    frame.setSize (1000, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);

    Panel p = new Panel ();
    p.setLayout(new BorderLayout());//why this sentence is necessary  FlowLayout doesn't fill the container but rather lets components size to their preferredSizes.
    p.addKeyListener (this);
    p.requestFocusInWindow();//it's useless here
    //requestFocus only works on focusable components that are displayed.
    MyDrawPanel dp = new MyDrawPanel();
    dp.setBackground(Color.darkGray);

    JLabel test = new JLabel("a trial");
    JButton t = new JButton("b");
    dp.add(t);
    dp.add (test);
    p.add (dp);     
    frame.getContentPane().add(p);
    p.requestFocusInWindow();
    //frame.pack();//why it doesn't work
    //frame.setVisible(true);
}
class MyDrawPanel extends JPanel { 
    public void paintComponent (Graphics g) {
        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);
        }
    }
}
} 
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 5

建议:

  • 打电话setVisible(true) 打电话pack().有道理,不是吗?
  • BorderLayout将告诉MyDrawPanel填充p容器,因为组件是以默认方式添加的(意思是BorderLayout.CENTER),这就是BorderLayout的工作方式.
  • FlowLayout不会填充容器,而是将组件大小设置为其preferredSizes.
  • 不要将Swing与AWT组件混合使用.即,不要使用Panels,而是使用JPanels.
  • requestFocus仅适用于显示的可聚焦组件.
  • 比KeyListeners更好地使用键绑定.
  • 如果可能的话,最好避免设置任何尺寸.

根据您的新代码,您的问题是由于您的来电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);
  }
}
Run Code Online (Sandbox Code Playgroud)

另外请注意,要求重点如果组件是可聚焦的工作:

  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();
Run Code Online (Sandbox Code Playgroud)

但另请注意,应避免使用KeyListeners.请改用键绑定.

  • 并使用轻质不重的组件 (3认同)
  • 该注释的扩展名:Swing组件通常以J开头. (2认同)