【问题标题】:JFrame pack() and requestFocus() is not workingJFrame pack() 和 requestFocus() 不工作
【发布时间】:2014-02-26 03:01:52
【问题描述】:

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

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

  2. 为什么第一个requestFocusInWindow()不行,使用原理是什么?

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


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

【问题讨论】:

  • 为什么requestFocus 应该在您没有实际添加面板到任何实际显示在屏幕上并且可供用户使用的任何内容时工作...或者您只是不喜欢您的用户.. .

标签: java swing jpanel paintcomponent preferredsize


【解决方案1】:

建议:

  • 致电setVisible(true)之后致电pack()。有道理,不是吗?
  • BorderLayout 将告诉 MyDrawPanel 填充 p 容器,因为组件是以默认方式添加的(即 BorderLayout.CENTER),这就是 BorderLayout 的工作方式。
  • FlowLayout 不会填充容器,而是让组件调整到它们的preferredSizes。
  • 不要将 Swing 与 AWT 组件混合使用。即,不要使用面板,而是使用 JPanel。
  • requestFocus 仅适用于显示的可聚焦组件。
  • 使用键绑定比使用 KeyListener 更好。
  • 如果可能,最好避免设置任何东西的大小。

根据您的新代码,您的问题是由于您正在调用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();

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

【讨论】:

  • 并使用轻而不重的组件
  • 该注释的扩展:Swing 组件通常以 J 开头。
  • 以为你最终会解决它;)
  • 谢谢。但是设置哪个组件可见?看来这个包还是不行
  • @user2870532:您可能需要创建并发布minimal, compilable and runnable example program 才能让我们充分了解您的问题。
猜你喜欢
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多