3 changed files with 174 additions and 15 deletions
@ -0,0 +1,153 @@
|
||||
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.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; |
||||
|
||||
public class FineBreadcrumbPane <T> extends Row { |
||||
|
||||
private static final int SEP_HEIGHT = 20; |
||||
|
||||
private static final int BUTTON_HEIGHT = 20; |
||||
|
||||
private static final int MAX_BUTTON_WIDTH = FineUIScale.scale(150); |
||||
|
||||
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(); |
||||
|
||||
} |
||||
|
||||
public void addCrumb(final T text, final BreadcrumbBackListener<T> backListener) { |
||||
if (currentCrumb != null) { |
||||
if (text instanceof FILE) { |
||||
FILE file = (FILE) text; |
||||
if (ComparatorUtils.equals(currentCrumb.getContent(), file) || !file.isDirectory()) { |
||||
return; |
||||
} |
||||
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; |
||||
} |
||||
} |
||||
currentCrumb.setSelected(false); |
||||
currentCrumb.setForeground(Color.GRAY); |
||||
add(createSeparator()); |
||||
} |
||||
final BreadcrumbButton breadcrumb = createBreadcrumb(text); |
||||
add(breadcrumb); |
||||
currentCrumb = breadcrumb; |
||||
final int index = getComponentCount(); |
||||
addBreadcrumbListener(breadcrumb, index, backListener); |
||||
} |
||||
|
||||
private void removeTailCrumbs(int from) { |
||||
Component[] components = getComponents(); |
||||
for (int i = from; i < components.length; i++) { |
||||
remove(components[i]); |
||||
} |
||||
currentCrumb = (BreadcrumbButton) components[from-1]; |
||||
revalidate(); |
||||
repaint(); |
||||
} |
||||
|
||||
public void clear() { |
||||
removeAll(); |
||||
currentCrumb = null; |
||||
} |
||||
|
||||
protected Component createSeparator() { |
||||
UILabel separator = new UILabel("/"); |
||||
separator.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); |
||||
separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, FineUIScale.scale(SEP_HEIGHT))); |
||||
|
||||
return separator; |
||||
} |
||||
|
||||
protected BreadcrumbButton createBreadcrumb(T content) { |
||||
BreadcrumbButton button = new BreadcrumbButton(getText(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); |
||||
return button; |
||||
} |
||||
|
||||
private void addBreadcrumbListener(BreadcrumbButton breadcrumb, int index, BreadcrumbBackListener backListener) { |
||||
breadcrumb.addActionListener(e -> { |
||||
removeTailCrumbs(index); |
||||
breadcrumb.setSelected(true); |
||||
breadcrumb.setForeground(Color.BLACK); |
||||
if (breadcrumb != currentCrumb) { |
||||
currentCrumb = breadcrumb; |
||||
} |
||||
if (backListener != null) { |
||||
backListener.onBreadcrumbBack(breadcrumb.getContent()); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private String getText(T text) { |
||||
if (text instanceof String) { |
||||
return (String) text; |
||||
} else if (text instanceof FILE){ |
||||
return ((FILE)text).getName(); |
||||
} |
||||
return (String) text; |
||||
} |
||||
|
||||
public static class BreadcrumbButton <T> extends UIButton { |
||||
|
||||
private T content; |
||||
|
||||
public BreadcrumbButton(String text, T content) { |
||||
super(text); |
||||
BreadcrumbButton.this.content = content; |
||||
setMargin(new Insets(0, 0, 0, 0)); |
||||
setBorder(BorderFactory.createEmptyBorder()); |
||||
FineUIStyle.setStyle(BreadcrumbButton.this, FineUIStyle.PLAIN_BUTTON); |
||||
setBorderPainted(false); |
||||
setOpaque(false); |
||||
} |
||||
|
||||
@Override |
||||
public Insets getMargin() { |
||||
Insets insets = super.getMargin(); |
||||
if (insets != null) { |
||||
insets.set(0, 0, 0, 0); |
||||
} |
||||
return insets; |
||||
} |
||||
|
||||
protected T getContent() { |
||||
return content; |
||||
} |
||||
|
||||
protected void setContent(T content) { |
||||
this.content = content; |
||||
} |
||||
} |
||||
|
||||
public interface BreadcrumbBackListener <T> { |
||||
void onBreadcrumbBack(T text); |
||||
} |
||||
} |
Loading…
Reference in new issue