Browse Source
* commit '287996fbecd7221fc02187e4675e35f6c4563a3b': REPORT-113994 feat:TabPane组件实现 REPORT-113994 feat:TabPane组件实现newui
Renekton-张世豪
4 months ago
5 changed files with 271 additions and 27 deletions
@ -0,0 +1,166 @@ |
|||||||
|
package com.fr.design.gui.frpane; |
||||||
|
|
||||||
|
import com.fine.swing.ui.layout.Column; |
||||||
|
import com.fine.theme.utils.FineUIStyle; |
||||||
|
import com.formdev.flatlaf.util.ScaledEmptyBorder; |
||||||
|
import com.fr.design.gui.ibutton.UIButtonGroup; |
||||||
|
|
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.CardLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static com.fine.swing.ui.layout.Layouts.cell; |
||||||
|
import static com.fine.swing.ui.layout.Layouts.fix; |
||||||
|
import static com.fine.swing.ui.layout.Layouts.flex; |
||||||
|
import static com.fine.swing.ui.layout.Layouts.row; |
||||||
|
|
||||||
|
/** |
||||||
|
* Tab面板组件 |
||||||
|
* |
||||||
|
* @author Levy.Xie |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/05/14 |
||||||
|
*/ |
||||||
|
public class FineTabbedPane extends Column { |
||||||
|
|
||||||
|
private CardLayout cards; |
||||||
|
private JPanel centerPane; |
||||||
|
private final float headRatio; |
||||||
|
private final UIButtonGroup<String> tabGroup; |
||||||
|
private final Map<String, Component> tabComponents; |
||||||
|
|
||||||
|
private FineTabbedPane(Map<String, Component> tabComponents, float headRatio, int[] tabLayout) { |
||||||
|
this.headRatio = headRatio; |
||||||
|
this.tabComponents = tabComponents; |
||||||
|
|
||||||
|
String[] titleArray = tabComponents.keySet().toArray(new String[0]); |
||||||
|
this.tabGroup = new UIButtonGroup<>(titleArray, titleArray, tabLayout); |
||||||
|
|
||||||
|
initLayout(); |
||||||
|
initListeners(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 建造者模式创建TabPane |
||||||
|
* |
||||||
|
* @return TabPaneBuilder |
||||||
|
*/ |
||||||
|
public static TabPaneBuilder builder() { |
||||||
|
return new TabPaneBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* FineTabbedPane建造者 |
||||||
|
*/ |
||||||
|
public static class TabPaneBuilder { |
||||||
|
private int[] tabLayout; |
||||||
|
private float headRatio = 0.5f; |
||||||
|
private final Map<String, Component> tabComponents = new LinkedHashMap<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置头部居中比例,0-1之间 |
||||||
|
* |
||||||
|
* @param headRatio 头部居中比例 |
||||||
|
* @return TabPaneBuilder |
||||||
|
*/ |
||||||
|
public TabPaneBuilder withHeadRatio(float headRatio) { |
||||||
|
this.headRatio = headRatio; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置Tab布局,形如[3,4]即为首行3个组件,次行4个组件 |
||||||
|
* |
||||||
|
* @param tabLayout Tab头部布局 |
||||||
|
* @return TabPaneBuilder |
||||||
|
*/ |
||||||
|
public TabPaneBuilder withTabLayout(int[] tabLayout) { |
||||||
|
this.tabLayout = tabLayout; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 添加tab标签 |
||||||
|
* |
||||||
|
* @param title tab标签标头 |
||||||
|
* @param component 组件 |
||||||
|
* @return TabPaneBuilder |
||||||
|
*/ |
||||||
|
public TabPaneBuilder addTab(String title, Component component) { |
||||||
|
JPanel wrapperPane = new JPanel(new BorderLayout()); |
||||||
|
wrapperPane.add(component, BorderLayout.CENTER); |
||||||
|
this.tabComponents.put(title, wrapperPane); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 构造 |
||||||
|
* |
||||||
|
* @return FineTabbedPane |
||||||
|
*/ |
||||||
|
public FineTabbedPane build() { |
||||||
|
if (headRatio > 1) { |
||||||
|
throw new IllegalArgumentException("illegal headRatio argument!"); |
||||||
|
} |
||||||
|
if (tabLayout != null && Arrays.stream(tabLayout).sum() != tabComponents.size()) { |
||||||
|
throw new IllegalArgumentException("illegal tab layout argument!"); |
||||||
|
} |
||||||
|
return new FineTabbedPane(tabComponents, headRatio, tabLayout); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initLayout() { |
||||||
|
cards = new CardLayout(); |
||||||
|
centerPane = new JPanel(cards); |
||||||
|
tabComponents.forEach((key, value) -> centerPane.add(value, key)); |
||||||
|
float flexRatio = (1 - headRatio) / 2; |
||||||
|
add( |
||||||
|
row( |
||||||
|
flex(flexRatio), cell(tabGroup).weight(headRatio), flex(flexRatio) |
||||||
|
), |
||||||
|
fix(5), |
||||||
|
cell(centerPane).with(it -> FineUIStyle.setStyle(it, FineUIStyle.LIGHT_GREY)) |
||||||
|
); |
||||||
|
setBorder(new ScaledEmptyBorder(10, 10, 10, 10)); |
||||||
|
} |
||||||
|
|
||||||
|
private void initListeners() { |
||||||
|
tabGroup.addChangeListener((e) -> { |
||||||
|
cards.show(centerPane, String.valueOf(tabGroup.getSelectedItem())); |
||||||
|
}); |
||||||
|
tabGroup.setSelectedIndex(0); |
||||||
|
cards.show(centerPane, String.valueOf(tabGroup.getSelectedItem())); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 添加事件监听 |
||||||
|
* |
||||||
|
* @param l 监听器 |
||||||
|
*/ |
||||||
|
public void addChangeListener(ChangeListener l) { |
||||||
|
listenerList.add(ChangeListener.class, l); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 移除事件监听 |
||||||
|
* |
||||||
|
* @param l 监听器 |
||||||
|
*/ |
||||||
|
public void removeChangeListener(ChangeListener l) { |
||||||
|
listenerList.remove(ChangeListener.class, l); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前选中的Tab组件 |
||||||
|
* |
||||||
|
* @return Tab组件 |
||||||
|
*/ |
||||||
|
public Component getSelectedComponent() { |
||||||
|
return tabComponents.get(String.valueOf(tabGroup.getSelectedItem())); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package com.fr.design.gui.storybook.components; |
||||||
|
|
||||||
|
import com.formdev.flatlaf.util.ScaledEmptyBorder; |
||||||
|
import com.fr.design.gui.frpane.FineTabbedPane; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.storybook.StoryBoard; |
||||||
|
|
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
import static com.fine.swing.ui.layout.Layouts.cell; |
||||||
|
import static com.fine.swing.ui.layout.Layouts.column; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Levy.Xie |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/05/22 |
||||||
|
*/ |
||||||
|
public class TabbedPaneStoryBoard extends StoryBoard { |
||||||
|
public TabbedPaneStoryBoard() { |
||||||
|
super("切换标题面板"); |
||||||
|
add( |
||||||
|
cell(createSampleTabPane()), |
||||||
|
cell(createSampleTabPaneWithRatio(0.8f)), |
||||||
|
cell(createMultiRowTab()) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
private FineTabbedPane createSampleTabPane() { |
||||||
|
|
||||||
|
return FineTabbedPane.builder() |
||||||
|
.addTab("测试1", getSampleCell(1)) |
||||||
|
.addTab("测试2", getSampleCell(2)) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private FineTabbedPane createSampleTabPaneWithRatio(float ratio) { |
||||||
|
|
||||||
|
return FineTabbedPane.builder() |
||||||
|
.addTab("测试1", getSampleCell(1)) |
||||||
|
.addTab("测试2", getSampleCell(2)) |
||||||
|
.withHeadRatio(ratio) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private FineTabbedPane createMultiRowTab() { |
||||||
|
|
||||||
|
return FineTabbedPane.builder() |
||||||
|
.addTab("测试1", getSampleCell(1)) |
||||||
|
.addTab("测试2", getSampleCell(2)) |
||||||
|
.addTab("测试3", getSampleCell(3)) |
||||||
|
.addTab("测试4", getSampleCell(4)) |
||||||
|
.addTab("测试5", getSampleCell(5)) |
||||||
|
.withTabLayout(new int[]{2,3}) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private Component getSampleCell(int seq) { |
||||||
|
return column(10, |
||||||
|
cell(new UIButton(seq + "-按钮1")), cell(new UIButton(seq + "-按钮2")) |
||||||
|
).with(it -> it.setBorder(new ScaledEmptyBorder(10, 10, 10, 10))).getComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue