为什么我们需要在swing应用程序中扩展JFrame?

时间:2013-04-07 20:01:50

标签: java swing jframe

为什么在构建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());
      }
   }
}

4 个答案:

答案 0 :(得分:15)

你不需要扩展JFrame,事实上,我们许多做过很多Swing编程的人都会使而不是来扩展这个类。我自己,我尝试扩展我计划改变类的固有行为的类 - 即,覆盖类的非静态方法之一。由于我很少为JFrame做这个,我很少想扩展它。

避免扩展它的另一个原因:如果您以后想要在JDialog或JOptionPane或其他容器中创建GUI作为复杂GUI的一部分,该怎么办?如果你的类扩展了JFrame,那将很难做到。我自己,我尝试将我的GUI类设置为创建JPanels,这样做更容易。

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

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

答案 1 :(得分:4)

您的代码中要注意的第一件事是:

super("The title");

这实际上调用JFrame构造函数,并将其作为标题String传递给它"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方法。如果类A是类B的示例,我们倾向于使用继承。如果类A具有类B的实例,那么您使用合成,尽管在大多数情况下,继承可以与Composition互换。

另一个观点

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

答案 2 :(得分:2)

在您的应用程序中使用JFrame您可以像在代码中一样对其进行扩展,或者将object设为

JFrame frame= new JFrame();

然后你可以做到

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

以任何一种方式执行它,因为您很容易但是在Application中使用JFrame并访问其方法等,您必须使用这些方法之一

答案 3 :(得分:0)

如果要创建独立应用程序,可以扩展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