forked from fanruan/finekit
richie
5 years ago
12 changed files with 1642 additions and 0 deletions
@ -0,0 +1,231 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import com.fanruan.api.design.macro.UIConstants; |
||||||
|
import com.fanruan.api.design.util.GUICoreKit; |
||||||
|
import com.fanruan.api.util.AssistKit; |
||||||
|
import com.fanruan.api.util.GeneralKit; |
||||||
|
import com.fr.design.event.GlobalNameListener; |
||||||
|
import com.fr.design.event.GlobalNameObserver; |
||||||
|
import com.fr.design.event.UIObserver; |
||||||
|
import com.fr.design.event.UIObserverListener; |
||||||
|
import com.fr.design.gui.ibutton.UIButtonUI; |
||||||
|
import com.fr.design.gui.ipoppane.PopupHider; |
||||||
|
import com.fr.design.style.color.ColorControlWindow; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import javax.swing.event.EventListenerList; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
*/ |
||||||
|
public class UIColorButton extends UIButton implements PopupHider, UIObserver, GlobalNameObserver { |
||||||
|
|
||||||
|
private static final int SIZE = 16; |
||||||
|
private static final int SIZE_2 = 2; |
||||||
|
private static final int SIZE_4 = 4; |
||||||
|
private static final int SIZE_6 = 6; |
||||||
|
private static final int POPUP_MENU_SHIFT = -70; |
||||||
|
private Color color = Color.BLACK; |
||||||
|
private ColorControlWindow popupWin; |
||||||
|
private EventListenerList colorChangeListenerList = new EventListenerList(); |
||||||
|
private boolean isEventBanned = false; |
||||||
|
private String colorButtonName = ""; |
||||||
|
private UIObserverListener uiObserverListener; |
||||||
|
private GlobalNameListener globalNameListener = null; |
||||||
|
|
||||||
|
public UIColorButton() { |
||||||
|
this(UIConstants.FONT_ICON); |
||||||
|
} |
||||||
|
|
||||||
|
public UIColorButton(Icon icon) { |
||||||
|
super(icon); |
||||||
|
setUI(getButtonUI()); |
||||||
|
addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
showPopupMenu(); |
||||||
|
} |
||||||
|
}); |
||||||
|
iniListener(); |
||||||
|
} |
||||||
|
|
||||||
|
private void iniListener() { |
||||||
|
if (shouldResponseChangeListener()) { |
||||||
|
this.addColorChangeListener(new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
if (uiObserverListener == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (globalNameListener != null && shouldResponseNameListener()) { |
||||||
|
globalNameListener.setGlobalName(colorButtonName); |
||||||
|
} |
||||||
|
uiObserverListener.doChange(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private UIButtonUI getButtonUI() { |
||||||
|
return new UIButtonUI() { |
||||||
|
@Override |
||||||
|
protected void paintIcon(Graphics g, JComponent c) { |
||||||
|
super.paintIcon(g, c); |
||||||
|
AbstractButton b = (AbstractButton) c; |
||||||
|
ButtonModel model = b.getModel(); |
||||||
|
if (model.isEnabled()) { |
||||||
|
g.setColor(UIColorButton.this.getColor()); |
||||||
|
} else { |
||||||
|
g.setColor(new Color(GeneralKit.filterRGB(UIColorButton.this.getColor().getRGB(), 50))); |
||||||
|
} |
||||||
|
g.fillRect((b.getWidth() - SIZE) / SIZE_2, b.getHeight() - SIZE_6, SIZE, SIZE_4); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEventBanned(boolean isEventBanned) { |
||||||
|
this.isEventBanned = isEventBanned; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGlobalName(String name) { |
||||||
|
colorButtonName = name; |
||||||
|
} |
||||||
|
|
||||||
|
public Color getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(Color color) { |
||||||
|
if (AssistKit.equals(this.color, color)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
this.color = color; |
||||||
|
hidePopupMenu(); |
||||||
|
fireColorStateChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
private void showPopupMenu() { |
||||||
|
if (isEventBanned) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (popupWin != null && popupWin.isVisible()) { |
||||||
|
hidePopupMenu(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (!this.isEnabled()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
popupWin = this.getColorControlWindow(); |
||||||
|
|
||||||
|
GUICoreKit.showPopupMenu(popupWin, this, POPUP_MENU_SHIFT, this.getSize().height); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 隐藏popupmenu |
||||||
|
*/ |
||||||
|
public void hidePopupMenu() { |
||||||
|
if (popupWin != null) { |
||||||
|
popupWin.setVisible(false); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
popupWin = null; |
||||||
|
} |
||||||
|
|
||||||
|
private ColorControlWindow getColorControlWindow() { |
||||||
|
if (this.popupWin == null) { |
||||||
|
this.popupWin = new ColorControlWindow(UIColorButton.this) { |
||||||
|
@Override |
||||||
|
protected void colorChanged() { |
||||||
|
UIColorButton.this.setColor(this.getColor()); |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
return popupWin; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 添加监听 |
||||||
|
* |
||||||
|
* @param changeListener 监听列表 |
||||||
|
*/ |
||||||
|
public void addColorChangeListener(ChangeListener changeListener) { |
||||||
|
colorChangeListenerList.add(ChangeListener.class, changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 移除监听 |
||||||
|
* Removes an old ColorChangeListener. |
||||||
|
* |
||||||
|
* @param changeListener 监听列表 |
||||||
|
*/ |
||||||
|
public void removeColorChangeListener(ChangeListener changeListener) { |
||||||
|
colorChangeListenerList.remove(ChangeListener.class, changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 颜色状态改变 |
||||||
|
*/ |
||||||
|
public void fireColorStateChanged() { |
||||||
|
Object[] listeners = colorChangeListenerList.getListenerList(); |
||||||
|
ChangeEvent e = null; |
||||||
|
|
||||||
|
for (int i = listeners.length - 2; i >= 0; i -= 2) { |
||||||
|
if (listeners[i] == ChangeListener.class) { |
||||||
|
if (e == null) { |
||||||
|
e = new ChangeEvent(this); |
||||||
|
} |
||||||
|
((ChangeListener) listeners[i + 1]).stateChanged(e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 注册状态改变监听 |
||||||
|
* |
||||||
|
* @param listener 观察者监听事件 |
||||||
|
*/ |
||||||
|
public void registerChangeListener(UIObserverListener listener) { |
||||||
|
uiObserverListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否需要响应监听 |
||||||
|
* |
||||||
|
* @return 是否响应 |
||||||
|
*/ |
||||||
|
public boolean shouldResponseChangeListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 注册监听 |
||||||
|
* |
||||||
|
* @param listener 观察者监听事件 |
||||||
|
*/ |
||||||
|
public void registerNameListener(GlobalNameListener listener) { |
||||||
|
globalNameListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否需要相应 |
||||||
|
* |
||||||
|
* @return 是否响应 |
||||||
|
*/ |
||||||
|
public boolean shouldResponseNameListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,245 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import com.fanruan.api.design.macro.UIConstants; |
||||||
|
import com.fanruan.api.util.StringKit; |
||||||
|
import com.fr.design.event.GlobalNameListener; |
||||||
|
import com.fr.design.event.GlobalNameObserver; |
||||||
|
import com.fr.design.gui.ibutton.UIButtonUI; |
||||||
|
import com.fr.design.roleAuthority.ReportAndFSManagePane; |
||||||
|
import com.fr.design.utils.gui.GUIPaintUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.awt.geom.RoundRectangle2D; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 可切换状态的按钮 |
||||||
|
*/ |
||||||
|
public class UIToggleButton extends UIButton implements GlobalNameObserver { |
||||||
|
|
||||||
|
private static final int ICON_COUNT = 2; |
||||||
|
private boolean selected; |
||||||
|
private boolean eventBanned = false; |
||||||
|
private String toggleButtonName = StringKit.EMPTY; |
||||||
|
private GlobalNameListener globalNameListener = null; |
||||||
|
private Icon[] icons; |
||||||
|
|
||||||
|
public UIToggleButton() { |
||||||
|
this(StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
public UIToggleButton(Icon image) { |
||||||
|
this(StringKit.EMPTY, image); |
||||||
|
} |
||||||
|
|
||||||
|
public UIToggleButton(String text) { |
||||||
|
this(text, null); |
||||||
|
} |
||||||
|
|
||||||
|
public UIToggleButton(String text, Icon image) { |
||||||
|
super(text, image); |
||||||
|
addMouseListener(getMouseListener()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 需要反白的按钮接口(组合按钮情况-UIButtonGroup) |
||||||
|
* support icons[normalIcon, selectedIcon] |
||||||
|
* |
||||||
|
* @param icons 图标 |
||||||
|
*/ |
||||||
|
public UIToggleButton(Icon[] icons) { |
||||||
|
super(icons[0], null, null); |
||||||
|
setExtraPainted(true); |
||||||
|
this.icons = icons; |
||||||
|
addActionListener(new AbstractAction() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (!UIToggleButton.super.isSelected()) { |
||||||
|
UIToggleButton.super.setSelected(!UIToggleButton.super.isSelected()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
addMouseListener(getMouseListener()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 需要反白的按钮接口(单个按钮情况)-再次点击取消选中状态 |
||||||
|
* |
||||||
|
* @param icons 图标 |
||||||
|
* @param needRelease 是否能够点击之后释放 |
||||||
|
*/ |
||||||
|
public UIToggleButton(Icon[] icons, boolean needRelease) { |
||||||
|
super(icons[0], null, null); |
||||||
|
setBorderPainted(true); |
||||||
|
setExtraPainted(true); |
||||||
|
this.icons = icons; |
||||||
|
if (!needRelease) { |
||||||
|
addActionListener(new AbstractAction() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (UIToggleButton.super.isSelected()) { |
||||||
|
UIToggleButton.super.setSelected(false); |
||||||
|
} else { |
||||||
|
UIToggleButton.super.setSelected(true); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
addMouseListener(getMouseListener()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public final void setGlobalName(String name) { |
||||||
|
toggleButtonName = name; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public final boolean isSelected() { |
||||||
|
return selected; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public final void setSelected(boolean isSelected) { |
||||||
|
super.setSelected(isSelected); |
||||||
|
if (this.selected != isSelected) { |
||||||
|
this.selected = isSelected; |
||||||
|
refresh(isSelected); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initListener() { |
||||||
|
if (shouldResponseChangeListener()) { |
||||||
|
this.addChangeListener(new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
if (uiObserverListener == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (globalNameListener != null && shouldResponseNameListener()) { |
||||||
|
globalNameListener.setGlobalName(toggleButtonName); |
||||||
|
} |
||||||
|
uiObserverListener.doChange(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public final void setSelectedWithFireListener(boolean isSelected) { |
||||||
|
if (this.selected != isSelected) { |
||||||
|
this.selected = isSelected; |
||||||
|
fireSelectedChanged(); |
||||||
|
refresh(isSelected); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void refresh(final boolean isSelected) { |
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
Icon[] icons = UIToggleButton.this.icons; |
||||||
|
if (icons != null && icons.length == ICON_COUNT) { |
||||||
|
if (isSelected) { |
||||||
|
UIToggleButton.this.setIcon(icons[1]); |
||||||
|
} else { |
||||||
|
UIToggleButton.this.setIcon(icons[0]); |
||||||
|
} |
||||||
|
} |
||||||
|
UIToggleButton.this.repaint(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected MouseListener getMouseListener() { |
||||||
|
return new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (isEnabled() && !eventBanned) { |
||||||
|
setSelectedWithFireListener(!isSelected()); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEventBanned(boolean ban) { |
||||||
|
this.eventBanned = ban; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void fireStateChanged() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected final void fireSelectedChanged() { |
||||||
|
Object[] listeners = listenerList.getListenerList(); |
||||||
|
|
||||||
|
for (int i = listeners.length - 2; i >= 0; i -= 2) { |
||||||
|
if (listeners[i] == ChangeListener.class) { |
||||||
|
((ChangeListener) listeners[i + 1]).stateChanged(new ChangeEvent(this)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected final void paintBorder(Graphics g) { |
||||||
|
if (!isBorderPainted()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
boolean isBorderPainted = isBorderPaintedOnlyWhenPressed && (getModel().isPressed() || selected); |
||||||
|
if (isBorderPainted || !isBorderPaintedOnlyWhenPressed) { |
||||||
|
if (ui instanceof UIButtonUI) { |
||||||
|
drawRoleName((Graphics2D) g); |
||||||
|
} else { |
||||||
|
super.paintBorder(g); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void drawRoleName(Graphics2D g) { |
||||||
|
String roleName = ReportAndFSManagePane.getInstance().getRoleTree().getSelectedRoleName(); |
||||||
|
GUIPaintUtils.drawBorder(g, 0, 0, getWidth(), getHeight(), isRoundBorder(), getRectDirection(), isDoneAuthorityEdited(roleName)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected final void paintOtherBorder(Graphics g) { |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
g2d.setStroke(UIConstants.BS); |
||||||
|
Shape shape = new RoundRectangle2D.Float(0.5f, 0.5f, getWidth() - 1F, getHeight() - 1F, UIConstants.ARC, UIConstants.ARC); |
||||||
|
g2d.setColor(UIConstants.LINE_COLOR); |
||||||
|
g2d.draw(shape); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 组件是否需要响应添加的观察者事件 |
||||||
|
* |
||||||
|
* @return 如果需要响应观察者事件则返回true,否则返回false |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public final boolean shouldResponseChangeListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param listener 观察者监听事件 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public final void registerNameListener(GlobalNameListener listener) { |
||||||
|
globalNameListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean shouldResponseNameListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.pane; |
||||||
|
|
||||||
|
import javax.swing.text.StyledDocument; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 用于显示文本的容器(可显示富文本) |
||||||
|
* @see javax.swing.JTextPane |
||||||
|
*/ |
||||||
|
public class UITextPane extends com.fr.design.gui.frpane.UITextPane { |
||||||
|
|
||||||
|
/** |
||||||
|
* 构造容器 |
||||||
|
*/ |
||||||
|
public UITextPane() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据特定的样式构造容器 |
||||||
|
* |
||||||
|
* @param document 样式 |
||||||
|
*/ |
||||||
|
public UITextPane(StyledDocument document) { |
||||||
|
super(document); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,188 @@ |
|||||||
|
package com.fanruan.api.design.work; |
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.pane.UITextPane; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.util.AssistKit; |
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.formula.FormulaFactory; |
||||||
|
import com.fr.design.formula.UIFormula; |
||||||
|
import com.fr.report.cell.cellattr.core.RichText; |
||||||
|
import com.fr.report.cell.cellattr.core.RichTextConverter; |
||||||
|
|
||||||
|
import javax.swing.text.AttributeSet; |
||||||
|
import javax.swing.text.BadLocationException; |
||||||
|
import javax.swing.text.Element; |
||||||
|
import javax.swing.text.StyledDocument; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 富文本编辑器容器 |
||||||
|
*/ |
||||||
|
public class RichTextEditingPane extends UITextPane { |
||||||
|
|
||||||
|
private static final int WRAPPER_LEN = 3; |
||||||
|
|
||||||
|
private static final int PREFIX_LEN = 2; |
||||||
|
|
||||||
|
private boolean updating = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* 构造函数 |
||||||
|
*/ |
||||||
|
public RichTextEditingPane() { |
||||||
|
//双击选取公式监听器
|
||||||
|
//往前回溯, 寻找${, 如果发现先找到了}, 说明不在公式内部, 直接return.
|
||||||
|
//有可能当前字符刚好处于{后面, 所以要-1
|
||||||
|
//发现大括号了, 再找$
|
||||||
|
//再往后找"}"
|
||||||
|
//发现左大括号了, 肯定异常
|
||||||
|
//要把后缀包进去, 所以+1
|
||||||
|
// 取得选择文本的起始位置和结束位置
|
||||||
|
//公式起点
|
||||||
|
//公式终点
|
||||||
|
//找到公式的起点与终点了, 下面就是选中, 并弹出编辑窗口
|
||||||
|
//缓存第一个字符的样式, 用于给新公式设置样式
|
||||||
|
//弹出公式编辑窗口
|
||||||
|
MouseListener doubleClickFormulaListener = new MouseAdapter() { |
||||||
|
|
||||||
|
private int findFormulaStart(int start, StyledDocument doc) throws BadLocationException { |
||||||
|
//往前回溯, 寻找${, 如果发现先找到了}, 说明不在公式内部, 直接return.
|
||||||
|
//有可能当前字符刚好处于{后面, 所以要-1
|
||||||
|
for (int i = start - 1; i >= 0; i--) { |
||||||
|
String text = doc.getText(i, 1); |
||||||
|
if (AssistKit.equals(text, RichText.SUFFIX)) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
//发现大括号了, 再找$
|
||||||
|
if (AssistKit.equals(text, RichText.PREFIX)) { |
||||||
|
if (i - 1 >= 0 && AssistKit.equals(doc.getText(i - 1, 1), RichText.FLAG)) { |
||||||
|
return i - 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
private int findFormulaEnd(int start, StyledDocument doc) throws BadLocationException { |
||||||
|
//再往后找"}"
|
||||||
|
int total = doc.getLength(); |
||||||
|
for (int j = start; j < total; j++) { |
||||||
|
String text = doc.getText(j, 1); |
||||||
|
//发现左大括号了, 肯定异常
|
||||||
|
if (AssistKit.equals(text, RichText.PREFIX)) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
if (AssistKit.equals(text, RichText.SUFFIX)) { |
||||||
|
//要把后缀包进去, 所以+1
|
||||||
|
return j + 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
private void popUpFormulaEditPane(final String formulaContent, final int formulaStart, |
||||||
|
final AttributeSet attrs) { |
||||||
|
final UIFormula formulaPane = FormulaFactory.createFormulaPane(); |
||||||
|
formulaPane.populate(BaseFormula.createFormulaBuilder().build(formulaContent)); |
||||||
|
formulaPane.showLargeWindow(DesignKit.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
StyledDocument doc = (StyledDocument) RichTextEditingPane.this.getDocument(); |
||||||
|
BaseFormula fm = formulaPane.update(); |
||||||
|
String content = RichTextConverter.asFormula(fm.getContent()); |
||||||
|
try { |
||||||
|
doc.remove(formulaStart, formulaContent.length() + WRAPPER_LEN); |
||||||
|
doc.insertString(formulaStart, content, attrs); |
||||||
|
} catch (BadLocationException e) { |
||||||
|
LogKit.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}).setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseReleased(MouseEvent e) { |
||||||
|
if (e.getClickCount() == 2) { |
||||||
|
// 取得选择文本的起始位置和结束位置
|
||||||
|
int start = RichTextEditingPane.this.getSelectionStart(); |
||||||
|
|
||||||
|
if (start <= 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
StyledDocument doc = (StyledDocument) RichTextEditingPane.this.getDocument(); |
||||||
|
try { |
||||||
|
//公式起点
|
||||||
|
final int formulaStart = findFormulaStart(start, doc); |
||||||
|
if (formulaStart == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//公式终点
|
||||||
|
int formulaEnd = findFormulaEnd(start, doc); |
||||||
|
if (formulaEnd == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//找到公式的起点与终点了, 下面就是选中, 并弹出编辑窗口
|
||||||
|
RichTextEditingPane.this.select(formulaStart, formulaEnd); |
||||||
|
//缓存第一个字符的样式, 用于给新公式设置样式
|
||||||
|
Element ele = doc.getCharacterElement(formulaStart); |
||||||
|
final AttributeSet attrs = ele.getAttributes(); |
||||||
|
|
||||||
|
final String formulaContent = doc.getText(formulaStart + PREFIX_LEN, formulaEnd - formulaStart - WRAPPER_LEN); |
||||||
|
//弹出公式编辑窗口
|
||||||
|
popUpFormulaEditPane(formulaContent, formulaStart, attrs); |
||||||
|
} catch (BadLocationException e1) { |
||||||
|
LogKit.error(e1.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
this.addMouseListener(doubleClickFormulaListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否有其他进程正在更新编辑区域 |
||||||
|
* |
||||||
|
* @return 是否有其他进程正在更新编辑区域 |
||||||
|
*/ |
||||||
|
public boolean isUpdating() { |
||||||
|
return updating; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置更新状态 |
||||||
|
* |
||||||
|
* @param updating 是否正在更新 |
||||||
|
*/ |
||||||
|
public void setUpdating(boolean updating) { |
||||||
|
this.updating = updating; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 开始更新 |
||||||
|
*/ |
||||||
|
public void startUpdating() { |
||||||
|
this.updating = true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 结束更新 |
||||||
|
*/ |
||||||
|
public void finishUpdating() { |
||||||
|
this.updating = false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,612 @@ |
|||||||
|
package com.fanruan.api.design.work; |
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.UIButton; |
||||||
|
import com.fanruan.api.design.ui.component.UIComboBox; |
||||||
|
import com.fanruan.api.design.ui.component.UIToggleButton; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.util.GeneralKit; |
||||||
|
import com.fanruan.api.util.IOKit; |
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.formula.FormulaFactory; |
||||||
|
import com.fr.design.formula.UIFormula; |
||||||
|
import com.fr.design.gui.style.FRFontPane; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.report.RichTextEditingPane; |
||||||
|
import com.fr.design.report.RichTextPane; |
||||||
|
import com.fr.design.style.color.UIToolbarColorButton; |
||||||
|
import com.fr.general.FRFont; |
||||||
|
import com.fr.report.cell.cellattr.core.RichTextConverter; |
||||||
|
import com.fr.stable.Constants; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.CaretEvent; |
||||||
|
import javax.swing.event.CaretListener; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import javax.swing.event.DocumentEvent; |
||||||
|
import javax.swing.event.DocumentListener; |
||||||
|
import javax.swing.text.AttributeSet; |
||||||
|
import javax.swing.text.BadLocationException; |
||||||
|
import javax.swing.text.Element; |
||||||
|
import javax.swing.text.MutableAttributeSet; |
||||||
|
import javax.swing.text.SimpleAttributeSet; |
||||||
|
import javax.swing.text.StyleConstants; |
||||||
|
import javax.swing.text.StyledDocument; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 富文本编辑器工具栏 |
||||||
|
*/ |
||||||
|
public class RichTextToolBar extends BasicPane { |
||||||
|
|
||||||
|
private static final Dimension BUTTON_SIZE = new Dimension(24, 20); |
||||||
|
|
||||||
|
private static final int NOT_INITIALIZED = -1; |
||||||
|
private static final int UPDATING = -2; |
||||||
|
|
||||||
|
private int inputStart = NOT_INITIALIZED; |
||||||
|
|
||||||
|
private UIComboBox<String> fontNameComboBox; |
||||||
|
private UIComboBox<Integer> fontSizeComboBox; |
||||||
|
private UIToggleButton bold; |
||||||
|
private UIToggleButton italic; |
||||||
|
private UIToggleButton underline; |
||||||
|
|
||||||
|
private UIToolbarColorButton colorSelectPane; |
||||||
|
private UIToggleButton superPane; |
||||||
|
private UIToggleButton subPane; |
||||||
|
private UIToggleButton formulaPane; |
||||||
|
|
||||||
|
//外部传进来的
|
||||||
|
private RichTextEditingPane textPane; |
||||||
|
|
||||||
|
public RichTextToolBar() { |
||||||
|
this.initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
public RichTextToolBar(RichTextEditingPane textPane) { |
||||||
|
this.textPane = textPane; |
||||||
|
|
||||||
|
this.initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return DesignKit.i18nText("Fine-Design_Form_Font"); |
||||||
|
} |
||||||
|
|
||||||
|
protected void initComponents() { |
||||||
|
//初始化并设置所有按钮样式
|
||||||
|
initAllButton(); |
||||||
|
//添加到工具栏
|
||||||
|
addToToolBar(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initAllButton() { |
||||||
|
fontNameComboBox = new UIComboBox<>(GeneralKit.getAvailableFontFamilyNames()); |
||||||
|
fontNameComboBox.setPreferredSize(new Dimension(144, 20)); |
||||||
|
fontSizeComboBox = new UIComboBox<>(FRFontPane.getFontSizes()); |
||||||
|
colorSelectPane = new UIToolbarColorButton(IOKit.readIcon("/com/fr/design/images/gui/color/foreground.png")); |
||||||
|
colorSelectPane.set4Toolbar(); |
||||||
|
|
||||||
|
bold = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); |
||||||
|
italic = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); |
||||||
|
underline = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png")); |
||||||
|
superPane = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_format/cellstyle/sup.png")); |
||||||
|
subPane = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_format/cellstyle/sub.png")); |
||||||
|
formulaPane = new UIToggleButton(IOKit.readIcon("/com/fr/design/images/m_insert/formula.png")); |
||||||
|
|
||||||
|
//名字
|
||||||
|
initAllNames(); |
||||||
|
//悬浮提示
|
||||||
|
setToolTips(); |
||||||
|
//样式
|
||||||
|
setAllButtonStyle(); |
||||||
|
//绑定监听器
|
||||||
|
bindListener(); |
||||||
|
} |
||||||
|
|
||||||
|
private void setAllButtonStyle() { |
||||||
|
setButtonStyle(bold); |
||||||
|
setButtonStyle(italic); |
||||||
|
setButtonStyle(underline); |
||||||
|
setButtonStyle(subPane); |
||||||
|
setButtonStyle(superPane); |
||||||
|
setButtonStyle(formulaPane); |
||||||
|
} |
||||||
|
|
||||||
|
private void setButtonStyle(UIButton button) { |
||||||
|
button.setNormalPainted(false); |
||||||
|
button.setBackground(null); |
||||||
|
button.setOpaque(false); |
||||||
|
button.setPreferredSize(BUTTON_SIZE); |
||||||
|
button.setBorderPaintedOnlyWhenPressed(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void addToToolBar() { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT)); |
||||||
|
|
||||||
|
this.add(fontNameComboBox); |
||||||
|
this.add(fontSizeComboBox); |
||||||
|
this.add(bold); |
||||||
|
this.add(italic); |
||||||
|
this.add(underline); |
||||||
|
this.add(colorSelectPane); |
||||||
|
this.add(superPane); |
||||||
|
this.add(subPane); |
||||||
|
this.add(formulaPane); |
||||||
|
} |
||||||
|
|
||||||
|
private void bindListener() { |
||||||
|
FRFont defaultFont = (this.textPane != null) ? FRFont.getInstance(this.textPane.getFont()) : RichTextPane.DEFAUL_FONT; |
||||||
|
fontNameComboBox.addItemListener(fontNameItemListener); |
||||||
|
fontNameComboBox.setSelectedItem(defaultFont.getFontName()); |
||||||
|
fontSizeComboBox.addItemListener(fontSizeItemListener); |
||||||
|
fontSizeComboBox.setSelectedItem(scaleDown(defaultFont.getSize())); |
||||||
|
|
||||||
|
bold.addActionListener(blodChangeAction); |
||||||
|
italic.addActionListener(itaChangeAction); |
||||||
|
underline.addActionListener(underlineChangeAction); |
||||||
|
subPane.addActionListener(subChangeAction); |
||||||
|
superPane.addActionListener(superChangeAction); |
||||||
|
colorSelectPane.addColorChangeListener(colorChangeAction); |
||||||
|
formulaPane.addActionListener(formulaActionListener); |
||||||
|
|
||||||
|
//选中文字的监听器
|
||||||
|
textPane.addCaretListener(textCareListener); |
||||||
|
textPane.addMouseListener(setMouseCurrentStyle); |
||||||
|
textPane.getDocument().addDocumentListener(inputListener); |
||||||
|
} |
||||||
|
|
||||||
|
private void initAllNames() { |
||||||
|
fontNameComboBox.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Font_Family")); |
||||||
|
fontSizeComboBox.setGlobalName(DesignKit.i18nText("Fine-Design_Form_Font_Size")); |
||||||
|
italic.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Italic")); |
||||||
|
bold.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Bold")); |
||||||
|
underline.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Underline")); |
||||||
|
superPane.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Super_Script")); |
||||||
|
subPane.setGlobalName(DesignKit.i18nText("Fine-Design_Report_Sub_Script")); |
||||||
|
} |
||||||
|
|
||||||
|
private void setToolTips() { |
||||||
|
colorSelectPane.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Foreground")); |
||||||
|
italic.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Italic")); |
||||||
|
bold.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Bold")); |
||||||
|
underline.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Underline")); |
||||||
|
superPane.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Super_Script")); |
||||||
|
subPane.setToolTipText(DesignKit.i18nText("Fine-Design_Report_Sub_Script")); |
||||||
|
formulaPane.setToolTipText(DesignKit.i18nText("Fine-Design_Basic_Formula")); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 移除输入监听 |
||||||
|
* 用于populate时, 插入字符串, 那时不需要插入监听 |
||||||
|
*/ |
||||||
|
public void removeInputListener() { |
||||||
|
this.textPane.getDocument().removeDocumentListener(inputListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 增加输入监听事件 |
||||||
|
*/ |
||||||
|
public void addInputListener() { |
||||||
|
this.textPane.getDocument().addDocumentListener(inputListener); |
||||||
|
} |
||||||
|
|
||||||
|
private ActionListener blodChangeAction = new ActionListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isBold = RichTextToolBar.this.bold.isSelected(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setBold(attr, !isBold); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private ActionListener itaChangeAction = new ActionListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isIta = RichTextToolBar.this.italic.isSelected(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setItalic(attr, !isIta); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private ActionListener underlineChangeAction = new ActionListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isUnder = RichTextToolBar.this.underline.isSelected(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setUnderline(attr, !isUnder); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
private ActionListener subChangeAction = new ActionListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isSub = RichTextToolBar.this.subPane.isSelected(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setSubscript(attr, !isSub); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
private ActionListener superChangeAction = new ActionListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isSuper = RichTextToolBar.this.superPane.isSelected(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setSuperscript(attr, !isSuper); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private ChangeListener colorChangeAction = new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
Color color = RichTextToolBar.this.colorSelectPane.getColor(); |
||||||
|
color = color == null ? Color.BLACK : color; |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setForeground(attr, color); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// 设置文本区选择文本的样式
|
||||||
|
private void setCharacterAttributes(JEditorPane editor, AttributeSet attr, |
||||||
|
boolean replace) { |
||||||
|
//注意不要失焦
|
||||||
|
textPane.requestFocus(); |
||||||
|
|
||||||
|
// 取得选择文本的起始位置和结束位置
|
||||||
|
int start = editor.getSelectionStart(); |
||||||
|
int end = editor.getSelectionEnd(); |
||||||
|
|
||||||
|
// 如果选中文本,设置选中文本的样式
|
||||||
|
if (start != end) { |
||||||
|
StyledDocument doc = (StyledDocument) textPane.getDocument(); |
||||||
|
// 将所选文本设置为新的样式,replace为false表示不覆盖原有的样式
|
||||||
|
doc.setCharacterAttributes(start, end - start, attr, replace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ItemListener fontSizeItemListener = new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
int fontSize = (Integer) RichTextToolBar.this.fontSizeComboBox.getSelectedItem(); |
||||||
|
fontSize = scaleUp(fontSize); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setFontSize(attr, fontSize); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private ItemListener fontNameItemListener = new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
String fontName = (String) RichTextToolBar.this.fontNameComboBox.getSelectedItem(); |
||||||
|
// 调用setCharacterAttributes函数设置文本区选择文本的字体
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setFontFamily(attr, fontName); |
||||||
|
setCharacterAttributes(RichTextToolBar.this.textPane, attr, false); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private ActionListener formulaActionListener = new ActionListener() { |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
final UIFormula formulaPane = FormulaFactory.createFormulaPane(); |
||||||
|
formulaPane.populate(BaseFormula.createFormulaBuilder().build()); |
||||||
|
formulaPane.showLargeWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
StyledDocument doc = (StyledDocument) textPane.getDocument(); |
||||||
|
BaseFormula fm = formulaPane.update(); |
||||||
|
String content = RichTextConverter.asFormula(fm.getContent()); |
||||||
|
int start = textPane.getSelectionStart(); |
||||||
|
AttributeSet attrs = start > 0 ? doc.getCharacterElement(start - 1).getAttributes() : new SimpleAttributeSet(); |
||||||
|
try { |
||||||
|
doc.insertString(start, content, attrs); |
||||||
|
} catch (BadLocationException e) { |
||||||
|
LogKit.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}).setVisible(true); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private int roundUp(double num) { |
||||||
|
String numStr = Double.toString(num); |
||||||
|
numStr = new BigDecimal(numStr).setScale(0, BigDecimal.ROUND_HALF_UP).toString(); |
||||||
|
return Integer.parseInt(numStr); |
||||||
|
} |
||||||
|
|
||||||
|
private CaretListener textCareListener = new CaretListener() { |
||||||
|
|
||||||
|
//根据选中部分的文字样式, 来动态显示工具栏上按钮的状态
|
||||||
|
private void setSelectedCharStyle(int start, int end, StyledDocument doc) { |
||||||
|
boolean isBold = true; |
||||||
|
boolean isItalic = true; |
||||||
|
boolean isUnderline = true; |
||||||
|
boolean isSubscript = true; |
||||||
|
boolean isSuperscript = true; |
||||||
|
String fontName_1st = null; |
||||||
|
int fontSize_1st = 0; |
||||||
|
Color fontColor_1st = null; |
||||||
|
|
||||||
|
for (int i = start; i < end; i++) { |
||||||
|
Element ele = doc.getCharacterElement(i); |
||||||
|
AttributeSet attrs = ele.getAttributes(); |
||||||
|
|
||||||
|
//粗体
|
||||||
|
isBold = isBold && StyleConstants.isBold(attrs); |
||||||
|
//斜体
|
||||||
|
isItalic = isItalic && StyleConstants.isItalic(attrs); |
||||||
|
//下划线
|
||||||
|
isUnderline = isUnderline && StyleConstants.isUnderline(attrs); |
||||||
|
//下标
|
||||||
|
isSubscript = isSubscript && StyleConstants.isSubscript(attrs); |
||||||
|
//上标
|
||||||
|
isSuperscript = isSuperscript && StyleConstants.isSuperscript(attrs); |
||||||
|
|
||||||
|
if (i == start) { |
||||||
|
fontName_1st = (String) attrs.getAttribute(StyleConstants.FontFamily); |
||||||
|
fontSize_1st = (Integer) attrs.getAttribute(StyleConstants.FontSize); |
||||||
|
fontColor_1st = (Color) attrs.getAttribute(StyleConstants.Foreground); |
||||||
|
fontColor_1st = fontColor_1st == null ? Color.BLACK : fontColor_1st; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
setButtonSelected(isBold, isItalic, isUnderline, isSubscript, isSuperscript, |
||||||
|
fontName_1st, fontSize_1st, fontColor_1st); |
||||||
|
} |
||||||
|
|
||||||
|
//动态显示工具栏上按钮的状态
|
||||||
|
private void setButtonSelected(boolean isBold, boolean isItalic, boolean isUnderline, |
||||||
|
boolean isSubscript, boolean isSuperscript, String fontName_1st, |
||||||
|
int fontSize_1st, Color fontColor_1st) { |
||||||
|
bold.setSelected(isBold); |
||||||
|
italic.setSelected(isItalic); |
||||||
|
underline.setSelected(isUnderline); |
||||||
|
subPane.setSelected(isSubscript); |
||||||
|
superPane.setSelected(isSuperscript); |
||||||
|
//为什么字体名称, 大小, 颜色, 不需要去判断是否全相同呢
|
||||||
|
//因为如果全相同, 则设置为第一个字符的样式, 如果不全相同, 那么默认也设置成第一个字符的样式.
|
||||||
|
fontNameComboBox.setSelectedItem(fontName_1st); |
||||||
|
fontSizeComboBox.removeItemListener(fontSizeItemListener); |
||||||
|
fontSizeComboBox.setSelectedItem(scaleDown(fontSize_1st)); |
||||||
|
fontSizeComboBox.addItemListener(fontSizeItemListener); |
||||||
|
selectColorPane(fontColor_1st); |
||||||
|
} |
||||||
|
|
||||||
|
private void selectColorPane(Color color) { |
||||||
|
colorSelectPane.removeColorChangeListener(colorChangeAction); |
||||||
|
colorSelectPane.setColor(color); |
||||||
|
colorSelectPane.addColorChangeListener(colorChangeAction); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void caretUpdate(CaretEvent e) { |
||||||
|
StyledDocument doc = (StyledDocument) textPane.getDocument(); |
||||||
|
|
||||||
|
// 取得选择文本的起始位置和结束位置
|
||||||
|
int start = textPane.getSelectionStart(); |
||||||
|
int end = textPane.getSelectionEnd(); |
||||||
|
|
||||||
|
//如果没有选定字符
|
||||||
|
if (end == start) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
setSelectedCharStyle(start, end, doc); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
//设置当前光标位样式
|
||||||
|
private MouseListener setMouseCurrentStyle = new MouseAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
StyledDocument doc = (StyledDocument) textPane.getDocument(); |
||||||
|
|
||||||
|
// 取得选择文本的起始位置和结束位置
|
||||||
|
int start = textPane.getSelectionStart(); |
||||||
|
int end = textPane.getSelectionEnd(); |
||||||
|
|
||||||
|
if (start != end) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
setToLastCharStyle(end, doc); |
||||||
|
} |
||||||
|
|
||||||
|
//如果默认不选字符, 那么设置为最后一个字符的样式
|
||||||
|
private void setToLastCharStyle(int end, StyledDocument doc) { |
||||||
|
if (textPane.isUpdating()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//取前一个字符的样式
|
||||||
|
Element ele = doc.getCharacterElement(end - 1); |
||||||
|
AttributeSet attrs = ele.getAttributes(); |
||||||
|
populateToolBar(attrs); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* 从样式中更新工具栏上的按钮状态 |
||||||
|
* |
||||||
|
* @param attrs 样式 |
||||||
|
* @date 2015-1-5-下午5:12:33 |
||||||
|
*/ |
||||||
|
public void populateToolBar(AttributeSet attrs) { |
||||||
|
int size = scaleDown(StyleConstants.getFontSize(attrs)); |
||||||
|
fontNameComboBox.setSelectedItem(StyleConstants.getFontFamily(attrs)); |
||||||
|
fontSizeComboBox.setSelectedItem(size); |
||||||
|
|
||||||
|
bold.setSelected(StyleConstants.isBold(attrs)); |
||||||
|
italic.setSelected(StyleConstants.isItalic(attrs)); |
||||||
|
underline.setSelected(StyleConstants.isUnderline(attrs)); |
||||||
|
subPane.setSelected(StyleConstants.isSubscript(attrs)); |
||||||
|
superPane.setSelected(StyleConstants.isSuperscript(attrs)); |
||||||
|
Color foreGround = StyleConstants.getForeground(attrs); |
||||||
|
foreGround = foreGround == null ? Color.BLACK : foreGround; |
||||||
|
colorSelectPane.setColor(foreGround); |
||||||
|
colorSelectPane.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
//pt转为px =*4/3
|
||||||
|
private int scaleUp(int fontSize) { |
||||||
|
return scale(fontSize, true); |
||||||
|
} |
||||||
|
|
||||||
|
//px转pt = *3/4
|
||||||
|
private int scaleDown(int fontSize) { |
||||||
|
return scale(fontSize, false); |
||||||
|
} |
||||||
|
|
||||||
|
private int scale(int fontSize, boolean isUp) { |
||||||
|
double dpi96 = Constants.FR_PAINT_RESOLUTION; |
||||||
|
double dpi72 = Constants.DEFAULT_FONT_PAINT_RESOLUTION; |
||||||
|
double scale = isUp ? (dpi96 / dpi72) : (dpi72 / dpi96); |
||||||
|
|
||||||
|
return roundUp(fontSize * scale); |
||||||
|
} |
||||||
|
|
||||||
|
private DocumentListener inputListener = new DocumentListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeUpdate(DocumentEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void insertUpdate(DocumentEvent e) { |
||||||
|
//标志正在更新内容
|
||||||
|
textPane.startUpdating(); |
||||||
|
final MutableAttributeSet attr = updateStyleFromToolBar(); |
||||||
|
final int start = textPane.getSelectionStart(); |
||||||
|
int end = textPane.getSelectionEnd(); |
||||||
|
|
||||||
|
if (start != end) { |
||||||
|
textPane.finishUpdating(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//放到SwingWorker里, 是因为在documentListener里不能动态改变doc内容
|
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
changeContentStyle(start, attr); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
//根据Style来显示populate按钮
|
||||||
|
private void changeContentStyle(int start, MutableAttributeSet attr) { |
||||||
|
changeContentStyle(start, attr, 1); |
||||||
|
} |
||||||
|
|
||||||
|
private void changeContentStyle(int start, MutableAttributeSet attr, int contentLength) { |
||||||
|
// 将所选文本设置为新的样式,replace为false表示不覆盖原有的样式
|
||||||
|
StyledDocument doc = (StyledDocument) textPane.getDocument(); |
||||||
|
doc.setCharacterAttributes(start, contentLength, attr, false); |
||||||
|
textPane.finishUpdating(); |
||||||
|
} |
||||||
|
|
||||||
|
//将界面上的设置赋值给输入的字符
|
||||||
|
private MutableAttributeSet updateStyleFromToolBar() { |
||||||
|
final boolean isBold = bold.isSelected(); |
||||||
|
final boolean isItalic = italic.isSelected(); |
||||||
|
final boolean isSub = subPane.isSelected(); |
||||||
|
final boolean isSuper = superPane.isSelected(); |
||||||
|
final boolean isUnderLine = underline.isSelected(); |
||||||
|
final String fontName = (String) fontNameComboBox.getSelectedItem(); |
||||||
|
final int fontSize = scaleUp((Integer) fontSizeComboBox.getSelectedItem()); |
||||||
|
final Color foreGround = colorSelectPane.getColor() == null ? Color.BLACK : colorSelectPane.getColor(); |
||||||
|
|
||||||
|
MutableAttributeSet attr = new SimpleAttributeSet(); |
||||||
|
StyleConstants.setBold(attr, isBold); |
||||||
|
StyleConstants.setItalic(attr, isItalic); |
||||||
|
StyleConstants.setSubscript(attr, isSub); |
||||||
|
StyleConstants.setSuperscript(attr, isSuper); |
||||||
|
StyleConstants.setUnderline(attr, isUnderLine); |
||||||
|
StyleConstants.setForeground(attr, foreGround); |
||||||
|
StyleConstants.setFontFamily(attr, fontName); |
||||||
|
StyleConstants.setFontSize(attr, fontSize); |
||||||
|
|
||||||
|
return attr; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void changedUpdate(DocumentEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void setContentStyle(final int inputLen) { |
||||||
|
//缓存下Start, 下面要用来设置样式
|
||||||
|
final int _start = inputStart; |
||||||
|
final MutableAttributeSet attr = updateStyleFromToolBar(); |
||||||
|
|
||||||
|
//放到SwingWorker里, 是因为在documentListener里不能动态改变doc内容
|
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
//防止触发死循环change事件
|
||||||
|
startUpdating(); |
||||||
|
//Start-1 是因为中文输入法会用空格占1位
|
||||||
|
changeContentStyle(_start, attr, inputLen); |
||||||
|
resetFlag(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isUpdating() { |
||||||
|
return inputStart == UPDATING; |
||||||
|
} |
||||||
|
|
||||||
|
private void startUpdating() { |
||||||
|
inputStart = UPDATING; |
||||||
|
} |
||||||
|
|
||||||
|
//初始标记状态, 用于记录中文输入法多个字符同时输入的问题
|
||||||
|
private void initFlag(StyledDocument doc) { |
||||||
|
if (inputStart != NOT_INITIALIZED) { |
||||||
|
return; |
||||||
|
} |
||||||
|
inputStart = textPane.getSelectionStart() - 1; |
||||||
|
} |
||||||
|
|
||||||
|
//重置标记状态
|
||||||
|
private void resetFlag() { |
||||||
|
inputStart = NOT_INITIALIZED; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
package com.fanruan.api.design.work.component; |
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.UIComboBox; |
||||||
|
import com.fanruan.api.macro.LineConstants; |
||||||
|
import com.fanruan.api.util.GraphKit; |
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.ScreenResolution; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBoxRenderer; |
||||||
|
import com.fr.general.FRFont; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.geom.GeneralPath; |
||||||
|
import java.awt.geom.Point2D; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 用于选择线条类型的下拉框 |
||||||
|
*/ |
||||||
|
public class LineComboBox extends UIComboBox<Integer> { |
||||||
|
|
||||||
|
public LineComboBox(int[] lineStyleArray) { |
||||||
|
Integer[] lineStyleIntegerArray = new Integer[lineStyleArray.length]; |
||||||
|
|
||||||
|
for (int i = 0; i < lineStyleArray.length; i++) { |
||||||
|
lineStyleIntegerArray[i] = lineStyleArray[i]; |
||||||
|
} |
||||||
|
|
||||||
|
this.setModel(new DefaultComboBoxModel(lineStyleIntegerArray)); |
||||||
|
|
||||||
|
this.setRenderer(new LineComboBox.LineCellRenderer()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取选择的线条类型 |
||||||
|
* |
||||||
|
* @return 用于表示线条类型的整数 |
||||||
|
*/ |
||||||
|
public int getSelectedLineStyle() { |
||||||
|
int style = (Integer) getSelectedItem(); |
||||||
|
return (style < 0) ? LineConstants.LINE_NONE : style; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置选中的线条类型 |
||||||
|
* |
||||||
|
* @param style 用于表示线条类型的整数 |
||||||
|
*/ |
||||||
|
public void setSelectedLineStyle(int style) { |
||||||
|
this.setSelectedItem(style); |
||||||
|
} |
||||||
|
|
||||||
|
private static class LineCellRenderer extends UIComboBoxRenderer { |
||||||
|
|
||||||
|
private int style = LineConstants.LINE_NONE; |
||||||
|
|
||||||
|
public Component getListCellRendererComponent( |
||||||
|
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||||
|
JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||||
|
this.style = (Integer) value; |
||||||
|
comp.setText(null); |
||||||
|
return comp; |
||||||
|
} |
||||||
|
|
||||||
|
public void paint(Graphics g) { |
||||||
|
super.paint(g); |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
|
||||||
|
Dimension d = getSize(); |
||||||
|
g2d.setColor(getForeground()); |
||||||
|
|
||||||
|
FRFont font = FRContext.getDefaultValues().getFRFont(); |
||||||
|
int resolution = ScreenResolution.getScreenResolution(); |
||||||
|
Font rfont = font.applyResolutionNP(resolution); |
||||||
|
g2d.setFont(rfont); |
||||||
|
FontMetrics fm = GraphKit.getFontMetrics(rfont); |
||||||
|
if (style == LineConstants.LINE_NONE) { |
||||||
|
GraphKit.drawString(g2d, DesignKit.i18nText("Fine-Design_Report_None"), 4, (d.height - fm.getHeight()) / 2D + fm.getAscent()); |
||||||
|
} else { |
||||||
|
GraphKit.drawLine(g2d, 4, d.height / 2D, d.width - 8D, d.height / 2D, style); |
||||||
|
} |
||||||
|
|
||||||
|
if (isShowAxisWithLineStyle()) { // 带有坐标轴箭头的样式.
|
||||||
|
drawArrow(g2d, new Point2D.Double(4, d.height / 2D), new Point2D.Double(d.width - 8D, d.height / 2D)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void drawArrow(Graphics2D g2d, Point2D p0, Point2D p1) { |
||||||
|
Point2D s = new Point2D.Double(p1.getX() - p0.getX(), p1.getY() - p0.getY()); |
||||||
|
Point2D t = new Point2D.Double(); |
||||||
|
double d1 = p0.distance(p1); |
||||||
|
//d2-d5设定箭头的大小,p1-p2为坐标轴的延长线,p2-p5-p3-p6为箭头4个点的具体位置
|
||||||
|
double d2 = 9; |
||||||
|
double d3 = 15; |
||||||
|
double d4 = 7; |
||||||
|
double d5 = 3; |
||||||
|
t.setLocation(d2 * s.getX() / d1, d2 * s.getY() / d1); |
||||||
|
Point2D p2 = new Point2D.Double(p1.getX() + t.getX(), p1.getY() + t.getY()); |
||||||
|
t.setLocation(d3 * s.getX() / d1, d3 * s.getY() / d1); |
||||||
|
Point2D p3 = new Point2D.Double(p1.getX() + t.getX(), p1.getY() + t.getY()); |
||||||
|
t.setLocation(d4 * s.getX() / d1, d4 * s.getY() / d1); |
||||||
|
Point2D p4 = new Point2D.Double(p1.getX() + t.getX(), p1.getY() + t.getY()); |
||||||
|
Point2D p5 = new Point2D.Double(p4.getX() + s.getY() / d1 * d5, p4.getY() - s.getX() / d1 * d5); |
||||||
|
Point2D p6 = new Point2D.Double(p4.getX() - s.getY() / d1 * d5, p4.getY() + s.getX() / d1 * d5); |
||||||
|
|
||||||
|
GeneralPath arrow = new GeneralPath(); |
||||||
|
arrow.moveTo((float) p2.getX() - 10, (float) p2.getY()); |
||||||
|
arrow.lineTo((float) p5.getX() - 10, (float) p5.getY()); |
||||||
|
arrow.lineTo((float) p3.getX() - 10, (float) p3.getY()); |
||||||
|
arrow.lineTo((float) p6.getX() - 10, (float) p6.getY()); |
||||||
|
arrow.closePath(); |
||||||
|
|
||||||
|
g2d.draw(arrow); |
||||||
|
g2d.fill(arrow); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isShowAxisWithLineStyle() { |
||||||
|
return style == LineConstants.LINE_CHART_MED_ARROW |
||||||
|
|| style == LineConstants.LINE_CHART_THICK_ARROW || style == LineConstants.LINE_CHART_THIN_ARROW; |
||||||
|
} |
||||||
|
|
||||||
|
public Dimension getPreferredSize() { |
||||||
|
return new Dimension(60, 16); |
||||||
|
} |
||||||
|
|
||||||
|
public Dimension getMinimumSize() { |
||||||
|
return getPreferredSize(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fanruan.api.macro; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 用于表示线条样式 |
||||||
|
*/ |
||||||
|
public class LineConstants { |
||||||
|
|
||||||
|
public static final int LINE_NONE = 0; |
||||||
|
public static final int LINE_THIN = 1; |
||||||
|
public static final int LINE_MEDIUM = 2; |
||||||
|
public static final int LINE_DASH = 3; |
||||||
|
public static final int LINE_HAIR = 4; |
||||||
|
public static final int LINE_THICK = 5; |
||||||
|
public static final int LINE_DOUBLE = 6; |
||||||
|
public static final int LINE_DOT = 7; |
||||||
|
public static final int LINE_MEDIUM_DASH = 8; |
||||||
|
public static final int LINE_DASH_DOT = 9; |
||||||
|
public static final int LINE_MEDIUM_DASH_DOT = 10; |
||||||
|
public static final int LINE_DASH_DOT_DOT = 11; |
||||||
|
public static final int LINE_MEDIUM_DASH_DOT_DOT = 12; |
||||||
|
public static final int LINE_SLANTED_DASH_DOT = 13; |
||||||
|
public static final int LINE_HAIR2 = 14; |
||||||
|
public static final int LINE_DOUBLE_DOT = 15; |
||||||
|
public static final int LINE_LARGE = 16; |
||||||
|
public static final int LINE_SLIM = 17; |
||||||
|
public static final int LINE_CHART_THIN_ARROW = 21; |
||||||
|
public static final int LINE_CHART_MED_ARROW = 22; |
||||||
|
public static final int LINE_CHART_THICK_ARROW = 23; |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.fanruan.api.report.form.category; |
||||||
|
|
||||||
|
import com.fanruan.api.report.form.BaseWidget; |
||||||
|
import com.fr.form.ui.LayoutBorderStyle; |
||||||
|
import com.fr.form.ui.PaddingMargin; |
||||||
|
import com.fr.form.ui.RichStyleWidgetProvider; |
||||||
|
import com.fr.general.Background; |
||||||
|
import com.fr.general.act.BorderPacker; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 带边框和样式设置的控件基类 |
||||||
|
*/ |
||||||
|
public abstract class BaseBorderStyleWidget extends BaseWidget implements RichStyleWidgetProvider { |
||||||
|
|
||||||
|
private BorderPacker borderStyle = new LayoutBorderStyle(); |
||||||
|
private Background background; |
||||||
|
private PaddingMargin margin = new PaddingMargin(); |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package com.fanruan.api.util; |
||||||
|
|
||||||
|
import com.fr.stable.GraphDrawHelper; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019/10/25 |
||||||
|
* 图形绘制相关的工具类 |
||||||
|
*/ |
||||||
|
public class GraphKit { |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取字体规格属性 |
||||||
|
* |
||||||
|
* @param font 字体 |
||||||
|
* @return 字体的规格属性 |
||||||
|
*/ |
||||||
|
public static FontMetrics getFontMetrics(Font font) { |
||||||
|
return GraphDrawHelper.getFontMetrics(font); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取字体规格属性 |
||||||
|
* |
||||||
|
* @param font 字体 |
||||||
|
* @param g2d 图形绘制上下文 |
||||||
|
* @return 字体的规格属性 |
||||||
|
*/ |
||||||
|
public static FontMetrics getFontMetrics(Font font, Graphics2D g2d) { |
||||||
|
return GraphDrawHelper.getFontMetrics(font, g2d); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 绘制文本 |
||||||
|
* |
||||||
|
* @param g 图形绘制上下文 |
||||||
|
* @param str 待绘制的文本 |
||||||
|
* @param x 横坐标 |
||||||
|
* @param y 纵坐标 |
||||||
|
*/ |
||||||
|
public static void drawString(Graphics g, String str, double x, double y) { |
||||||
|
GraphDrawHelper.drawString(g, str, x, y); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 绘制线段 |
||||||
|
* |
||||||
|
* @param g 图形绘制上下文 |
||||||
|
* @param x1 起点横坐标 |
||||||
|
* @param y1 起点纵坐标 |
||||||
|
* @param x2 终点横坐标 |
||||||
|
* @param y2 终点纵坐标 |
||||||
|
*/ |
||||||
|
public static void drawLine(Graphics g, double x1, double y1, double x2, double y2) { |
||||||
|
GraphDrawHelper.drawLine(g, x1, y1, x2, y2); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 绘制线段 |
||||||
|
* |
||||||
|
* @param g 图形绘制上下文 |
||||||
|
* @param x1 起点横坐标 |
||||||
|
* @param y1 起点纵坐标 |
||||||
|
* @param x2 终点横坐标 |
||||||
|
* @param y2 终点纵坐标 |
||||||
|
* @param lineStyle 线条样式 |
||||||
|
* @see com.fanruan.api.macro.LineConstants |
||||||
|
*/ |
||||||
|
public static void drawLine(Graphics g, |
||||||
|
double x1, double y1, double x2, double y2, int lineStyle) { |
||||||
|
GraphDrawHelper.drawLine(g, x1, y1, x2, y2, lineStyle); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 绘制矩形 |
||||||
|
* |
||||||
|
* @param g 图形绘制上下文 |
||||||
|
* @param x 起点横坐标 |
||||||
|
* @param y 起点纵坐标 |
||||||
|
* @param width 矩形宽度 |
||||||
|
* @param height 矩形高度 |
||||||
|
*/ |
||||||
|
public static void drawRect(Graphics g, double x, double y, double width, double height) { |
||||||
|
GraphDrawHelper.drawRect(g, x, y, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 绘制矩形 |
||||||
|
* |
||||||
|
* @param g 图形绘制上下文 |
||||||
|
* @param x 起点横坐标 |
||||||
|
* @param y 起点纵坐标 |
||||||
|
* @param width 矩形宽度 |
||||||
|
* @param height 矩形高度 |
||||||
|
* @param lineStyle 线条样式 |
||||||
|
* @see com.fanruan.api.macro.LineConstants |
||||||
|
*/ |
||||||
|
public static void drawRect(Graphics g, double x, double y, double width, double height, int lineStyle) { |
||||||
|
GraphDrawHelper.drawRect(g, x, y, width, height, lineStyle); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue