8

为什么我们JFrame在构建 Swing 应用程序时需要扩展类。据我所知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

4 回答 4

19

您不需要扩展 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();
         }
      });
   }
}
于 2013-04-07T20:14:56.383 回答
4

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

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 Aand的Has A方法。如果 classA是 class 的一个例子B,我们倾向于使用继承。如果 classA有 class 的实例B,则使用组合,尽管在大多数情况下,继承可以与组合互换。

另一个观点

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

于 2013-04-07T20:06:08.327 回答
2

JFrame在您的应用程序中使用您可以像在代码中那样扩展它或制作一个object as

JFrame frame= new JFrame();

然后你可以做到

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

以任何一种方式进行操作都很容易,但要在 Application 中使用 JFrame 并访问其方法等,您必须使用其中一种方法

于 2013-04-07T20:12:57.463 回答
0

If you want to create a standalone application, you can either extend JPanel or JFrame or create their instance in your class implementation.

As a rule, a standalone application with a Swing-based GUI has at least one containment hierarchy with a JFrame as its root. For example, if an application has one main window and two dialogs, then the application has three containment hierarchies, and thus three top-level containers. http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html?

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

于 2013-10-29T15:49:03.470 回答