Java 构建动态JPanel的最佳方法

Java 构建动态JPanel的最佳方法,java,swing,design-patterns,user-interface,jpanel,Java,Swing,Design Patterns,User Interface,Jpanel,我正在构建一个包含多个字段的JPanel,但根据产品,字段可能会有所不同。每个产品都有一些通用字段和一些特定字段。 使用一些接口,可以将字段分组,以使用所有需要的字段构建引用的JPanel,如下所示: public class VPNProduct extends JPanel implements VPNFields{ //use and positioning of the fields } interface VPNFields extends CommonFields{

我正在构建一个包含多个字段的JPanel,但根据产品,字段可能会有所不同。
每个产品都有一些通用字段和一些特定字段。 使用一些接口,可以将字段分组,以使用所有需要的字段构建引用的JPanel,如下所示:

public class VPNProduct extends JPanel implements VPNFields{
    //use and positioning of the fields
}

interface VPNFields extends CommonFields{
    //particular VPN fields
}

interface CommonFields{
    //fields common to all products
}
我的问题是,有一些最佳实践或技术使它更容易或更有条理,包括字段在面板中的位置


提前谢谢。

我认为这不是一个好方法,因为我不知道你用什么类型的字段,所以制作了一些虚构的字段,如
JLabel
s,请看一看。我希望这能从我的角度解释我试图提供的内容,并为您提供一个可供参考的小方向:-)


我想这不是一个好方法,因为我不知道你用什么类型的字段,所以做了一些虚构的字段,如
JLabel
s,请看一看。我希望这能从我的角度解释我试图提供的内容,并为您提供一个可供参考的小方向:-)


有一些优雅的方法可以做到这一点。首先,一个接口将具有访问字段的get/set方法。因此,您将为您的公共字段和其他字段提供一个接口。公共字段接口(因为它将被共享)应该被实现为一个抽象类。这个抽象类将扩展JPanel,构造JLabel、JComboxes等,并在布局管理器中进行布局

然后,对于需要添加更多字段的任何其他类,您将创建一个类,并让它扩展您的抽象类(因此,现在它是一个JPanel,包含所有已创建和布局的公共字段),并使用您的额外字段实现一个接口。这些额外字段必须创建它们的Swing组件,并将它们添加到当前具有公共字段的布局管理器中

如果您提供一些领域的例子或给我们一个结构的提示,我可以起草一些代码样本,以便您可以看到

一个代码示例显示了可用于公司和学校的公共字段,以及我们如何创建2个JFrames,其中所有表单均源自1个JPanel抽象类:

package stackoverflow.test;

public interface CommonFields {

    public void setName(String name);

    public void setLastName(String lastName);

    public void setAge(int age);

    public String getName();

    public String getLastName();

    public int getAge();
}
-

-

-

-

-

-


有一些优雅的方法可以做到这一点。首先,一个接口将具有访问字段的get/set方法。因此,您将为您的公共字段和其他字段提供一个接口。公共字段接口(因为它将被共享)应该被实现为一个抽象类。这个抽象类将扩展JPanel,构造JLabel、JComboxes等,并在布局管理器中进行布局

然后,对于需要添加更多字段的任何其他类,您将创建一个类,并让它扩展您的抽象类(因此,现在它是一个JPanel,包含所有已创建和布局的公共字段),并使用您的额外字段实现一个接口。这些额外字段必须创建它们的Swing组件,并将它们添加到当前具有公共字段的布局管理器中

如果您提供一些领域的例子或给我们一个结构的提示,我可以起草一些代码样本,以便您可以看到

一个代码示例显示了可用于公司和学校的公共字段,以及我们如何创建2个JFrames,其中所有表单均源自1个JPanel抽象类:

package stackoverflow.test;

public interface CommonFields {

    public void setName(String name);

    public void setLastName(String lastName);

    public void setAge(int age);

    public String getName();

    public String getLastName();

    public int getAge();
}
-

-

-

-

-

-


什么是“场”?这些是JLabel/JTextField组合吗?我认为在类层次结构或“接口标记”中实现特定的产品/分组不是一个好主意,因为最终会得到太多的类。如果我正确理解你的问题:我可能会通过一些算法/注入到一些规格图中。你们有多少产品在扫描仪下?如果所谓的产品具有与普通产品相同的
JPanel
,并且基于排列和组合技术,那么您知道最多两个或三个
JPanel
正是您所需要的。然后,您可以事先制作这些文件,并根据需要使用它们,而不是动态制作。@HovercraftFullOfEels JTextfields、JComboBox和JCheckBox。@Elias:我可以想到这个场景。比如说,我选择了一个产品,现在我将获得
JPanel
上的公共字段,并将其添加到我的产品
JPanel
,在某个位置,布局设置为
GridLayout
,其中
0行1列,现在,我将向另一个
JPanel
添加额外的
字段
,并将此
JPanel
再次添加到我的产品
JPanel
所在的位置,该位置具有
GridLayout
,以便可以轻松添加,并且看起来也很漂亮。这还不够好吗?什么是“场”?这些是JLabel/JTextField组合吗?我认为在类层次结构或“接口标记”中实现特定的产品/分组不是一个好主意,因为最终会得到太多的类。如果我正确理解你的问题:我可能会通过一些算法/注入到一些规格图中。你们有多少产品在扫描仪下?如果所谓的产品具有与普通产品相同的
JPanel
,并且基于排列和组合技术,那么您知道最多两个或三个
JPanel
正是您所需要的。然后,您可以事先制作这些文件,并根据需要使用它们,而不是动态制作。@HovercraftFullOfEels JTextfields、JComboBox和JCheckBox。@Elias:我可以想到这个场景。比如说,我选择了一个产品,现在我将获得
JPanel
上的公共字段,并将其添加到我的产品
JPanel
,在某个位置,布局设置为
GridLayout
,其中
0行1列,现在,我将向另一个
JPanel
添加额外的
字段
,并将此
JPanel
再次添加到我的产品
JPanel
所在的位置
package stackoverflow.test;

