但是,大多數情況下,對于UI中的每個面板,只需要一個布局管理器即可達到所需的效果,但是有時您需要根據容器中的組件數對同一容器使用多個布局管理器。
這樣的示例之一是在創建類似居中網格的布局時。 大多數情況下,如果組件的數量固定,則GridLayout或GridBagLayout可能就足夠了,但是如果組件的數量不斷變化,則布局可能不理想。 今天下午我遇到了類似的問題,這是我想出的解決方案。
我想要實現的UI與Opera的快速撥號類似,但是撥號次數可變。 基本上,
- 您從一個組件開始,并且應該在面板中居中
- 添加另一個組件,它們都應該居中
- 添加三分之一,所有三個都應放在一行的中心
- 如果添加了第四個組件,則您應該有一個3 x 2的矩陣,第一行中有三項,第二行中有一項
- 對于最多六個組件,應保留3 x 2矩陣
- 對于6個以上的組件,矩陣應為4 x 3,因此我們最多可以容納12個組件,這將是最大
最初,這個要求看起來很棘手,但解決方案通常是僅使用兩個JPanels的布局管理器的組合。 基本上,是一個用于使內部內容物居中的外部容器,以及一個用于根據需要創建矩陣的內部容器。
使用哪個布局管理器
隨之而來的問題是,哪個布局管理器可以提供所需的結果? 經過幾分鐘的試驗,我終于意識到GridBagLayout給了我所需的居中內容外觀,但是有時是不一致的。 因此,我選擇通過netbeans設計器使用GroupLayout。 因此,將其應用于外部容器。
接下來,我試圖找到一個可以有效滿足第一個要求的布局管理器。 選項為FlowLayout和GridLayout。 但是,盡管FlowLayout傾向于將其內容垂直對齊到頂部,但在這種情況下就足夠了,因為GroupLayout將FlowLayout內容垂直居中,并滿足了1-3的要求。
接下來,對于需求4,再次選擇了GridLayout,但是這次將其設置為anx 3矩陣,其中n是任意數量的行。 這使GridLayout可以按預期增長,并且還可以在垂直放置之前先水平放置其組件。 這也自動滿足了要求5。
最后,當組件大于6時,將創建一個新的GridLayout,其大小為nx 4,需要有效地對齊內容。 可以進一步添加新組件,直到最多達到12個組件為止,并且禁止進一步添加。
這是該過程的示例代碼。
JPanel container = new JPanel();
container.setName("container"); // NOI18N
container.setOpaque(false);JPanel content = new JPanel();
content.setBorder(javax.swing.BorderFactory.createEmptyBorder(50, 50, 50, 50));
content.setName("content"); // NOI18N
content.setOpaque(false);
content.setLayout(new java.awt.GridLayout(0, 3));javax.swing.GroupLayout containerLayout = new javax.swing.GroupLayout(container);
container.setLayout(containerLayout);
containerLayout.setHorizontalGroup(containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(containerLayout.createSequentialGroup().addContainerGap(346, Short.MAX_VALUE).addComponent(content, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(347, Short.MAX_VALUE))
);
containerLayout.setVerticalGroup(containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(containerLayout.createSequentialGroup().addContainerGap(223, Short.MAX_VALUE).addComponent(content, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(224, Short.MAX_VALUE))
);
然后,每添加一個新組件,就會運行以下代碼:
getContent().removeAll();int gridSize = organisations.size();switch( gridSize ) {case 1:case 2:case 3:getContent().setLayout( new FlowLayout(FlowLayout.CENTER) );break;case 4:case 5:case 6:getContent().setLayout( new GridLayout(0,3) );break;case 7:case 8:getContent().setLayout( new GridLayout(0,4) );break;default:getContent().setLayout( new GridLayout(0, 4) );
}for (Organisation org : organisations) {getContent().add(createOrgSelectionComponent(org));
}getContent().validate();
getContent().repaint();
這是最終布局的屏幕截圖。
參考: 有時在Java中,我們的JCG合作伙伴 Francis在“ Ice in Code”博客中 還沒有一個Layout Manager 。
- JavaFX 2.0 beta示例應用程序和思考
- Xuggler開發教程
- Java Swing –日期選擇器對話框
- SmartGWT入門,提供出色的GWT界面
- YouTube Java API入門
翻譯自: https://www.javacodegeeks.com/2011/09/sometimes-in-java-one-layout-manager-is.html