如何在不覆盖的情况下添加同一JPanel类的不同实例

How to add different instances of the same JPanel class without overwriting

本文关键字:实例 JPanel 情况下 覆盖 添加      更新时间:2023-09-26

因此,我遇到的问题是,我创建了一个扩展JPanel的类(如下所示),并试图将该JPanel类的多个实例添加到另一个JPanel类别中。

public class DOBGui extends JPanel {
  private static String dayList[] = {bunch of days};
  private static JComboBox dobDay = new JComboBox(dayList);
  private static String monthList[] = {bunch of months};
  private static JComboBox dobMonth = new JComboBox(monthList);
  private static String yearList[] = {bunch of dates};
  private static JComboBox dobYear = new JComboBox(yearList);
  public static String DOBString() {
    int dayInt = dobDay.getSelectedIndex() + 1;
    int monthInt = dobMonth.getSelectedIndex() + 1;
    String year = dobYear.getSelectedItem().toString();
    String day = "" + dayInt;
    if (day.length() == 1) {
      day = "0" + day;
    }
    String month = "" + monthInt;
    if (month.length() == 1) {
      month = "0" + month;
    }
    return day + month + year;
  }
  public DOBGui() {
    add(dobDay);
    add(dobMonth);
    add(dobYear);
  }
  void reset() {
    dobDay.setSelectedIndex(0);
    dobMonth.setSelectedIndex(0);
    dobYear.setSelectedIndex(0);
  }
}

我试图通过创建DOBGui类的两个实例将这个JPanel添加到另一个JPanel类中两次,但它覆盖了第一个实例。

questionsPanel.add(new JLabel("Date for budget skills training session"), "wrap");
DOBGui budgetSkillsDate = new DOBGui();
budgetSkillsDate.reset();
questionsPanel.add(budgetSkillsDate, "wrap");
questionsPanel.add(new JLabel("Date for cooking course training session"), "wrap");
DOBGui cookingCourseDate = new DOBGui();
cookingCourseDate.reset();
questionsPanel.add(cookingCourseDate, "wrap");

这是因为您定义的所有字段都是静态类型的。现在,当你在面板1上调用重置时,你会调用:

 void reset() {
    dobDay.setSelectedIndex(0);
    dobMonth.setSelectedIndex(0);
    dobYear.setSelectedIndex(0);
 }

您重置日期、月份、年份。然后你把它设置回来,然后对于第二个面板,你调用reset,这意味着你只有一个dobDay、dobMonth、dobYear的实例,所有面板都只使用一个实例。

简短的版本是:字段不应该是静态的。

静态字段不是对象(实例)的一部分,而是类的一部分。典型的例子是具有序列号的对象。"序列号"字段对于每个实例都是唯一的,因此它必须是一个实例字段。但是,包含"下一个要给出的序列号"的字段属于类,而不属于任何实际实例,并且在创建新实例的过程中使用。

当编译器告诉您"不能从静态上下文访问非静态XXX"时,在大多数情况下,这并不意味着您应该将XXX转换为静态。这意味着您应该使用类的实例,而不是整个类。

你打算DOBString()做什么?您的代码中没有文档,但我猜这是为了给您提供子组件所选日期的字符串表示。但是,对于每个DOBGui对象来说,这个日期不是不同吗?如果应用程序中同时有两个DOBGui对象,并且用户在其中一个对象中选择2014年1月15日,在另一个中选择1969年7月28日,则DOBString()应为第一个对象返回与第二个对象不同的字符串。调用DOBGui.DOBString()毫无意义,因为它应该在什么日期返回?第一个还是第二个?一般默认日期?

因此,所有应该成为单个面板一部分的东西(字段和访问它们或对它们执行操作的方法)都应该是静态的。不是字段,也不是方法。

那么,你的事件监听器呢?好吧,你希望它显示哪个面板的日期?如果您希望它显示budgetSkillsDate的日期,那么它应该调用budgetSkillsDate.DOBString()。为了实现这一点,budgetSkillsDate不应该是局部变量,而应该是创建它的方法和侦听器都可以访问的字段。

重要的是,它必须是DOBGui实例,而不是DOBGui,因为这没有任何意义——类不应该表示日期。这是实例应该做的。

注:

  • 方法名称不应以大写字母开头。只有类型名称以大写字母开头。语法高亮显示者希望它是这样的,所以如果你不遵守惯例,它就会变得令人困惑
  • 您的代码中确实应该有更多的文档。当代码中没有一条注释时,很难猜测你想做什么