【问题标题】:Why do we need to extend JFrame in a swing application?为什么我们需要在 Swing 应用程序中扩展 JFrame?
【发布时间】:2013-03-29 19:54:23
【问题描述】:

为什么我们在构建 Swing 应用程序时需要扩展 JFrame 类。据我所知extends 用于继承基类。以下程序中没有使用JFrame 类的任何功能,但仍对其进行了扩展。我知道我错过了一些信息。是不是JFrame类的一些功能在后台运行。

1) 代码

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JOptionPane;

public class tuna extends JFrame{

   private JTextField item1;
   private JTextField item2;
   private JTextField item3;
   private JPasswordField passwordField;
   Container contentPane ;
   public tuna(){
      super("The title");

      setLayout(new FlowLayout());

      item1 = new JTextField(10);
      contentPane.add(item1);

      item2 = new JTextField("enter text here");
      add(item2);

      item3 = new JTextField("uneditable", 20);
      item3.setEditable(false);
      add(item3);

      passwordField = new JPasswordField("mypass");
      add(passwordField);

      thehandler handler = new thehandler();

      item1.addActionListener(handler);
      item2.addActionListener(handler);
      item3.addActionListener(handler);
      passwordField.addActionListener(handler);
   }

   public static void main(String[] args){
      tuna aye = new tuna();
   }

   private class thehandler implements ActionListener{

      public void actionPerformed(ActionEvent event){
         String string = "";

         if(event.getSource()==item1)
            string=String.format("field 1: %s",event.getActionCommand());
         else if (event.getSource()==item2)
            string=String.format("field 2: %s",event.getActionCommand());
         else if (event.getSource()==item3)
            string=String.format("field 3: %s",event.getActionCommand());
         else if (event.getSource()==passwordField)
            string=String.format("password field is: %", event.getActionCommand());
      }
   }
}

【问题讨论】:

  • 这个问题的前提是错误的。您不必为了使用它而扩展 JFrame。
  • 实际上,您应该扩展 JFrame(也不应该扩展任何其他类,除非您真正增强功能,即实现通过使用/配置无法实现的功能class) - 大多数教程和 Netbeans 都给出了不好的例子:-)

标签: java swing jframe


【解决方案1】:

如果您想创建一个独立的应用程序,您可以扩展 JPanel 或 JFrame 或在您的类实现中创建它们的实例。

通常,具有基于 Swing 的 GUI 的独立应用程序具有至少一个以 JFrame 作为其根的包含层次结构。例如,如果一个应用程序有一个主窗口和两个对话框,则该应用程序具有三个包含层次结构,因此具有三个顶级容器。 http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html?

http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html

【讨论】:

    【解决方案2】:

    在您的代码中首先要注意的是:

    super("The title");
    

    这实际上调用了JFrame 构造函数,并将"The title" 作为标题字符串传递给它。这是在代码中使用 Jframe 功能的一个明确示例。这将构建为您显示的窗口。

    使用add 之类的方法都继承自JFrame 类。这些将Components 添加到JFrame 对象。

    为什么要继承?

    嗯,简单地说,你的类是一个 JFrame,还有更多。当你有一个Is A 操作时,你使用继承。此方法的另一个优点是您的类可以称为 JFrame。那就是:

    JFrame tuna = new tuna();
    // Note: All classes are meant to start with a capital letter.
    

    另一种观点

    请务必注意,您不必严格地从 JFrame 类继承。您可以使用Composition。在这种情况下,你会有类似的东西:

     public class Tuna {
          private JFrame parentWindow;
          // Rest of class.
     }
    

    如上所述,约定是遵循Is AHas A 方法。如果 class A 是 class B 的一个例子,我们倾向于使用继承。如果类A 有一个类B 的实例,那么您使用组合,尽管在大多数情况下,继承可以与组合互换。

    另一个观点

    如 cmets 中所述,在尝试自己实现之前,您应该始终寻找提供此类功能的现有 API。

    【讨论】:

    • 我还有一个问题。当我写 JFrame tuna = new tuna(); 时,我是在创建 JFrame 类的对象还是将 tuna 类称为 JFrame
    • @AmlanKarmakar:你正在做这两件事。您正在创建一个 tuna 对象(应该命名为“Tuna”,因为它是一个类),但由于 Tuna 扩展了 JFrame,它也 是一个 JFrame。它由 JFrame variable 持有,因此该变量将无法引用任何不属于 JFrame 的新方法。顺便说一下,对克里斯的体面回答加分。
    • @HovercraftFullOfEels 每天学习新东西!
    • 一个经验法则是:如果您可以通过 使用 现有的 api 达到相同的效果,则永远不要扩展。因此,您答案的后半部分大部分是 .. 次优的 :-) 而 inheritance is compatible with Composition 完全是错误的
    • @kleopatra 在大多数情况下,您可以使用组合实现与使用继承相同的功能。我相信这是一个完全合理的声明。 OP 的问题是关于为什么我们从 JFrame 上下文中的超类继承。我觉得我已经解释得很好了。我没有考虑 API,现在我将对其进行编辑。
    【解决方案3】:

    您不需要扩展 JFrame,事实上,我们中许多从事 Swing 编程的人都认为扩展这个类。我自己,我尝试扩展我计划改变类的固有行为的类——即,覆盖类的非静态方法之一。由于我很少需要为 JFrame 执行此操作,因此我很少想要扩展它。

    避免扩展它的另一个原因是:如果您稍后想要在 JDialog 或 JOptionPane 或另一个容器中显示您刚刚创建的 GUI 作为复杂 GUI 的一部分,该怎么办?如果你的类扩展了 JFrame,这将很难做到。我自己,我尝试将我的 GUI 类用于创建 JPanel,以便更容易做到。

    基于您的代码的愚蠢示例:

    import javax.swing.*;
    
    // this guy extends *nothing*
    public class TunaExample {
       private static final int COLS = 10;
       private JPanel mainPanel = new JPanel(); // this is what I'll add to contentPane
       private JTextField field1 = new JTextField(COLS);
       private JTextField field2 = new JTextField(COLS);
       private JPasswordField passwordField = new JPasswordField(COLS);
       private JComponent[] allComponents = { new JLabel("Field 1:"), field1,
             new JLabel("Field 2:"), field2, new JLabel("Password:"), passwordField };
    
       public TunaExample() {
          field2.setEditable(false);
          field2.setFocusable(false);
          field1.setText("Field 1");
          field2.setText("Uneditable");
    
          for (JComponent comp : allComponents) {
             mainPanel.add(comp);
          }
       }
    
       public JComponent getMainComponent() {
          return mainPanel;
       }
    
       private static void createAndShowGui() {
          TunaExample tunaExample = new TunaExample();
    
          // creating my JFrame only when I need it and where I need it
          JFrame frame = new JFrame("Tuna Example");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(tunaExample.getMainComponent());
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    【讨论】:

      【解决方案4】:

      在您的应用程序中使用JFrame 您可以像在代码中那样扩展它,或者将object 设为

      JFrame frame= new JFrame();
      

      然后你就可以做到了

      frame.setTitle("Title");
      frame.setLayout(layout);
      

      以任何一种方式都可以轻松完成,但要在应用程序中使用 JFrame 并访问其方法等,您必须使用其中一种方法

      【讨论】:

        猜你喜欢
        • 2018-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        • 1970-01-01
        • 2013-05-14
        • 2022-11-06
        • 1970-01-01
        相关资源
        最近更新 更多