2015-11-25 46 views
2

我试图使JPanel(“父面板”)的内容从顶部向底部添加,并有宽度每个组件的高度与父面板的宽度相匹配,同时每个组件的高度都包含内容。内容将被动态生成。JPanel与儿童匹配的父宽度和包装的高度

这是想什么我它看起来像:

enter image description here

这已经很容易在Android中的事。我已经看过Swing LayoutManagers,但他们似乎都不是一个明显的选择。我试过使用Boxlayout(垂直),除了没有填充父面板宽度的面板(这使得它看起来非常糟糕)之外,它的工作原理。

感谢您的任何建议!

编辑:

由于camickr的答案,我想它了。如果将来有助于任何人,我已经提供了我的代码和屏幕截图。

该解决的问题中的代码:

(注为GridBagConstraints的使用的GridBagLayout,BorderLayout的和参数)

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.Random; 

import javax.swing.BorderFactory; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class Test extends JFrame{ 

    private final Color darkGreen = Color.decode("#388E3C"); 
    private final Color green = Color.decode("#4CAF50"); 
    private final Color lightGreen = Color.decode("#C8E6C9"); 

    public static void main(String[] args){ 
     Test test = new Test(); 
     test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    int noOfTitles = 4; 
    int noOfSubTitles = 3; 
    Random random = new Random(); 

    public Test(){ 


     JPanel parentPanel = new JPanel(); 
     this.setSize(new Dimension(300,800)); 
     this.setContentPane(parentPanel); 
     parentPanel.setBackground(Color.white); 

     //Set layout of parent panel to Gridlayout 
     parentPanel.setLayout(new GridBagLayout()); 

     //Panel for our titles 
     JPanel titlesPanel = new JPanel(); 
     titlesPanel.setLayout(new BoxLayout(titlesPanel, BoxLayout.Y_AXIS)); 

     for(int i = 0;i<noOfTitles;i++){ 
      //Panel for the subtitles of each title 
      JPanel subTitlesPanel = new JPanel(); 
      subTitlesPanel.setLayout(new BoxLayout(subTitlesPanel, BoxLayout.Y_AXIS)); 

      for(int j = 0;j<noOfSubTitles;j++){ 
       //Get a panel with a title header, a collapse/uncollapse button and some sample content 
       subTitlesPanel.add(getCollapsiblePanel(getSampleContent(),"Subtitle")); 
       subTitlesPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); 
      } 
      //Get a panel with a title header, a collapse/uncollapse button and the subtitles as content 
      titlesPanel.add(getCollapsiblePanel(subTitlesPanel,"Title")); 
     } 

     //The constraints for the 
     GridBagConstraints constraints = new GridBagConstraints(); 
     constraints.anchor = GridBagConstraints.PAGE_START; 
     constraints.fill = GridBagConstraints.HORIZONTAL; //Fill the panels horizontally. A weightx is needed for this to work. 
     constraints.gridx = 1; 
     constraints.gridy = 0; 
     constraints.weightx = 1; //Actually makes it fill 
     parentPanel.add(titlesPanel,constraints); 

     //To actually bump the rest of the other stuff to the top, 
     //we need something below with a weighty > 0 
     constraints.gridy = 1; 
     constraints.weighty = 1; 
     constraints.anchor = GridBagConstraints.PAGE_END; 
     parentPanel.add(new JLabel(""),constraints); 

     this.setVisible(true); 
    } 

    /* 
    * Gets a title for the supplied content-panel. 
    * The title includes the titleText and a button for collapsing/uncollapsing the content. 
    */ 
    private JPanel getCollapsiblePanel(JPanel content,String titleText){ 
     JPanel titlePanel = new JPanel(); //Top container for the title 
     JPanel title = new JPanel();  //collapse/uncollapse button and title text 

     title.setLayout(new BoxLayout(title,BoxLayout.X_AXIS)); 
     title.add(getToggleVisibilityIcon(content)); 
     title.add(new JLabel(" "+titleText)); 

     //A border layout is needed here for the fill of the parent panel to work 
     // (I tried with the box layout but it didn't work) 
     titlePanel.setLayout(new BorderLayout()); 
     titlePanel.add(title,BorderLayout.PAGE_START); 
     titlePanel.add(content,BorderLayout.CENTER); 

     //Vanity 
     title.setBackground(green); 
     title.setBorder(BorderFactory.createEmptyBorder(1,1,2,1)); 

     return titlePanel; 
    } 

    /* 
    * Not important, just generates a panel with some "sample" strings. 
    */ 
    private JPanel getSampleContent(){ 
     JPanel content = new JPanel(); 
     content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS)); 
     for(int i = 0; i<1+random.nextInt(3); i++){ 
      String sampleContent = ""; 
      for(int j = 0;j<1 + random.nextInt(5);j++){ 
       sampleContent += "sample "; 
      } 
      JLabel sample = new JLabel(sampleContent); 
      sample.setForeground(Color.decode("#111111")); 
      content.add(sample); 
     } 
     content.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); 
     content.setBackground(lightGreen); 
     return content; 
    } 

    /* 
    * Method that returns a JLabel that will toggle the visibility of the 
    * supplied content panel upon clicking. 
    */ 
    private JLabel getToggleVisibilityIcon(JPanel content){ 
     JLabel icon = new JLabel(" V "); 
     icon.setBackground(green); 
     icon.setBorder(BorderFactory.createLineBorder(darkGreen,2)); 
     icon.setOpaque(true); 
     icon.addMouseListener(new MouseListener(){ 
      private JPanel content; 
      private JLabel icon; 
      MouseListener init(JPanel content,JLabel icon){ 
       this.content = content; 
       this.icon = icon; 
       return this; 
      } 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       if(content.isVisible()){ 
        content.setVisible(false); 
        icon.setText(" > "); 
       }else{ 
        content.setVisible(true); 
        icon.setText(" V "); 
       } 
      } 

      @Override 
      public void mousePressed(MouseEvent e) {} 
      @Override 
      public void mouseReleased(MouseEvent e) {} 
      @Override 
      public void mouseEntered(MouseEvent e) {} 
      @Override 
      public void mouseExited(MouseEvent e) {} 
     }.init(content,icon)); 
     return icon; 
    } 
} 

运行的应用程序的屏幕截图:

enter image description here

+0

参见'org.netbeans.swing.outline.Outline',看到[这里](HTTP:/ /stackoverflow.com/a/15150756/230513)和[there](http://stackoverflow.com/search?tab=votes&q=user%3a230513%20org.netbeans.swing.outline.Outline)。 – trashgod

回答

1

不是很理解你的问题。您通常没有文字,按钮和组合框随机包装。通常面板具有布局,所以组件在逻辑上组织。那就是你不想要一个带有“First Name”文本的标签,随后是一个随机包装到下一行的文本字段。

它在我看来像你有一个“详细面板”,你隐藏或显示?

那么你可以使用BorderLayout实现这一点。所以隐藏/显示按钮将被放置在BorderLayout.PAGE_START中。然后细节面板将在BorderLayout.CENTER中。然后根据需要设置详细信息面板的可见性。

然后顶级容器可能是GridBagLayout。您可以使用约束来让每行填充单元格的宽度。每个儿童小组可以使用Border在左侧稍微缩进。

阅读Swing tutorial。上有几个部分:

  1. 如何使用的GridBagLayout和
  2. 如何使用边框