public interface SchoolFields {

    public void setSchoolName(String schoolName);

    public void setGrade(int grade);

    public void setHonorsProgram(boolean isHonors);

    public String getSchoolName();

    public int getGrade();

    public boolean hasHonorsProgram();
}
package stackoverflow.test;

public interface CompanyFields {

    public void setCompanyName(String companyName);

    public void setJobTitle(String jobTitle);

    public void setAddress(String address);

    public String getCompanyName();

    public String getJobTitle();

    public String getAddress();
}
package stackoverflow.test;

import java.awt.GridLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AbstractJPanel extends JPanel implements CommonFields {

    private static final long serialVersionUID = 150030761086805569L;

    private JTextField nameField = null;
    private JTextField lastNameField = null;
    private JTextField ageField = null;
    private JLabel nameLabel = null;
    private JLabel lastNameLabel = null;
    private JLabel ageLabel = null;


    public AbstractJPanel() {
        super(new GridLayout(0, 2));

        nameField = new JTextField();
        lastNameField = new JTextField();
        ageField = new JTextField();

        nameLabel = new JLabel("Name: ");
        lastNameLabel =new JLabel("Last Name: ");
        ageLabel = new JLabel("Age: ");

        add(nameLabel);
        add(nameField);
        add(lastNameLabel);
        add(lastNameField);
        add(ageLabel);
        add(ageField);
    }

    public void setName(String name) {
        nameField.setText(name);
    }

    public void setLastName(String lastName) {
        lastNameField.setText(lastName);
    }

    public void setAge(int age) {
        ageField.setText(""+age);
    }

    public String getName() {
        return nameField.getText();
    }

    public String getLastName() {
        return lastNameField.getText();
    }

    public int getAge() {
        return Integer.parseInt(ageField.getText());
    }
}
package stackoverflow.test;

import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class SchoolPanel extends AbstractJPanel implements SchoolFields {

    private static final long serialVersionUID = -6201476099194804075L;

    private JTextField schoolNameField = null;
    private JTextField gradeField = null;
    private JCheckBox honorsCheckBox = null;
    private JLabel schoolNameLabel = null;
    private JLabel gradeLabel = null;
    private JLabel honorsLabel = null;

    public SchoolPanel() {
        super();


        schoolNameLabel = new JLabel("School Name: ");
        gradeLabel = new JLabel("Grade: ");
        honorsLabel = new JLabel("Is Honors: ");

        schoolNameField = new JTextField();
        gradeField = new JTextField();
        honorsCheckBox = new JCheckBox();

        add(schoolNameLabel);
        add(schoolNameField);
        add(gradeLabel);
        add(gradeField);
        add(honorsLabel);
        add(honorsCheckBox);
    }

    @Override
    public void setSchoolName(String schoolName) {
        schoolNameField.setText(schoolName);
    }

    @Override
    public void setGrade(int grade) {
        gradeField.setText(""+grade);
    }

    @Override
    public void setHonorsProgram(boolean isHonors) {
        honorsCheckBox.setSelected(isHonors);
    }

    @Override
    public String getSchoolName() {
        return schoolNameField.getText();
    }

    @Override
    public int getGrade() {
        return Integer.parseInt(gradeField.getText());
    }

    @Override
    public boolean hasHonorsProgram() {
        return honorsCheckBox.isSelected();
    }
}
package stackoverflow.test;

import javax.swing.JLabel;
import javax.swing.JTextField;

public class CompanyPanel extends AbstractJPanel implements CompanyFields {

    private static final long serialVersionUID = 7834845724312492112L;

    private JTextField companyNameField = null;
    private JTextField jobTitleField = null;
    private JTextField addressField = null;
    private JLabel companyNameLabel = null;
    private JLabel jobTitleLabel = null;
    private JLabel addressLabel = null;

    public CompanyPanel() {
        super();

        companyNameLabel = new JLabel("Company Name: ");
        jobTitleLabel = new JLabel("Job Title: ");
        addressLabel = new JLabel("Address: ");

        companyNameField = new JTextField();
        jobTitleField = new JTextField();
        addressField = new JTextField();

        super.add(companyNameLabel);
        super.add(companyNameField);
        super.add(jobTitleLabel);
        super.add(jobTitleField);
        super.add(addressLabel);
        super.add(addressField);
    }

    @Override
    public void setCompanyName(String companyName) {
        companyNameField.setText(companyName);
    }

    @Override
    public void setJobTitle(String jobTitle) {
        jobTitleField.setText(jobTitle);
    }

    @Override
    public void setAddress(String address) {
        addressField.setText(address);
    }

    @Override
    public String getCompanyName() {
        return companyNameField.getText();
    }

    @Override
    public String getJobTitle() {
        return jobTitleField.getText();
    }

    @Override
    public String getAddress() {
        return addressField.getText();
    }

}
package stackoverflow.test;

import java.awt.BorderLayout;

import javax.swing.JFrame;

public class MainClass {

    public MainClass() {
        JFrame frame1 = new JFrame();
        frame1.setLayout(new BorderLayout());
        frame1.add(new CompanyPanel());
        frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame1.setSize(500, 500);
        frame1.setVisible(true);


        JFrame frame2 = new JFrame();
        frame2.setLayout(new BorderLayout());
        frame2.add(new SchoolPanel());
        frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame2.setSize(500, 500);
        frame2.setVisible(true);
    }


    public static final void main(String ... args) {
        new MainClass();
    }
}