使用继承的 Java 中的基本窗口和扩展窗口




我有一个名为WindowTemplate的类,它是其他(更复杂的(窗口的基础。这是一个抽象类,然后我尝试使用"扩展"技巧向新窗口添加更多内容,保留原始"骨架"。
这是我的问题,因为如果我运行 WindowTemplate.createWindow((; 或 a_Welcome.createWindow((; (它们应该指向同一件事(,我会得到我的"基本"窗口。但是当我运行a_Welcome窗口 = new a_Welcome((; (应该是基础 + 新东西(时,我只得到我添加的额外位,而没有原始功能。
这是我的代码:

package windows;
import java.awt.*;
import javax.swing.*;
public abstract class WindowTemplate extends JFrame {
/**
 * Create the GUI and show it. For thread safety, this method should be
 * invoked from the event-dispatching thread.
 */
public static void createWindow() {
    JFrame myFrame = new JFrame("My first window");
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myFrame.setVisible(true);
    myFrame.setSize(550, 450);
    myFrame.setLocationRelativeTo(null);
    // JLabel emptyLabel = new JLabel("");
    // emptyLabel.setPreferredSize(new Dimension(550, 450));
    // myFrame.getContentPane().setLayout(new CardLayout());
    // myFrame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
    // myFrame.pack();
}
} 

具有新窗口和一些额外内容的类(忽略a_(:

package windows;
import java.awt.*;
import javax.swing.*;
public class a_Welcome extends WindowTemplate {
public a_Welcome() {
    JPanel area = new JPanel();
    JLabel text = new JLabel("One line another line and another line"); // , JLabel.CENTER);
    // text.setBounds(80, 400, 400, 50);
    add(area);
    // area.setLayout(null);
    area.add(text, new CardLayout());
    // area.add(text); // , BorderLayout.CENTER);
    Font font = new Font("SansSerif", Font.BOLD, 30);
    text.setFont(font);
    text.setForeground(Color.green);
    area.setBackground(Color.darkGray);
    area.setSize(550, 450);
}
}
// timer-after 5 seconds-go to the next window (countdown in the bottom right corner)

和主要:

package windows;
public class Launcher {
public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // WindowTemplate.createWindow();
            // a_Welcome.createWindow();
             a_Welcome window = new a_Welcome();
             window.setVisible(true);
        }
    });
}
}


感谢您的帮助!

静态方法createWindow()总是创建一个新的JFrame,它不是WindowTemplate的超类。a_Window的构造函数正在将组件添加到尚未初始化的WindowTemplate,因为静态createWindow()创建了一个独立的帧。

我建议您将静态createWindow()更改为构造函数WindowTemplate并再次尝试运行main

package windows;
import java.awt.*;
import javax.swing.*;
public abstract class WindowTemplate extends JFrame {
/**
 * Create the GUI and show it. For thread safety, this method should be
 * invoked from the event-dispatching thread.
 */
public WindowTemplate () {
    JFrame myFrame = new JFrame("My first window");
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myFrame.setVisible(true);
    myFrame.setSize(550, 450);
    myFrame.setLocationRelativeTo(null);
    // JLabel emptyLabel = new JLabel("");
    // emptyLabel.setPreferredSize(new Dimension(550, 450));
    // myFrame.getContentPane().setLayout(new CardLayout());
    // myFrame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
    // myFrame.pack();
}
}

你在静态 createWindow(( 方法中定义了另一个 JFrame。 这意味着您将组件添加到此框架中,该框架的作用域仅为 createWindow(( 方法,并且在要添加到a_Welcome实例的构造函数中。

你应该做这样的事情

public class BaseWindow() {
  //Constructor
  public BaseWindow() {
    init();
  }
  public void init() {
    //add basic components
  }
}

public class SubClassWindow() {
  public SubClassWindow() {
    super();
  }
  @Override
  public void init() {
    super.init(); //important so you get the base stuff
    //add other components
  }
}

代码未测试。

您可以考虑的另一种方法是拥有一个只是一个包装器的 JFrame,并通过添加面板来组成窗口。 假设您希望在要创建的每个窗口的顶部都有一个工具栏。 每个窗口在工具栏上都有不同的按钮,在底部都有一组不同的组件。 这样你就是在做组合而不是继承,因为继承以后会变得丑陋。 (有关这一点的讨论,请参阅此,此和此

(

这看起来像这样:

public interface AppPanel {
  List<JButton> getToolbarButtons();
  boolean okToClose();
  JPanel getGui();
}
public MyPanel extends JPanel implements AppPanel {
  //standard swing components stuff set up here
  public List<JButton> getToolbarButtons() {
    //set up buttons and their actions
    return buttonList;
  }
  public boolean okToClose() {
    //ask user if they want to save, etc.
    return true;
  }
  public JPanel getGui() {
    return this;
  }
}
public AppFrame extends JFrame {
  private AppPanel panel;
  public static AppFrame createFrame(AppPanel panel) {
    AppFrame frame = new AppFrame(panel);
    return frame;
  }
  public AppFrame(AppPanel panel) {
    super();
    this.panel = panel;
    add(panel.getGui(), someLayoutConstraints);
    panel.getToolbarButtons(); //do stuff with the buttons
    //...
    this.addWindowListener(new WindowAdapter() {
      public void WindowClosing(WindowEvent e) {
        if (panel.isOkToClose()) {
          setVisible(false);
        }
      }
    });
  }

}

相关内容

  • 没有找到相关文章

最新更新