forked from fanruan/design
Browse Source
Merge in DESIGN/design from ~STARRYI/design:feature/x to feature/x * commit '1ab435281d8a1ce962dd8507e5c098459bcaa93a': REPORT-59902 主题切换交互框架优化 REPORT-59089 【主题切换】主题比较多有滚动条,右侧主题的勾选图标有点显示不全research/11.0
starryi
3 years ago
14 changed files with 607 additions and 273 deletions
@ -0,0 +1,339 @@
|
||||
package com.fr.design.mainframe.theme; |
||||
|
||||
import com.fr.base.ScreenResolution; |
||||
import com.fr.base.theme.FormTheme; |
||||
import com.fr.base.theme.FormThemeConfig; |
||||
import com.fr.base.theme.ReportTheme; |
||||
import com.fr.base.theme.ReportThemeConfig; |
||||
import com.fr.base.theme.TemplateTheme; |
||||
import com.fr.base.theme.TemplateThemeConfig; |
||||
import com.fr.design.ExtraDesignClassManager; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.event.ChangeEvent; |
||||
import com.fr.design.event.ChangeListener; |
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.gui.frpane.UITabbedPane; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.design.mainframe.theme.dialog.TemplateThemeDialog; |
||||
import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider; |
||||
import com.fr.design.mainframe.theme.ui.BreadcrumbBar; |
||||
import com.fr.stable.ArrayUtils; |
||||
import com.fr.stable.unit.FU; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.border.CompoundBorder; |
||||
import javax.swing.border.LineBorder; |
||||
import java.awt.BasicStroke; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.CardLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Container; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.RenderingHints; |
||||
import java.awt.Stroke; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/10/9 |
||||
*/ |
||||
public class TemplateThemeGridPagesPane extends JPanel { |
||||
private BreadcrumbBar breadcrumbBar; |
||||
private JPanel contentPane; |
||||
private CardLayout cardLayout; |
||||
|
||||
private TemplateThemeGridPagePane themeUsingPane; |
||||
private TemplateThemeGridPagePane themeManagingPane; |
||||
|
||||
private PageChangeListener pageChangeListener; |
||||
private TemplateThemeGridPagePane currentTemplateThemeGridPagePane; |
||||
|
||||
public TemplateThemeGridPagesPane() { |
||||
initializePane(); |
||||
} |
||||
|
||||
private void initializePane() { |
||||
setLayout(new BorderLayout()); |
||||
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); |
||||
|
||||
breadcrumbBar = new BreadcrumbBar(); |
||||
breadcrumbBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); |
||||
add(breadcrumbBar, BorderLayout.NORTH); |
||||
|
||||
contentPane = new JPanel(); |
||||
contentPane.setBorder(new CompoundBorder( |
||||
new TopLineBorder(new Color(0xE0E0E1), 1), |
||||
BorderFactory.createEmptyBorder(10, 0, 0, 0))); |
||||
cardLayout = new CardLayout(); |
||||
contentPane.setLayout(cardLayout); |
||||
add(contentPane, BorderLayout.CENTER); |
||||
|
||||
|
||||
themeUsingPane = new TemplateThemeUsingPane(); |
||||
contentPane.add(themeUsingPane, themeUsingPane.getTitle()); |
||||
themeManagingPane = new TemplateThemeManagingPane(); |
||||
contentPane.add(themeManagingPane, themeManagingPane.getTitle()); |
||||
|
||||
showThemeUsingPane(); |
||||
} |
||||
|
||||
public void showThemeUsingPane() { |
||||
if (currentTemplateThemeGridPagePane != themeUsingPane) { |
||||
cardLayout.show(contentPane, themeUsingPane.getTitle()); |
||||
currentTemplateThemeGridPagePane = themeUsingPane; |
||||
if (pageChangeListener != null) { |
||||
pageChangeListener.onPageChangeListener(); |
||||
} |
||||
breadcrumbBar.clear(); |
||||
breadcrumbBar.addCrumb(themeUsingPane.getTitle(), new BreadcrumbBar.BreadcrumbBackListener() { |
||||
@Override |
||||
public void onBreadcrumbBack(String text) { |
||||
cardLayout.show(contentPane, themeUsingPane.getTitle()); |
||||
currentTemplateThemeGridPagePane = themeUsingPane; |
||||
if (pageChangeListener != null) { |
||||
pageChangeListener.onPageChangeListener(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
public void showThemeManagingPane() { |
||||
if (currentTemplateThemeGridPagePane != themeManagingPane) { |
||||
cardLayout.show(contentPane, themeManagingPane.getTitle()); |
||||
currentTemplateThemeGridPagePane = themeManagingPane; |
||||
if (pageChangeListener != null) { |
||||
pageChangeListener.onPageChangeListener(); |
||||
} |
||||
breadcrumbBar.addCrumb(themeManagingPane.getTitle(), null); |
||||
} |
||||
} |
||||
|
||||
public UIButton[] createLeftButtons() { |
||||
UIButton[] buttons = new UIButton[] {}; |
||||
if (currentTemplateThemeGridPagePane != themeManagingPane && WorkContext.getCurrent().isRoot()) { |
||||
buttons = ArrayUtils.addAll(buttons, createOpenThemeManagerButton()); |
||||
} |
||||
return buttons; |
||||
} |
||||
|
||||
public UIButton[] createRightButtons() { |
||||
UIButton[] buttons = new UIButton[] {}; |
||||
buttons = ArrayUtils.addAll(buttons, createExtraButtons()); |
||||
buttons = ArrayUtils.addAll(buttons, createCompleteButton()); |
||||
return buttons; |
||||
} |
||||
|
||||
private UIButton createOpenThemeManagerButton() { |
||||
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); |
||||
button.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
showThemeManagingPane(); |
||||
} |
||||
}); |
||||
return button; |
||||
} |
||||
|
||||
private UIButton[] createExtraButtons() { |
||||
List<UIButton> uiButtonList = new ArrayList<>(); |
||||
|
||||
Set<ThemeManageActionProvider> providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING); |
||||
for (ThemeManageActionProvider provider : providers) { |
||||
uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() { |
||||
|
||||
@Override |
||||
public TemplateThemeDialog getDialog() { |
||||
Container container = getRootPane().getParent(); |
||||
if (container instanceof TemplateThemeDialog) { |
||||
return (TemplateThemeDialog) container; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public TemplateThemeConfig<? extends TemplateTheme> getConfig() { |
||||
return currentTemplateThemeGridPagePane.getConfig(); |
||||
} |
||||
})); |
||||
} |
||||
|
||||
return uiButtonList.toArray(new UIButton[]{}); |
||||
} |
||||
|
||||
private UIButton createCompleteButton() { |
||||
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete")); |
||||
button.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
Container container = getRootPane().getParent(); |
||||
if (container instanceof TemplateThemeDialog) { |
||||
((TemplateThemeDialog) container).exit(); |
||||
} |
||||
} |
||||
}); |
||||
return button; |
||||
} |
||||
|
||||
public void exit() { |
||||
themeUsingPane.exit(); |
||||
themeManagingPane.exit(); |
||||
} |
||||
|
||||
public void setPageChangeListener(PageChangeListener changeListener) { |
||||
this.pageChangeListener = changeListener; |
||||
} |
||||
|
||||
public interface PageChangeListener { |
||||
void onPageChangeListener(); |
||||
} |
||||
|
||||
public static class TopLineBorder extends LineBorder { |
||||
private final FU fu; |
||||
|
||||
private TopLineBorder(Color color, int thickness) { |
||||
super(color, thickness); |
||||
fu = FU.getInstance(thickness); |
||||
} |
||||
|
||||
@Override |
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
||||
Graphics2D g2d = (Graphics2D)g; |
||||
|
||||
Color oldColor = g2d.getColor(); |
||||
Stroke oldStroke = g2d.getStroke(); |
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||
|
||||
g2d.setColor(getLineColor()); |
||||
int thickness = Math.max(1, fu.toPixI(ScreenResolution.getScreenResolution())); |
||||
g2d.setStroke(new BasicStroke(thickness)); |
||||
g2d.drawLine(0, 0, width, thickness); |
||||
|
||||
g2d.setStroke(oldStroke); |
||||
g2d.setColor(oldColor); |
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
||||
} |
||||
} |
||||
|
||||
public abstract static class TemplateThemeGridPagePane extends BasicPane { |
||||
public abstract TemplateThemeConfig<? extends TemplateTheme> getConfig(); |
||||
|
||||
public void exit() { } |
||||
} |
||||
|
||||
public static class TemplateThemeUsingPane extends TemplateThemeGridPagePane { |
||||
private final JTemplate<?,?> template; |
||||
public final TemplateThemeGridPane<? extends TemplateTheme> themeListPane; |
||||
|
||||
public TemplateThemeUsingPane() { |
||||
super(); |
||||
setLayout(new BorderLayout()); |
||||
setBorder(new CompoundBorder( |
||||
BorderFactory.createLineBorder(new Color(0xE0E0E1)), |
||||
BorderFactory.createEmptyBorder(0, 10, 0, 10))); |
||||
|
||||
template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig(); |
||||
themeListPane = new TemplateThemeGridPane<>(false, config, null); |
||||
|
||||
themeListPane.startListenThemeConfig(); |
||||
|
||||
themeListPane.setSelectedChangeListener(new ChangeListener() { |
||||
@Override |
||||
public void fireChanged(ChangeEvent event) { |
||||
TemplateTheme theme = themeListPane.getSelectedTheme(); |
||||
if (theme != null) { |
||||
template.setTemplateTheme(theme); |
||||
themeListPane.repaint(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
add(themeListPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
@Override |
||||
public TemplateThemeConfig<? extends TemplateTheme> getConfig() { |
||||
return template.getUsingTemplateThemeConfig(); |
||||
} |
||||
|
||||
@Override |
||||
public void exit() { |
||||
themeListPane.stopListenThemeConfig(); |
||||
themeListPane.stopAsyncFetchTheme(); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"); |
||||
} |
||||
} |
||||
|
||||
public static class TemplateThemeManagingPane extends TemplateThemeGridPagePane { |
||||
public static final int CONTENT_WIDTH = TemplateThemeGridControlPane.CONTENT_WIDTH + 4; |
||||
public static final int CONTENT_HEIGHT = TemplateThemeGridControlPane.CONTENT_HEIGHT + 10; |
||||
|
||||
private final UITabbedPane tabbedPane; |
||||
private final TemplateThemeGridControlPane<FormTheme> formThemesManagerPane; |
||||
private final TemplateThemeGridControlPane<ReportTheme> reportThemesManagerPane; |
||||
|
||||
public TemplateThemeManagingPane() { |
||||
setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); |
||||
|
||||
tabbedPane = new UITabbedPane(); |
||||
add(tabbedPane, BorderLayout.CENTER); |
||||
|
||||
formThemesManagerPane = TemplateThemeGridControlPane.createFormThemesManagerPane(); |
||||
formThemesManagerPane.startListenThemeConfig(); |
||||
reportThemesManagerPane = TemplateThemeGridControlPane.createReportThemesManagerPane(); |
||||
reportThemesManagerPane.startListenThemeConfig(); |
||||
|
||||
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane); |
||||
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane); |
||||
|
||||
tabbedPane.setSelectedIndex(0); |
||||
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig(); |
||||
if (config == reportThemesManagerPane.getConfig()) { |
||||
tabbedPane.setSelectedIndex(1); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public TemplateThemeConfig<? extends TemplateTheme> getConfig() { |
||||
if (tabbedPane.getSelectedIndex() == 0) { |
||||
return FormThemeConfig.getInstance(); |
||||
} else { |
||||
return ReportThemeConfig.getInstance(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void exit() { |
||||
formThemesManagerPane.stopListenThemeConfig(); |
||||
formThemesManagerPane.stopAsyncFetchTheme(); |
||||
reportThemesManagerPane.stopListenThemeConfig(); |
||||
reportThemesManagerPane.stopAsyncFetchTheme(); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,59 @@
|
||||
package com.fr.design.mainframe.theme.dialog; |
||||
|
||||
import com.fr.base.theme.TemplateTheme; |
||||
import com.fr.base.theme.TemplateThemeConfig; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.theme.TemplateThemeGridPagesPane; |
||||
import com.fr.design.mainframe.theme.TemplateThemeGridPane; |
||||
|
||||
import javax.swing.JPanel; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/13 |
||||
*/ |
||||
public class TemplateThemeGridPagesDialog extends TemplateThemeDialog implements TemplateThemeGridPagesPane.PageChangeListener { |
||||
public static final String COMPLETE_BUTTON = "theme_button_complete"; |
||||
public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 40; |
||||
public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; |
||||
|
||||
protected TemplateThemeGridPagesPane overallPane; |
||||
|
||||
public TemplateThemeGridPagesDialog() { |
||||
super(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); |
||||
|
||||
setupContentPane(); |
||||
setupActionButtons(); |
||||
} |
||||
|
||||
@Override |
||||
protected JPanel createContentPane() { |
||||
overallPane = new TemplateThemeGridPagesPane(); |
||||
overallPane.setPageChangeListener(this); |
||||
return overallPane; |
||||
} |
||||
|
||||
@Override |
||||
protected UIButton[] createLeftButtons() { |
||||
return overallPane.createLeftButtons(); |
||||
} |
||||
|
||||
@Override |
||||
protected UIButton[] createRightButtons() { |
||||
return overallPane.createRightButtons(); |
||||
} |
||||
|
||||
@Override |
||||
public void exit() { |
||||
overallPane.exit(); |
||||
super.exit(); |
||||
} |
||||
|
||||
@Override |
||||
public void onPageChangeListener() { |
||||
setupActionButtons(); |
||||
} |
||||
} |
@ -1,112 +1,13 @@
|
||||
package com.fr.design.mainframe.theme.dialog; |
||||
|
||||
import com.fr.base.theme.TemplateTheme; |
||||
import com.fr.base.theme.TemplateThemeConfig; |
||||
import com.fr.base.theme.ThemedTemplate; |
||||
import com.fr.design.event.ChangeEvent; |
||||
import com.fr.design.event.ChangeListener; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.theme.TemplateThemeListPane; |
||||
import com.fr.design.mainframe.theme.ui.BorderUtils; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.border.CompoundBorder; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Window; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/13 |
||||
*/ |
||||
public class TemplateThemeUsingDialog<T extends TemplateTheme> extends TemplateThemeDialog { |
||||
public static final String COMPLETE_BUTTON = "theme_button_complete"; |
||||
public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 42; |
||||
public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 23; |
||||
|
||||
private final TemplateThemeListPane<T> themeListPane; |
||||
private final ThemedTemplate currentTemplate; |
||||
|
||||
public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig<T> config) { |
||||
super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); |
||||
|
||||
this.currentTemplate = template; |
||||
this.themeListPane = new TemplateThemeListPane<>(false, config, null); |
||||
|
||||
JPanel content = createContent(); |
||||
UIButton openThemeManagerButton = createOpenThemeManagerButton(); |
||||
UIButton completeButton = createCompleteButton(); |
||||
|
||||
setContentPane(createDialogContentPane(content, |
||||
new UIButton[]{ openThemeManagerButton }, |
||||
new UIButton[]{ completeButton } |
||||
)); |
||||
|
||||
themeListPane.startListenThemeConfig(); |
||||
|
||||
themeListPane.setSelectedChangeListener(new ChangeListener() { |
||||
@Override |
||||
public void fireChanged(ChangeEvent event) { |
||||
TemplateTheme theme = themeListPane.getSelectedTheme(); |
||||
if (theme != null) { |
||||
currentTemplate.setTemplateTheme(theme); |
||||
themeListPane.repaint(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private JPanel createContent() { |
||||
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); |
||||
|
||||
JPanel themeListPaneContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
themeListPaneContainer.setBorder(new CompoundBorder( |
||||
BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Select"), 12), |
||||
BorderFactory.createEmptyBorder(0, 10, 0, 10) |
||||
)); |
||||
themeListPaneContainer.add(themeListPane, BorderLayout.CENTER); |
||||
container.add(themeListPaneContainer, BorderLayout.CENTER); |
||||
|
||||
return container; |
||||
} |
||||
|
||||
private UIButton createOpenThemeManagerButton() { |
||||
if (WorkContext.getCurrent().isRoot()) { |
||||
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); |
||||
button.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(TemplateThemeUsingDialog.this); |
||||
dialog.setVisible(true); |
||||
} |
||||
}); |
||||
return button; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private UIButton createCompleteButton() { |
||||
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Complete")); |
||||
button.setName(COMPLETE_BUTTON); |
||||
button.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
exit(); |
||||
} |
||||
}); |
||||
return button; |
||||
} |
||||
|
||||
public void exit() { |
||||
themeListPane.stopListenThemeConfig(); |
||||
themeListPane.stopAsyncFetchTheme(); |
||||
super.exit(); |
||||
public class TemplateThemeUsingDialog extends TemplateThemeGridPagesDialog { |
||||
public TemplateThemeUsingDialog() { |
||||
super(); |
||||
overallPane.showThemeUsingPane(); |
||||
} |
||||
} |
@ -0,0 +1,114 @@
|
||||
package com.fr.design.mainframe.theme.ui; |
||||
|
||||
import com.fr.design.gui.ilable.UILabel; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JButton; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.plaf.basic.BasicButtonUI; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Dimension; |
||||
import java.awt.FlowLayout; |
||||
import java.awt.Insets; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/10/9 |
||||
*/ |
||||
public class BreadcrumbBar extends JPanel { |
||||
private JButton currentCrumb; |
||||
|
||||
public BreadcrumbBar() { |
||||
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||
} |
||||
|
||||
public void addCrumb(final String text, final BreadcrumbBackListener backListener) { |
||||
if (currentCrumb != null) { |
||||
currentCrumb.setSelected(false); |
||||
add(createSeparator()); |
||||
} |
||||
final JButton breadcrumb = createBreadcrumb(text); |
||||
breadcrumb.setSelected(true); |
||||
add(breadcrumb); |
||||
currentCrumb = breadcrumb; |
||||
|
||||
final int index = getComponentCount() - 1; |
||||
breadcrumb.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
removeTailCrumbs(index + 1); |
||||
|
||||
breadcrumb.setSelected(true); |
||||
currentCrumb = breadcrumb; |
||||
if (backListener != null) { |
||||
backListener.onBreadcrumbBack(text); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void removeTailCrumbs(int from) { |
||||
Component[] components = getComponents(); |
||||
for (int i = from; i < components.length; i++) { |
||||
remove(components[i]); |
||||
} |
||||
revalidate(); |
||||
repaint(); |
||||
} |
||||
|
||||
public void clear() { |
||||
removeAll(); |
||||
currentCrumb = null; |
||||
} |
||||
|
||||
protected Component createSeparator() { |
||||
UILabel separator = new UILabel("/"); |
||||
separator.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); |
||||
separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, 17)); |
||||
|
||||
return separator; |
||||
} |
||||
|
||||
protected JButton createBreadcrumb(String text) { |
||||
JButton button = new BreadcrumbButton(text); |
||||
button.setPreferredSize(new Dimension(button.getPreferredSize().width, 17)); |
||||
return button; |
||||
} |
||||
|
||||
public static class BreadcrumbButton extends JButton { |
||||
|
||||
public BreadcrumbButton(String text) { |
||||
super(text); |
||||
setMargin(new Insets(0, 0, 0, 0)); |
||||
setBorder(BorderFactory.createEmptyBorder()); |
||||
setUI(new BasicButtonUI()); |
||||
setBorderPainted(false); |
||||
setOpaque(false); |
||||
setBackground(null); |
||||
} |
||||
|
||||
@Override |
||||
public Insets getMargin() { |
||||
Insets insets = super.getMargin(); |
||||
if (insets != null) { |
||||
insets.set(0, 0, 0, 0); |
||||
} |
||||
return insets; |
||||
} |
||||
|
||||
@Override |
||||
public void setSelected(boolean b) { |
||||
super.setSelected(b); |
||||
setForeground(b ? new Color(0x419BF9) : new Color(0x838384)); |
||||
repaint(); |
||||
} |
||||
} |
||||
|
||||
public interface BreadcrumbBackListener { |
||||
void onBreadcrumbBack(String text); |
||||
} |
||||
} |
Loading…
Reference in new issue