Levy.Xie-解安森
4 months ago
5 changed files with 253 additions and 14 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