Browse Source

REPORT-113994 feat:TabPane组件实现

newui
Levy.Xie-解安森 4 months ago
parent
commit
9f849586a0
  1. 2
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 166
      designer-base/src/main/java/com/fr/design/gui/frpane/FineTabbedPane.java
  3. 13
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java
  4. 63
      designer-base/src/test/java/com/fr/design/gui/storybook/components/TabbedPaneStoryBoard.java
  5. 23
      designer-realize/src/main/java/com/fr/design/dscolumn/DSColumnPane.java

2
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -326,7 +326,7 @@ public class PreferencePane extends BasicPane {
cell(createTplPreviewPane()),
// 设计器启动选项
cell(createDesignerStartupPane())
).getComponent();
).weight(1).getComponent();
useUniverseDBMCheckbox = new UICheckBox(i18nText("Fine-Design_Basic_Use_Universe_Database_Manager"));
UIScrollPane adviceScrollPane = patchScroll(advancePane);
tabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane);

166
designer-base/src/main/java/com/fr/design/gui/frpane/FineTabbedPane.java

@ -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()));
}
}

13
designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java

@ -50,6 +50,7 @@ public class UIButtonGroup<T> extends Column implements GlobalNameObserver, UIOb
private GlobalNameListener globalNameListener = null;
private String buttonGroupName = StringUtils.EMPTY;
private boolean isClick;
private int[] customCols;
private UIObserverListener uiObserverListener;
private boolean autoFireStateChanged = true;
@ -144,10 +145,11 @@ public class UIButtonGroup<T> extends Column implements GlobalNameObserver, UIOb
initLayout(getCols(), inToolbar);
}
public UIButtonGroup(String[] textArray, T[] objects) {
public UIButtonGroup(String[] textArray, T[] objects, int[] customCols) {
if (!ArrayUtils.isEmpty(objects) && textArray.length == objects.length) {
this.objectList = Arrays.asList(objects);
}
this.customCols = customCols;
labelButtonList = new ArrayList<>(textArray.length);
totalButtonSize = textArray.length;
for (int i = 0; i < textArray.length; i++) {
@ -180,17 +182,24 @@ public class UIButtonGroup<T> extends Column implements GlobalNameObserver, UIOb
initLayout(getCols());
}
public UIButtonGroup(String[] textArray, T[] objects) {
this(textArray, objects, null);
}
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
/**
* 计算按钮组的列布局
* 计算按钮组的列布局;支持自定义布局
*
* @return 列布局形如[5,3] 即为两行首行5个组件次行3个组件
*/
protected int[] getCols() {
if (customCols != null) {
return customCols;
}
return new int[]{totalButtonSize};
}

63
designer-base/src/test/java/com/fr/design/gui/storybook/components/TabbedPaneStoryBoard.java

@ -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();
}
}

23
designer-realize/src/main/java/com/fr/design/dscolumn/DSColumnPane.java

@ -2,7 +2,7 @@ package com.fr.design.dscolumn;
import com.fr.data.TableDataSource;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.frpane.FineTabbedPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
@ -29,7 +29,7 @@ public class DSColumnPane extends BasicPane {
public static final Dimension DEFAULT_DIMENSION = new Dimension(700, 600);
private TableDataSource tplEC;
private UITabbedPane tabbedPane;
private FineTabbedPane tabbedPane;
private DSColumnBasicPane basicPane = null;
private DSColumnConditionsPane conditionPane = null;
private DSColumnAdvancedPane advancedPane = null;
@ -90,22 +90,23 @@ public class DSColumnPane extends BasicPane {
JPanel contentPane = this;
contentPane.setLayout(FRGUIPaneFactory.createBorderLayout());
//peter:中心Panel.
tabbedPane = new UITabbedPane();
tabbedPane.addChangeListener(appliedWizardTabChangeListener);
contentPane.add(tabbedPane, BorderLayout.CENTER);
//_denny: 数据列面板
basicPane = new DSColumnBasicPane(setting);
basicPane.addPropertyChangeListener("cellElement", myPropertyChangeListener);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), basicPane);
conditionPane = new DSColumnConditionsPane(setting);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Filter"), conditionPane);
advancedPane = new DSColumnAdvancedPane(setting);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), advancedPane);
//peter:中心Panel.
tabbedPane = FineTabbedPane.builder()
.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), basicPane)
.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Filter"), conditionPane)
.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), advancedPane)
.build();
tabbedPane.addChangeListener(appliedWizardTabChangeListener);
contentPane.add(tabbedPane, BorderLayout.CENTER);
this.setPreferredSize(new Dimension(610, 400));
}

Loading…
Cancel
Save