【问题标题】:JFrame Button Logic errorJFrame按钮逻辑错误
【发布时间】:2013-08-03 01:40:28
【问题描述】:

我一直在花一些时间重新学习 java,但这里出现了一个特殊的逻辑错误。

import javax.swing.*;
import java.awt.*;

class Frame
{
    public static void main (String args[])
    {

        JFrame frame = new JFrame("Tester Frame");
        frame.setSize(400, 500);

        JButton btn1 = new JButton("FOO");
        btn1.setSize(150, 50);
        btn1.setLocation(45, 0);

        JButton btn2 = new JButton("BAR");
        btn2.setSize(150, 50);
        btn2.setLocation(205, 0);

        Container content = frame.getContentPane();
        content.setBackground(Color.blue);
        content.add(btn1);
        content.add(btn2);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }//end main                                                                                                         
}

我创建了 2 个 JButton 对象,它们应该大小相同,位置和文本不同。当然不是这样,“FOO”按钮正是我想要的位置和方式,但“BAR”按钮是整个框架的大小。

救命!

【问题讨论】:

    标签: java swing layout jframe jbutton


    【解决方案1】:

    1) 您正在尝试通过setSizesetLocation 等使用Absolute LayoutManager,但没有在要添加JButtons 的组件上调用setLayout(null)但这并不是 Swing 中的最佳做法

    添加到JFramecontentpane默认布局是BorderLayout,添加组件到默认位置BorderLayout.CENTER

    阅读A Visual Guide to Layout Managers

    2) 此外,当使用正确的 LayoutManager 时,您将省略 JFrame#setSize(..) 调用并将其替换为 JFrame#pack(),然后再设置 JFrame 可见。

    3) 还可以阅读 Concurrency in Swing,特别是 The Event Dispatch Thread 这规定所有摇摆组件都通过 SwingUtillities.invokeXXX(..) 块在 EDT 上创建:

    SwingUtilities.invokeLater(new Runnable() {
       @Override
        public void run() {
             //create and manipulate swing components here
        }
    });
    

    4) 还不如使用JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);,因为这将允许任何其他线程计时器等在JFrame 已被释放后继续执行。

    【讨论】:

      【解决方案2】:

      添加:

      frame.getContentPane().setLayout(null);
      

      到你的代码行后:

      frame.setSize(400, 500);
      

      【讨论】:

      • 这不是应该使用 Absolute 以外的适当布局管理器的正确方法
      • 这取决于你的愿望。他专门尝试自己调整按钮的大小和位置。他不是在问一个更好的方法来布置它们,他是在问为什么它们没有被正确放置和尺寸。我以我认为他想要的方式回答了他的问题。建议其他替代方案很好 - 他会选择他认为有用的信息。
      • OP 可以手动通过setXXXSize 调整JButton 的大小,或者在使用符合他需要的LayoutManager 时覆盖getXXXSize
      • 实际上,大多数 LayoutManagers 都会忽略你的 setSize()。而且当使用 LM 时,你不能指定你想要的东西——你必须建立它们。再一次,我试图以我认为他想要的方式回答他的问题。如果你有不同的意见 - 很好。这就是 SO 的意义所在。他会选择哪些信息可以解决他的问题。
      • 如您所见,我没有指定 setSize 方法...。setXXXSize 或覆盖 getXXXSizesetPreferredSizesetMamximumSizegetPreferredSize 等。请参阅 this Question and its answers特别是thisthis answer
      【解决方案3】:

      添加到容器的组件在列表中进行跟踪。列表的顺序将定义容器内组件的从前到后的堆叠顺序。如果在将组件添加到容器时未指定索引,它将被添加到列表的末尾(因此到堆叠顺序的底部)。在您的代码中,按钮堆叠在另一个上。这就是为什么您得到这个错误(如你所想)。 这将解决您的问题:-

      import javax.swing.*;
      
      import java.awt.*;
      
      class OP3
      {
          public static void main (String args[])
          {
      
          JFrame frame = new JFrame("Tester Frame");
          frame.setSize(400, 500);
      
          JButton btn1 = new JButton("FOO");
          btn1.setSize(150, 50);
          btn1.setLocation(45, 0);
      
              JButton btn2 = new JButton("BAR");
          btn2.setSize(150, 50);
          btn2.setLocation(205, 0);
      
             JPanel p  = new JPanel(new FlowLayout());
             p.add(btn1);
             p.add(btn2);
             frame.add(p);
      
      
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setVisible(true);
          }//end main                                                                                                         
      }
      

      【讨论】:

        【解决方案4】:

        只需将面板添加到框架中,然后将按钮添加到面板中。

        import javax.swing.*;
        
        import java.awt.*;
        
        class source
        {
           public static void main (String args[])
           {
        
           JFrame frame = new JFrame("Tester Frame");
           frame.setSize(400, 500);
        
           JPanel panel=new JPanel();//panel added here
           panel.setSize(frame.size());
           panel.setLocation(0, 0);
        
           JButton btn1 = new JButton("FOO");
           btn1.setSize(150, 50);
           btn1.setLocation(45, 0);
        
           JButton btn2 = new JButton("BAR");
           btn2.setSize(150, 50);
           btn2.setLocation(205, 0);
        
           panel.add(btn1);
           panel.add(btn2);
        
           Container content = frame.getContentPane();
           content.setBackground(Color.blue);
           content.add(panel);
        
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }//endmain                                                                                                         
        

        【讨论】:

        • 绝对 LayoutManager 不是构建体面的摇摆 GUI 时的最佳实践
        • @David Kroukamp 好的,谢谢。我知道基本的 JAVA,所以我尽我所能提供帮助。我将阅读有关绝对 LayoutManager 的更多信息。
        猜你喜欢
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多