动态将JPanel添加到JFrame

4
我在我的Java应用程序中有一个表单,基本上是为了向用户提供来自数据库查询的数据列表。我们考虑使用表格,并填充结果集中的每一行数据。但是,在设计UI时,我和团队决定它看起来不够平滑。所以,我们想着尝试在面板中创建结果的自定义视图。我们希望它看起来像这样:Desired custom view 因此,与其使用表格的行,它将像这样看起来,每个查询都有一个:
我遇到的问题是如何编写代码。我花了很多时间来研究如何向JForm添加组件,因为NetBeans默认设置UI为GroupLayout。因此,我弄清楚了如何使用以下方式添加1个面板:
javax.swing.JLabel idLbl;
 javax.swing.JLabel jLabel1;
 javax.swing.JLabel jLabel3;
 javax.swing.JLabel jLabel5;
 javax.swing.JLabel jLabel7;
 javax.swing.JPanel jPanel1;
 javax.swing.JLabel prefContactLbl;
 javax.swing.JLabel propertyLabel;
    jPanel1 = new javax.swing.JPanel();
    jLabel1 = new javax.swing.JLabel();
    idLbl = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    propertyLabel = new javax.swing.JLabel();
    jLabel5 = new javax.swing.JLabel();
    contactLabel = new javax.swing.JLabel();
    jLabel7 = new javax.swing.JLabel();
    prefContactLbl = new javax.swing.JLabel();

    jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

    jLabel1.setFont(new java.awt.Font("Tahoma", 1, 12));
    jLabel1.setText("Enquiry Id:");
    jLabel1.setName("jLabel"+i);

    idLbl.setText("jLabel2");

    jLabel3.setFont(new java.awt.Font("Tahoma", 1, 12));
    jLabel3.setText("Property:");

    propertyLabel.setText("A property Address in some town with a postcode");

    jLabel5.setFont(new java.awt.Font("Tahoma", 1, 12));
    jLabel5.setText("Contact:");

    contactLabel.setText("A Persons Name ( 01010100011)");

    jLabel7.setFont(new java.awt.Font("Tahoma", 1, 12));
    jLabel7.setText("Prefered Contact:");

    prefContactLbl.setText("Email/Phone");

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(idLbl)
                    .addGap(18, 18, 18)
                    .addComponent(jLabel3)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(propertyLabel))
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addComponent(jLabel7)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(prefContactLbl)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jLabel5)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(contactLabel)))
            .addContainerGap(20, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel1)
                .addComponent(idLbl)
                .addComponent(jLabel3)
                .addComponent(propertyLabel))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel7)
                .addComponent(prefContactLbl)
                .addComponent(jLabel5)
                .addComponent(contactLabel))
            .addContainerGap())
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
     getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(10 , 10, 10)
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addContainerGap(100, Short.MAX_VALUE))
    );

    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(570, Short.MAX_VALUE))
    );

我面临的主要问题是动态添加超过1个组件,我完全不知道该如何处理,因为我能找到的只是设置布局而不是更新它。而且我无法设置多少个.addcomponent,因为它是动态的。真的很困惑如何处理这个问题。

如果很难理解我的意思,那我很抱歉,更容易地理解它,但用语言表达却是一场噩梦。

2个回答

9

从封装一些东西开始会让你的生活变得更容易。创建一个EnquiryPanelJPanel子类,它代表了一个查询条目的视图。在EnquiryPanel中编写代码几乎与您上面粘贴的内容相同,除了它将从构造函数参数填充自身,并且它本身将成为一个JPanel

public class EnquiryPanel extends JPanel {
   public EnquiryPanel(Result dbResult) {
     // your layout code from above, but this is the content pane and
    // the fields are populated from the dbResult object
   }
}

您可以动态地将 EnquiryPanel 的实例添加到一个容器面板中,该面板的布局是垂直的 BoxLayout。我在下面称此容器面板为 ResultsPanel
public class ResultsPanel extends JPanel {
  public ResultsPanel() {
    // Layout our contents vertically
    BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
    this.setLayout(layout);
  }
  // method to iterate over the results from the database
  // construct an EnquiryPanel and add that EnquiryPanel to ourselves
  public void layoutEnquiryResults(ResultCollection results) {
     for (Result result : results) {
        EnquiryPanel eqPanel = new EnquiryPanel(result);
        add(eqPanel);
     }
     revalidate();
  }
}

最后,您需要将ResultsPanel的一个实例添加到您的JFrame中。
ResultsPanel resultsPanel = new ResultsPanel();
resultsPanel.layoutEnquiryResults(myResultSet);
getContentPane().add(resultsPanel);

1
不要使用GroupLayout。通常手动设置约束条件会非常混乱。
相反,我可能会使用垂直BoxLayout。在添加每个面板后,别忘了重新验证(revalidate())父面板。

由于Netbeans似乎会自动设置为GroupLayout,所以只需要执行以下操作: BoxLayout layout = new BoxLayout(getContentPane()); getContentPane().setLayout(layout)就可以了吗? - Vade
感谢 Boxlayout 的提示,结合其他答案解决了我的问题,谢谢。 - Vade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接