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

时间:2014-02-26 03:01:53

标签: java swing jpanel paintcomponent preferredsize

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

  1. 为什么面板无法显示我是否使用pack()以及如何使其有效?

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

  3. 如果我删除JPanel,<{1}}的默认布局管理器无法正常工作?


  4. setLayout()

1 个答案:

答案 0 :(得分:5)

建议:

  • 在 致电setVisible(true)后致电pack() 。有道理,不是吗?
  • BorderLayout将告诉MyDrawPanel填充p容器,因为组件是以默认方式添加的(意思是BorderLayout.CENTER),这就是BorderLayout的工作方式。
  • FlowLayout不会填充容器,而是将组件大小设置为其preferredSizes。
  • 不要将Swing与AWT组件混合使用。即,不要使用Panels,而是使用JPanels。
  • requestFocus仅适用于显示的可聚焦组件。
  • 最好使用Key Bindings而不是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);
  }
}

另请注意,如果组件具有焦点,请求焦点 有效:

  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();

但请注意,应避免使用KeyListeners。改为使用键绑定。