Browse Source

面包屑组件初实现,自动缩放,目录恢复

newui
renekton 5 months ago
parent
commit
6c7b869bd9
  1. 221
      designer-base/src/main/java/com/fr/design/gui/frpane/FineBreadcrumbPane.java
  2. 23
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java
  3. 15
      designer-base/src/main/java/com/fr/file/FILEChooserPane.java
  4. 8
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties

221
designer-base/src/main/java/com/fr/design/gui/frpane/FineBreadcrumbPane.java

@ -3,17 +3,25 @@ package com.fr.design.gui.frpane;
import com.fine.swing.ui.layout.Row;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.fine.theme.utils.FineUIUtils;
import com.finebi.cbb.utils.StringUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.file.FILE;
import com.fr.general.ComparatorUtils;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
/**
* @author Renekton
* @since 2024/08/08
* @param <T>
*/
public class FineBreadcrumbPane <T> extends Row {
private static final int SEP_HEIGHT = 20;
@ -22,39 +30,119 @@ public class FineBreadcrumbPane <T> extends Row {
private static final int MAX_BUTTON_WIDTH = FineUIScale.scale(150);
private static final String DEFAULT_SEP = "/";
private BreadcrumbButton currentCrumb;
public void setRootButton(T text, final BreadcrumbBackListener<T> backListener) {
clear();
currentCrumb = new BreadcrumbButton<>(getText(text), text);
add(currentCrumb);
final int index = getComponentCount();
addBreadcrumbListener(currentCrumb, index, backListener);
repaint();
private List<Component> breadcrumbs;
private int componentWidth;
private int hidingIndex;
private String sep;
public FineBreadcrumbPane() {
this(DEFAULT_SEP);
}
/**
* 可传入分隔符号
*/
public FineBreadcrumbPane(String sep) {
this.sep = sep;
this.breadcrumbs = new ArrayList<>();
this.componentWidth = 0;
this.hidingIndex = -1;
}
public void addCrumb(final T text, final BreadcrumbBackListener<T> backListener) {
/**
* 初始化节点
* @param data 节点数据
* @param backListener 节点点击关联动作
*/
public void init(T data, final BreadcrumbBackListener<T> backListener) {
if (currentCrumb != null) {
if (text instanceof FILE) {
FILE file = (FILE) text;
if (ComparatorUtils.equals(currentCrumb.getContent(), file) || !file.isDirectory()) {
return;
return;
}
if (data instanceof FILE) {
FILE file = (FILE) data;
List<FILE> files = new ArrayList<>();
while (file != null) {
if (StringUtils.isEmpty(file.getName())) {
break;
}
if (file.getParent().equals(((FILE)currentCrumb.getContent()).getParent())) {
remove(currentCrumb);
currentCrumb = new BreadcrumbButton<>(getText(text), text);
final int index = getComponentCount();
addBreadcrumbListener(currentCrumb, index, backListener);
repaint();
return;
if (file.isDirectory()) {
files.add(file);
}
file = file.getParent();
}
int size = files.size();
currentCrumb = new BreadcrumbButton<>(getRootdata((T) files.get(size-1)), files.get(size-1));
add(currentCrumb);
final int index = getComponentCount();
addBreadcrumbListener(currentCrumb, index, backListener);
for (int i = size-2; i >= 0; i--) {
addCrumb((T) files.get(i), backListener);
}
} else if (data instanceof String) {
currentCrumb = new BreadcrumbButton<>(getRootdata(data), data);
add(currentCrumb);
final int index = getComponentCount();
addBreadcrumbListener(currentCrumb, index, backListener);
}
repaint();
}
/**
* 根节点重置
* @param data 节点内容
* @param backListener
*/
public void reset(T data, final BreadcrumbBackListener<T> backListener) {
if (currentCrumb != null && ComparatorUtils.equals(data, currentCrumb.getContent())) {
return;
}
clear();
init(data, backListener);
}
/**
* 添加节点
* @param data
* @param backListener
*/
public void addCrumb(final T data, final BreadcrumbBackListener<T> backListener) {
if (currentCrumb != null) {
currentCrumb.setSelected(false);
currentCrumb.setForeground(Color.GRAY);
currentCrumb.setForeground(FineUIUtils.getUIColor("Button.breadcrumbForeground", "Button.breadcrumbForeground"));
add(createSeparator());
}
final BreadcrumbButton breadcrumb = createBreadcrumb(text);
final BreadcrumbButton breadcrumb = createBreadcrumb(data);
int currentWidth = componentWidth + breadcrumb.getPreferredSize().width;
if (this.getVisibleRect().width != 0 && currentWidth > this.getVisibleRect().width) {
// 大于可见宽度,隐藏前面的目录
for (int i = hidingIndex+1; i < breadcrumbs.size(); i++) {
int width = breadcrumbs.get(i).getPreferredSize().width;
breadcrumbs.get(i).setVisible(false);
hidingIndex = i;
currentWidth -= width;
if (currentWidth < this.getVisibleRect().width) {
if (breadcrumbs.get(i+1) instanceof UILabel) {
breadcrumbs.get(i+1).setVisible(false);
hidingIndex = i+1;
componentWidth = currentWidth - breadcrumb.getPreferredSize().width - breadcrumbs.get(i+1).getPreferredSize().width;
} else {
componentWidth = currentWidth - breadcrumb.getPreferredSize().width;
}
break;
}
}
}
add(breadcrumb);
currentCrumb = breadcrumb;
final int index = getComponentCount();
@ -71,13 +159,30 @@ public class FineBreadcrumbPane <T> extends Row {
repaint();
}
@Override
public void remove(Component comp) {
componentWidth -= comp.getPreferredSize().getWidth();
breadcrumbs.remove(comp);
super.remove(comp);
}
@Override
public Component add(Component comp) {
componentWidth += comp.getPreferredSize().getWidth();
breadcrumbs.add(comp);
return super.add(comp);
}
public void clear() {
removeAll();
currentCrumb = null;
componentWidth = 0;
breadcrumbs.clear();
}
protected Component createSeparator() {
UILabel separator = new UILabel("/");
UILabel separator = new UILabel(sep);
separator.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, FineUIScale.scale(SEP_HEIGHT)));
@ -85,18 +190,48 @@ public class FineBreadcrumbPane <T> extends Row {
}
protected BreadcrumbButton createBreadcrumb(T content) {
BreadcrumbButton button = new BreadcrumbButton(getText(content), content);
BreadcrumbButton button = new BreadcrumbButton(getdata(content), content);
button.setPreferredSize(new Dimension(Math.min(button.getPreferredSize().width, MAX_BUTTON_WIDTH), FineUIScale.scale(BUTTON_HEIGHT)));
button.setSelected(true);
button.setForeground(Color.black);
button.setForeground(FineUIUtils.getUIColor("Button.breadcrumbSelectedForeground", "Button.breadcrumbSelectedForeground"));
return button;
}
/**
* 节点点击事件
* @param breadcrumb
* @param index
* @param backListener
*/
private void addBreadcrumbListener(BreadcrumbButton breadcrumb, int index, BreadcrumbBackListener backListener) {
breadcrumb.addActionListener(e -> {
removeTailCrumbs(index);
// 存在隐藏目录,弹出部分隐藏目录
if (hidingIndex >= 0) {
int currentWidth = componentWidth;
for (int i = hidingIndex; i >= 0; i--) {
currentWidth += breadcrumbs.get(i).getPreferredSize().width;
if (currentWidth <= this.getVisibleRect().width) {
breadcrumbs.get(i).setVisible(true);
} else {
hidingIndex = i;
if (breadcrumbs.get(i+1) instanceof UILabel) {
currentWidth -= breadcrumbs.get(i+1).getPreferredSize().width;
breadcrumbs.get(i+1).setVisible(false);
hidingIndex = i+1;
}
componentWidth = currentWidth - breadcrumbs.get(i).getPreferredSize().width;
break;
}
}
if (currentWidth <= this.getVisibleRect().width) {
hidingIndex = -1;
componentWidth = currentWidth;
}
}
breadcrumb.setSelected(true);
breadcrumb.setForeground(Color.BLACK);
breadcrumb.setForeground(FineUIUtils.getUIColor("Button.breadcrumbSelectedForeground", "Button.breadcrumbSelectedForeground"));
if (breadcrumb != currentCrumb) {
currentCrumb = breadcrumb;
}
@ -106,21 +241,36 @@ public class FineBreadcrumbPane <T> extends Row {
});
}
private String getText(T text) {
if (text instanceof String) {
return (String) text;
} else if (text instanceof FILE){
return ((FILE)text).getName();
private String getRootdata(T data) {
if (data instanceof String) {
return (String) data;
} else if (data instanceof FILE){
FILE file = (FILE) data;
if (file.getPath().endsWith("/") || file.getPath().endsWith("\\")) {
return file.getPath().replaceAll("[/\\\\]+", "");
} else if (file.getPath().contains("/") || file.getPath().contains("\\")) {
return file.getPath().replaceAll("[/\\\\]+", sep);
}
return ((FILE)data).getPath();
}
return (String) text;
return (String) data;
}
private String getdata(T data) {
if (data instanceof String) {
return (String) data;
} else if (data instanceof FILE){
return ((FILE)data).getName();
}
return (String) data;
}
public static class BreadcrumbButton <T> extends UIButton {
private T content;
public BreadcrumbButton(String text, T content) {
super(text);
public BreadcrumbButton(String data, T content) {
super(data);
BreadcrumbButton.this.content = content;
setMargin(new Insets(0, 0, 0, 0));
setBorder(BorderFactory.createEmptyBorder());
@ -148,6 +298,7 @@ public class FineBreadcrumbPane <T> extends Row {
}
public interface BreadcrumbBackListener <T> {
void onBreadcrumbBack(T text);
void onBreadcrumbBack(T data);
}
}

23
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.theme;
import com.fine.theme.utils.FineUIScale;
import com.fr.base.ScreenResolution;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.FormThemeConfig;
@ -21,6 +22,8 @@ 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.file.FILE;
import com.fr.general.ComparatorUtils;
import com.fr.stable.ArrayUtils;
import com.fr.stable.unit.FU;
import com.fr.third.javax.annotation.Nullable;
@ -36,6 +39,7 @@ 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;
@ -77,7 +81,7 @@ public class TemplateThemeGridPagesPane extends JPanel {
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
breadcrumbBar = new FineBreadcrumbPane();
breadcrumbBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
breadcrumbBar.setPreferredSize(new Dimension(this.getPreferredSize().width, FineUIScale.scale(20)));
add(breadcrumbBar, BorderLayout.NORTH);
contentPane = new JPanel();
@ -105,13 +109,14 @@ public class TemplateThemeGridPagesPane extends JPanel {
pageChangeListener.onPageChangeListener();
}
breadcrumbBar.clear();
breadcrumbBar.addCrumb(themeUsingPane.getTitle(), text -> {
cardLayout.show(contentPane, themeUsingPane.getTitle());
currentTemplateThemeGridPagePane = themeUsingPane;
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
});
breadcrumbBar.addCrumb(themeUsingPane.getTitle(),
data -> {
cardLayout.show(contentPane, themeUsingPane.getTitle());
currentTemplateThemeGridPagePane = themeUsingPane;
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
});
}
}
@ -122,7 +127,7 @@ public class TemplateThemeGridPagesPane extends JPanel {
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
breadcrumbBar.addCrumb(themeManagingPane.getTitle(), null);
breadcrumbBar.addCrumb(themeManagingPane.getTitle(),null);
}
}

15
designer-base/src/main/java/com/fr/file/FILEChooserPane.java

@ -350,9 +350,7 @@ public class FILEChooserPane extends BasicPane {
Object selValue = placesList.getSelectedValue();
if (selValue instanceof FILE) {
setSelectedDirectory((FILE) selValue);
locationBreadcrumbPane.setRootButton(selValue, text -> {
setSelectedDirectory((FILE) selValue);
});
locationBreadcrumbPane.reset(selValue, data -> setSelectedDirectory((FILE) data));
}
}
});
@ -365,6 +363,7 @@ public class FILEChooserPane extends BasicPane {
Object selValue = placesList.getSelectedValue();
if (selValue instanceof FILE) {
setSelectedDirectory((FILE) selValue);
locationBreadcrumbPane.reset(selValue, data -> setSelectedDirectory((FILE) data));
}
}
});
@ -423,9 +422,8 @@ public class FILEChooserPane extends BasicPane {
setFileTextField((FILE) selValue);
fileNameTextField.addDocumentListener();
} else {
locationBreadcrumbPane.addCrumb(selValue, text -> {
setSelectedDirectory((FILE) selValue);
});
locationBreadcrumbPane.addCrumb(selValue,
data -> setSelectedDirectory((FILE) data));
setSelectedDirectory((FILE) selValue);
if (!((FILE) selValue).isDirectory()) {
doOK();
@ -1104,9 +1102,7 @@ public class FILEChooserPane extends BasicPane {
}
private void setTopPath(String path) {
this.locationBreadcrumbPane.setRootButton(path, text -> {
//setSelectedDirectory(text);
});
this.locationBreadcrumbPane.init(path, null);
}
@ -1160,6 +1156,7 @@ public class FILEChooserPane extends BasicPane {
}
setSelectedDirectory(dir);
locationBreadcrumbPane.reset(dir, text -> setSelectedDirectory((FILE) text));
}
/*

8
designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties

@ -1189,6 +1189,9 @@ Center.arc=10
#---- CellOtherSetPane ----
CellOtherSetPane.height=$Component.defaultHeight
Button.breadcrumbForeground = #8F999F
Button.breadcrumbSelectedForeground = #000000
#---- Styles ------------------------------------------------------------------
#---- inTextField ----
@ -1343,3 +1346,8 @@ CellOtherSetPane.height=$Component.defaultHeight
background: null;\
track: fade(@background, 0%); \
hoverTrackColor : fade(@background, 0%)
[style]Button.breadcrumbButton = \
background: null;\
foreground: null; \

Loading…
Cancel
Save