Browse Source
Merge in DESIGN/design from ~VITO/c-design:new-ui to newui * commit '7e1f6c1322043502c08a687473b50e8b45a147f4': REPORT-99485 适配主题,同步代码newui
106 changed files with 2302 additions and 963 deletions
@ -0,0 +1,11 @@
|
||||
package com.fine.theme.light.icon; |
||||
|
||||
/** |
||||
* 图标管理器 |
||||
* |
||||
* @author vito |
||||
* @since 11.0 |
||||
* Created on 2023/9/12 |
||||
*/ |
||||
public class IconManager { |
||||
} |
@ -0,0 +1,93 @@
|
||||
package com.fine.theme.light.ui; |
||||
|
||||
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; |
||||
import com.formdev.flatlaf.ui.FlatToggleButtonUI; |
||||
import com.formdev.flatlaf.ui.FlatUIUtils; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.swing.AbstractButton; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JToggleButton; |
||||
import javax.swing.UIManager; |
||||
import javax.swing.plaf.ComponentUI; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Graphics; |
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; |
||||
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE_TAB; |
||||
import static com.formdev.flatlaf.FlatClientProperties.TAB_BUTTON_SELECTED_BACKGROUND; |
||||
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyColor; |
||||
|
||||
/** |
||||
* 提供 {@link javax.swing.JToggleButton} 的UI类 |
||||
* <p> |
||||
* |
||||
* @author vito |
||||
* @uiDefault ToggleButton.tab.arc int |
||||
* @since 11.0 |
||||
* Created on 2023/11/3 |
||||
*/ |
||||
public class FineToggleButtonUI extends FlatToggleButtonUI { |
||||
|
||||
@Styleable(dot = true) |
||||
protected int tabArc; |
||||
|
||||
public static ComponentUI createUI(JComponent c) { |
||||
return FlatUIUtils.canUseSharedUI(c) |
||||
? FlatUIUtils.createSharedUI(FlatToggleButtonUI.class, () -> new FineToggleButtonUI(true)) |
||||
: new FineToggleButtonUI(false); |
||||
} |
||||
|
||||
protected FineToggleButtonUI(boolean shared) { |
||||
super(shared); |
||||
} |
||||
|
||||
@Override |
||||
protected void installDefaults(AbstractButton b) { |
||||
super.installDefaults(b); |
||||
tabArc = UIManager.getInt("ToggleButton.tab.arc"); |
||||
} |
||||
|
||||
|
||||
@Nullable |
||||
static String getButtonTypeStr(AbstractButton c) { |
||||
Object value = c.getClientProperty(BUTTON_TYPE); |
||||
if (value instanceof String) |
||||
return (String) value; |
||||
return null; |
||||
} |
||||
|
||||
static boolean isTabButton(Component c) { |
||||
return c instanceof JToggleButton && BUTTON_TYPE_TAB.equals(getButtonTypeStr((JToggleButton) c)); |
||||
} |
||||
|
||||
@Override |
||||
protected void paintBackground(Graphics g, JComponent c) { |
||||
if (isTabButton(c)) { |
||||
int height = c.getHeight(); |
||||
int width = c.getWidth(); |
||||
boolean selected = ((AbstractButton) c).isSelected(); |
||||
Color enabledColor = selected ? clientPropertyColor(c, TAB_BUTTON_SELECTED_BACKGROUND, tabSelectedBackground) : null; |
||||
|
||||
// use component background if explicitly set
|
||||
if (enabledColor == null) { |
||||
Color bg = c.getBackground(); |
||||
if (isCustomBackground(bg)) |
||||
enabledColor = bg; |
||||
} |
||||
|
||||
// paint background
|
||||
Color background = buttonStateColor(c, enabledColor, |
||||
null, tabFocusBackground, tabHoverBackground, null); |
||||
if (background != null) { |
||||
g.setColor(background); |
||||
g.fillRoundRect(0, 0, width, height, tabArc, tabArc); |
||||
} |
||||
} else |
||||
super.paintBackground(g, c); |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,24 @@
|
||||
package com.fine.theme.light.ui.laf; |
||||
|
||||
import com.formdev.flatlaf.FlatLightLaf; |
||||
|
||||
/** |
||||
* FineReport designer new look and feel |
||||
* |
||||
* @author vito |
||||
* @since 11.0 |
||||
* Created on 2023/9/12 |
||||
*/ |
||||
public class FineLightLaf extends FlatLightLaf { |
||||
public static boolean setup() { |
||||
return setup( new FineLightLaf() ); |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "FineLightLaf"; |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,40 @@
|
||||
package com.fine.theme.light.utils; |
||||
|
||||
import javax.swing.UIManager; |
||||
import java.awt.Color; |
||||
|
||||
/** |
||||
* UI绘制的一些常用方法 |
||||
* |
||||
* @author vito |
||||
* @since 11.0 |
||||
* Created on 2023/11/3 |
||||
*/ |
||||
public class FineUIUtils { |
||||
|
||||
|
||||
/** |
||||
* 通过key获取UI的颜色,如果没有则使用后备key获取 |
||||
* |
||||
* @param key 颜色key |
||||
* @param defaultKey 颜色后备key |
||||
* @return 颜色 |
||||
*/ |
||||
|
||||
public static Color getUIColor(String key, String defaultKey) { |
||||
Color color = UIManager.getColor(key); |
||||
return (color != null) ? color : UIManager.getColor(defaultKey); |
||||
} |
||||
|
||||
/** |
||||
* 获取key指定的int值,如果没有则使用后备key获取 |
||||
* |
||||
* @param key int所在的key |
||||
* @param defaultKey 后备key |
||||
* @return 长度 |
||||
*/ |
||||
public static int getUIInt(String key, String defaultKey) { |
||||
Object value = UIManager.get(key); |
||||
return (value instanceof Integer) ? (Integer) value : UIManager.getInt(defaultKey); |
||||
} |
||||
} |
@ -1,155 +1,201 @@
|
||||
package com.fr.design.gui.ibutton; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.design.utils.gui.UIComponentUtils; |
||||
|
||||
import com.fine.swing.ui.layout.Layouts; |
||||
import com.fine.swing.ui.layout.Row; |
||||
import com.fine.theme.light.utils.FineUIUtils; |
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; |
||||
import com.formdev.flatlaf.ui.FlatUIUtils; |
||||
import com.formdev.flatlaf.util.ScaledEmptyBorder; |
||||
import com.fr.third.guava.collect.Streams; |
||||
|
||||
import javax.swing.AbstractButton; |
||||
import javax.swing.ButtonGroup; |
||||
import javax.swing.Icon; |
||||
import javax.swing.JFrame; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JToggleButton; |
||||
import javax.swing.event.ChangeListener; |
||||
import javax.swing.plaf.ComponentUI; |
||||
import java.awt.Color; |
||||
import java.awt.Dimension; |
||||
import java.awt.GridLayout; |
||||
import java.awt.event.MouseAdapter; |
||||
import java.awt.event.MouseEvent; |
||||
import java.awt.event.MouseListener; |
||||
import java.awt.Graphics; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
|
||||
// fanglei:不是原作者,只是优化如下问题:代码冗余,无法拓展(例如我想加个enable属性没法加),甚至还有数组越界的问题。
|
||||
public class UIHeadGroup extends JPanel { |
||||
private static final int MIN_HEIGHT = 25; |
||||
private List<UIHead> uiHeads = new ArrayList<>(); |
||||
protected List<UIToggleButton> labelButtonList; |
||||
private boolean isNeedLeftRightOutLine = true; |
||||
protected int selectedIndex = -1; |
||||
import static com.fine.swing.ui.layout.Layouts.cell; |
||||
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; |
||||
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE_TAB; |
||||
|
||||
protected void tabChanged(int newSelectedIndex) { |
||||
// do nothing
|
||||
} |
||||
/** |
||||
* 面板头部 tab 按钮组 |
||||
* |
||||
* @author vito |
||||
* @since 11.0 |
||||
* Created on 2023/10/31 |
||||
*/ |
||||
public class UIHeadGroup extends Row { |
||||
|
||||
|
||||
private UIHeadGroupSingleSelectionModel model; |
||||
|
||||
private List<AbstractButton> btns; |
||||
|
||||
private final ButtonGroup buttonGroup = new ButtonGroup(); |
||||
|
||||
public UIHeadGroup(String[] textArray) { |
||||
for (int i = 0; i < textArray.length; i++) { |
||||
uiHeads.add(new UIHead(textArray[i], i)); |
||||
} |
||||
initUIHeadGroup(uiHeads); |
||||
setModel(new UIHeadGroupSingleSelectionModel( |
||||
Arrays.stream(textArray).map(UIHead::new).collect(Collectors.toList()))); |
||||
intiContent(); |
||||
} |
||||
|
||||
public UIHeadGroup(Icon[] iconArray) { |
||||
for (int i = 0; i < iconArray.length; i++) { |
||||
uiHeads.add(new UIHead(iconArray[i], i)); |
||||
} |
||||
initUIHeadGroup(uiHeads); |
||||
setModel(new UIHeadGroupSingleSelectionModel( |
||||
Arrays.stream(iconArray).map(UIHead::new).collect(Collectors.toList()))); |
||||
intiContent(); |
||||
} |
||||
|
||||
public UIHeadGroup(Icon[] iconArray, String[] textArray) { |
||||
int length = Math.min(textArray.length, iconArray.length); |
||||
for (int i = 0; i < length; i++) { |
||||
uiHeads.add(new UIHead(textArray[i], iconArray[i], i)); |
||||
} |
||||
initUIHeadGroup(uiHeads); |
||||
public UIHeadGroup(List<UIHead> heads) { |
||||
setModel(new UIHeadGroupSingleSelectionModel(heads)); |
||||
intiContent(); |
||||
} |
||||
|
||||
public UIHeadGroup(List<UIHead> uiHeads) { |
||||
initUIHeadGroup(uiHeads); |
||||
private void intiContent() { |
||||
setSpacing(4); |
||||
setOpaque(false); |
||||
add(buttonGroup()); |
||||
setUI(new UIHeadGroupUI()); |
||||
setSelectedIndex(0); |
||||
setBorder(new ScaledEmptyBorder(2, 2, 2, 2)); |
||||
} |
||||
|
||||
private Layouts.Cell<?>[] buttonGroup() { |
||||
btns = new ArrayList<>(getModel().getDataList().size()); |
||||
return Streams.mapWithIndex(getModel().getDataList().stream(), |
||||
(h, index) -> cell(new JToggleButton(h.getText(), h.getIcon())) |
||||
.weight(1.0) |
||||
.with(b -> { |
||||
btns.add(b); |
||||
buttonGroup.add(b); |
||||
b.setEnabled(h.isEnable()); |
||||
b.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_TAB); |
||||
b.addActionListener(e -> setSelectedIndex((int) index)); |
||||
}) |
||||
|
||||
).toArray(Layouts.Cell[]::new); |
||||
} |
||||
|
||||
/** |
||||
* tabChanged 时调用 |
||||
* |
||||
* @param newSelectedIndex |
||||
* @see #addChangeListener(ChangeListener) |
||||
* @deprecated 这种方式会导致使用的时候都要创建一个匿名类, 使用监听代替{@link #addChangeListener(ChangeListener)} |
||||
*/ |
||||
@Deprecated |
||||
protected void tabChanged(int newSelectedIndex) { |
||||
// do nothing
|
||||
} |
||||
|
||||
public void initUIHeadGroup(List<UIHead> uiHeads) { |
||||
if (uiHeads != null) { |
||||
labelButtonList = new ArrayList<UIToggleButton>(uiHeads.size()); |
||||
this.setLayout(new GridLayout(0, uiHeads.size(), 1, 0)); |
||||
private static class UIHeadGroupUI extends ComponentUI { |
||||
|
||||
for (UIHead head : uiHeads) { |
||||
if (head.isOnlyText()) { |
||||
this.setBackground(UIConstants.TREE_BACKGROUND); |
||||
} else { |
||||
this.setBackground(UIConstants.NORMAL_BACKGROUND); |
||||
} |
||||
initButton(createUIToggleButton(head)); |
||||
@Styleable(dot = true) |
||||
protected Color background; |
||||
|
||||
@Styleable(dot = true) |
||||
protected int arc; |
||||
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) |
||||
public static ComponentUI createUI(JComponent c) { |
||||
return new UIHeadGroupUI(); |
||||
} |
||||
setSelectedIndex(0); |
||||
|
||||
@Override |
||||
public void installUI(JComponent c) { |
||||
super.installUI(c); |
||||
background = FineUIUtils.getUIColor("HeadGroup.background", "desktop"); |
||||
arc = FineUIUtils.getUIInt("HeadGroup.arc", "Component.arc"); |
||||
} |
||||
|
||||
@Override |
||||
public void uninstallUI(JComponent c) { |
||||
super.uninstallUI(c); |
||||
} |
||||
|
||||
@Override |
||||
public Dimension getPreferredSize() { |
||||
Dimension dim = super.getPreferredSize(); |
||||
if (dim.height < MIN_HEIGHT) { |
||||
dim.height = MIN_HEIGHT; |
||||
public Dimension getMinimumSize(JComponent component) { |
||||
return new Dimension(0, 0); |
||||
} |
||||
return dim; |
||||
|
||||
@Override |
||||
public Dimension getMaximumSize(JComponent component) { |
||||
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); |
||||
} |
||||
|
||||
private void initButton(UIToggleButton labelButton) { |
||||
labelButton.setRoundBorder(false); |
||||
labelButton.setBorderPainted(false); |
||||
labelButton.setPressedPainted(false); |
||||
UIComponentUtils.setLineWrap(labelButton); |
||||
labelButtonList.add(labelButton); |
||||
this.add(labelButton); |
||||
@Override |
||||
public void update(Graphics g, JComponent c) { |
||||
paintBackground(g, c); |
||||
paint(g, c); |
||||
} |
||||
|
||||
public void setSelectedIndex(int newSelectedIndex) { |
||||
selectedIndex = newSelectedIndex; |
||||
for (int i = 0; i < labelButtonList.size(); i++) { |
||||
UIToggleButton button = labelButtonList.get(i); |
||||
if (i == selectedIndex) { |
||||
button.setNormalPainted(false); |
||||
button.setBackground(new Color(240, 240, 243)); |
||||
button.setOpaque(true); |
||||
button.setSelected(true); |
||||
} else { |
||||
button.setOpaque(false); |
||||
button.setNormalPainted(true); |
||||
button.setSelected(false); |
||||
protected void paintBackground(Graphics g, JComponent c) { |
||||
FlatUIUtils.setRenderingHints(g); |
||||
g.setColor(background); |
||||
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); |
||||
} |
||||
} |
||||
|
||||
tabChanged(newSelectedIndex); |
||||
private UIHeadGroupSingleSelectionModel getModel() { |
||||
return model; |
||||
} |
||||
|
||||
public void setNeedLeftRightOutLine(boolean isNeedLeftRightOutLine) { |
||||
this.isNeedLeftRightOutLine = isNeedLeftRightOutLine; |
||||
public void setModel(UIHeadGroupSingleSelectionModel model) { |
||||
this.model = model; |
||||
} |
||||
|
||||
public int getSelectedIndex() { |
||||
return selectedIndex; |
||||
/** |
||||
* 添加一个监听,在tab切换时触发 |
||||
* |
||||
* @param l 监听 |
||||
*/ |
||||
public void addChangeListener(ChangeListener l) { |
||||
getModel().addChangeListener(l); |
||||
} |
||||
|
||||
public UIToggleButton createUIToggleButton(final UIHead head) { |
||||
UIToggleButton uiToggleButton = new UIToggleButton(head.getText(), head.getIcon()) { |
||||
@Override |
||||
protected MouseListener getMouseListener() { |
||||
return new MouseAdapter() { |
||||
@Override |
||||
public void mousePressed(MouseEvent e) { |
||||
if (head.isEnable()) { |
||||
setSelectedIndex(head.getIndex()); |
||||
UIHeadGroup.this.repaint(); |
||||
/** |
||||
* 移除一个监听 |
||||
* |
||||
* @param l 监听 |
||||
*/ |
||||
public void removeChangeListener(ChangeListener l) { |
||||
getModel().removeChangeListener(l); |
||||
} |
||||
|
||||
/** |
||||
* 设置索引用于选中某个tab |
||||
* |
||||
* @param index 面板索引 |
||||
*/ |
||||
public void setSelectedIndex(int index) { |
||||
if (!checkRange(index)) { |
||||
return; |
||||
} |
||||
}; |
||||
buttonGroup.setSelected(btns.get(index).getModel(), true); |
||||
getModel().setSelectedIndex(index); |
||||
tabChanged(index); |
||||
} |
||||
}; |
||||
|
||||
uiToggleButton.setEnabled(head.isEnable()); |
||||
return uiToggleButton; |
||||
/** |
||||
* 获取选中tab的索引 |
||||
* |
||||
* @return 选中tab的索引 |
||||
*/ |
||||
public int getSelectedIndex() { |
||||
return getModel().getSelectedIndex(); |
||||
} |
||||
|
||||
public static void main(String... args) { |
||||
JFrame jf = new JFrame("test"); |
||||
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
||||
JPanel content = (JPanel) jf.getContentPane(); |
||||
content.setLayout(null); |
||||
Icon[] a1 = {BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), |
||||
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png")}; |
||||
UIHeadGroup bb = new UIHeadGroup(a1); |
||||
bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height); |
||||
bb.setSelectedIndex(0); |
||||
content.add(bb); |
||||
GUICoreUtils.centerWindow(jf); |
||||
jf.setSize(400, 400); |
||||
jf.setVisible(true); |
||||
private boolean checkRange(int newSelectedIndex) { |
||||
return newSelectedIndex > -1 && newSelectedIndex < btns.size(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,31 @@
|
||||
package com.fr.design.gui.ibutton; |
||||
|
||||
import javax.swing.DefaultSingleSelectionModel; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 头部按钮组单选模型 |
||||
* |
||||
* @author vito |
||||
* @since 11.0 |
||||
* Created on 2023/11/2 |
||||
*/ |
||||
public class UIHeadGroupSingleSelectionModel extends DefaultSingleSelectionModel { |
||||
|
||||
private final List<UIHead> dataList; |
||||
|
||||
UIHeadGroupSingleSelectionModel(List<UIHead> dataList) { |
||||
this.dataList = dataList; |
||||
} |
||||
|
||||
public UIHeadGroupSingleSelectionModel set(int index, UIHead head) { |
||||
dataList.add(index, head); |
||||
return this; |
||||
} |
||||
|
||||
|
||||
public List<UIHead> getDataList() { |
||||
return dataList; |
||||
} |
||||
|
||||
} |
@ -1,25 +0,0 @@
|
||||
package com.fr.design.gui.imenu; |
||||
|
||||
import java.awt.Color; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
|
||||
import javax.swing.JPanel; |
||||
|
||||
import com.fr.design.constants.UIConstants; |
||||
|
||||
public class UIMenuHighLight extends JPanel{ |
||||
|
||||
@Override |
||||
public Dimension getPreferredSize() { |
||||
Dimension dim = super.getPreferredSize(); |
||||
dim.height = 0; |
||||
return dim; |
||||
} |
||||
public void paint(Graphics g) { |
||||
g.setColor(UIConstants.LINE_COLOR); |
||||
g.drawLine(0, 0, getWidth(), 0); |
||||
g.setColor(Color.WHITE); |
||||
g.drawLine(0, 1, getWidth(), 1); |
||||
}; |
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Copyright (c) 2001-2014,FineReport Inc, All Rights Reserved. |
||||
*/ |
||||
|
||||
package com.fr.design.mainframe.toolbar; |
||||
|
||||
|
||||
import com.formdev.flatlaf.FlatLaf; |
||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange; |
||||
import com.fr.design.actions.UpdateAction; |
||||
|
||||
import javax.swing.LookAndFeel; |
||||
import javax.swing.UIManager; |
||||
import javax.swing.UnsupportedLookAndFeelException; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
public class LookAndFeelAction extends UpdateAction { |
||||
|
||||
private final LookAndFeel lookAndFeel; |
||||
|
||||
public LookAndFeelAction(String name, LookAndFeel lookAndFeel) { |
||||
this.setName(name); |
||||
this.lookAndFeel = lookAndFeel; |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
applyLookAndFeel(lookAndFeel); |
||||
} |
||||
|
||||
private void applyLookAndFeel(LookAndFeel lookAndFeel){ |
||||
FlatAnimatedLafChange.showSnapshot(); |
||||
try { |
||||
UIManager.setLookAndFeel( lookAndFeel ); |
||||
} catch (UnsupportedLookAndFeelException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
FlatLaf.updateUI(); |
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation(); |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
||||
dependencies { |
||||
compile project(':designer-base') |
||||
api project(':designer-base') |
||||
} |
||||
|
@ -1,3 +1,3 @@
|
||||
dependencies { |
||||
compile project(':designer-base') |
||||
api project(':designer-base') |
||||
} |
||||
|
@ -1,4 +1,4 @@
|
||||
dependencies { |
||||
compile project(':designer-form') |
||||
compile project(':designer-chart') |
||||
api project(':designer-form') |
||||
api project(':designer-chart') |
||||
} |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue