Browse Source
* 'feature/x' of ssh://code.fineres.com:7999/~fanglei/design: REPORT-62440 表头排序内置 REPORT-64445 新老自适应配置面板修改 REPORT-58833 js编辑器 REPORT-58833 js编辑器 REPORT-65474 设计器-水印,平台改变水印开关,模板水印变成了模板单独设置 1.新建水印默认不是模板水印,当新建模板水印的时候,进行配置即可。 REPORT-65449 在组件包详情页拖拽组件并修改后,再点到在线组件,标签和内容显示不一致 REPORT-64811 10.0设计器下载的组件文件无法解压缩 REPORT-65290 设计器-水印,平台改变水印开关,模板水印变成了模板单独设置 1.修改水印的isvalid REPORT-65369 设计器内对macOS12的处理-按钮图标设置-在点击 选择图片时回到了父弹窗界面,没有实时显示出来,而需要再次单机设计器界面 REPORT-65381 linux_arm设计器-点击菜单栏文件-选项,出现弹窗后再点击 确定按钮,弹窗不消失,无任何反应 REPORT-65371 【主题边框】附件截图,滚动条显示有问题 REPORT-65343 FR11-新自适应开发者调试-新建模板,直接点击开发者调试进行模板保存和预览,此时虽然弹出保存路径弹窗,但对话框弹窗还没有点击的时候模板web就打开了且报错,因为模板没保存成功;设计器端可以看到模板被关闭了 REPORT-65365 【主题边框】多次切换单元格样式后切换自定义,边框线有问题 REPORT-65358 【主题边框】单元格样式双线显示有问题 REPORT-65307 二轮冒烟测试-远程模板锁定优化-国际化问题-弹窗显示不全 删除无用接口 REPORT-64009 设计器内对macOS12的处理 fix import REPORT-64009 设计器内对macOS12的处理 fix门槛用例的bug REPORT-65107 决策报表-11frm,无法向tab组件上方拖入放置组件,10上操作还比较顺畅 # Conflicts: # designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.javafeature/x
方磊
3 years ago
85 changed files with 7127 additions and 3284 deletions
@ -0,0 +1,5 @@ |
|||||||
|
package com.fr.design.gui.autocomplete; |
||||||
|
|
||||||
|
public interface AutoCompleteExtraRefreshComponent { |
||||||
|
void refresh(String replacementText); |
||||||
|
} |
@ -0,0 +1,982 @@ |
|||||||
|
package com.fr.design.gui.autocomplete; |
||||||
|
|
||||||
|
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.PopupWindowDecorator; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.ComponentOrientation; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.Toolkit; |
||||||
|
import java.awt.Window; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.util.List; |
||||||
|
import javax.swing.AbstractAction; |
||||||
|
import javax.swing.Action; |
||||||
|
import javax.swing.ActionMap; |
||||||
|
import javax.swing.InputMap; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JScrollPane; |
||||||
|
import javax.swing.JWindow; |
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import javax.swing.event.CaretEvent; |
||||||
|
import javax.swing.event.CaretListener; |
||||||
|
import javax.swing.event.ListSelectionEvent; |
||||||
|
import javax.swing.event.ListSelectionListener; |
||||||
|
import javax.swing.plaf.ListUI; |
||||||
|
import javax.swing.text.Caret; |
||||||
|
import javax.swing.text.JTextComponent; |
||||||
|
|
||||||
|
public abstract class AutoCompleteWithExtraRefreshPopupWindow extends JWindow implements CaretListener, |
||||||
|
ListSelectionListener, MouseListener { |
||||||
|
private final static int DIS = 5; |
||||||
|
/** |
||||||
|
* The parent AutoCompletion instance. |
||||||
|
*/ |
||||||
|
private AutoCompletion ac; |
||||||
|
|
||||||
|
/** |
||||||
|
* The list of completion choices. |
||||||
|
*/ |
||||||
|
private JList list; |
||||||
|
|
||||||
|
/** |
||||||
|
* The contents of {@link #list()}. |
||||||
|
*/ |
||||||
|
private CompletionListModel model; |
||||||
|
|
||||||
|
/** |
||||||
|
* A hack to work around the fact that we clear our completion model (and |
||||||
|
* our selection) when hiding the completion window. This allows us to |
||||||
|
* still know what the user selected after the popup is hidden. |
||||||
|
*/ |
||||||
|
private Completion lastSelection; |
||||||
|
|
||||||
|
/** |
||||||
|
* Optional popup window containing a description of the currently |
||||||
|
* selected completion. |
||||||
|
*/ |
||||||
|
private AutoCompleteDescWindow descWindow; |
||||||
|
|
||||||
|
/** |
||||||
|
* The preferred size of the optional description window. This field |
||||||
|
* only exists because the user may (and usually will) set the size of |
||||||
|
* the description window before it exists (it must be parented to a |
||||||
|
* Window). |
||||||
|
*/ |
||||||
|
private Dimension preferredDescWindowSize; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Whether the completion window and the optional description window |
||||||
|
* should be displayed above the current caret position (as opposed to |
||||||
|
* underneath it, which is preferred unless there is not enough space). |
||||||
|
*/ |
||||||
|
private boolean aboveCaret; |
||||||
|
|
||||||
|
private int lastLine; |
||||||
|
|
||||||
|
private KeyActionPair escapeKap; |
||||||
|
private KeyActionPair upKap; |
||||||
|
private KeyActionPair downKap; |
||||||
|
private KeyActionPair leftKap; |
||||||
|
private KeyActionPair rightKap; |
||||||
|
private KeyActionPair enterKap; |
||||||
|
private KeyActionPair tabKap; |
||||||
|
private KeyActionPair homeKap; |
||||||
|
private KeyActionPair endKap; |
||||||
|
private KeyActionPair pageUpKap; |
||||||
|
private KeyActionPair pageDownKap; |
||||||
|
private KeyActionPair ctrlCKap; |
||||||
|
|
||||||
|
private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight, |
||||||
|
oldEnter, oldTab, oldHome, oldEnd, oldPageUp, oldPageDown, |
||||||
|
oldCtrlC; |
||||||
|
|
||||||
|
/** |
||||||
|
* The space between the caret and the completion popup. |
||||||
|
*/ |
||||||
|
private static final int VERTICAL_SPACE = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* The class name of the Substance List UI. |
||||||
|
*/ |
||||||
|
private static final String SUBSTANCE_LIST_UI = |
||||||
|
"org.pushingpixels.substance.internal.ui.SubstanceListUI"; |
||||||
|
|
||||||
|
|
||||||
|
protected AutoCompleteExtraRefreshComponent component; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* |
||||||
|
* @param parent The parent window (hosting the text component). |
||||||
|
* @param ac The auto-completion instance. |
||||||
|
*/ |
||||||
|
public AutoCompleteWithExtraRefreshPopupWindow(Window parent, final AutoCompletion ac) { |
||||||
|
|
||||||
|
super(parent); |
||||||
|
ComponentOrientation o = ac.getTextComponentOrientation(); |
||||||
|
|
||||||
|
this.ac = ac; |
||||||
|
model = new CompletionListModel(); |
||||||
|
list = new PopupList(model); |
||||||
|
|
||||||
|
list.setCellRenderer(new DelegatingCellRenderer()); |
||||||
|
list.addListSelectionListener(this); |
||||||
|
list.addMouseListener(this); |
||||||
|
|
||||||
|
JPanel contentPane = new JPanel(new BorderLayout()); |
||||||
|
JScrollPane sp = new JScrollPane(list, |
||||||
|
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, |
||||||
|
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); |
||||||
|
|
||||||
|
// In 1.4, JScrollPane.setCorner() has a bug where it won't accept
|
||||||
|
// JScrollPane.LOWER_TRAILING_CORNER, even though that constant is
|
||||||
|
// defined. So we have to put the logic added in 1.5 to handle it
|
||||||
|
// here.
|
||||||
|
JPanel corner = new SizeGrip(); |
||||||
|
//sp.setCorner(JScrollPane.LOWER_TRAILING_CORNER, corner);
|
||||||
|
boolean isLeftToRight = o.isLeftToRight(); |
||||||
|
String str = isLeftToRight ? JScrollPane.LOWER_RIGHT_CORNER : |
||||||
|
JScrollPane.LOWER_LEFT_CORNER; |
||||||
|
sp.setCorner(str, corner); |
||||||
|
|
||||||
|
contentPane.add(sp); |
||||||
|
setContentPane(contentPane); |
||||||
|
applyComponentOrientation(o); |
||||||
|
|
||||||
|
// Give apps a chance to decorate us with drop shadows, etc.
|
||||||
|
if (Util.getShouldAllowDecoratingMainAutoCompleteWindows()) { |
||||||
|
PopupWindowDecorator decorator = PopupWindowDecorator.get(); |
||||||
|
if (decorator != null) { |
||||||
|
decorator.decorate(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pack(); |
||||||
|
|
||||||
|
setFocusableWindowState(false); |
||||||
|
|
||||||
|
lastLine = -1; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void caretUpdate(CaretEvent e) { |
||||||
|
if (isVisible()) { // Should always be true
|
||||||
|
int line = ac.getLineOfCaret(); |
||||||
|
if (line != lastLine) { |
||||||
|
lastLine = -1; |
||||||
|
setVisible(false); |
||||||
|
} else { |
||||||
|
doAutocomplete(); |
||||||
|
} |
||||||
|
} else if (AutoCompletion.isDebug()) { |
||||||
|
Thread.dumpStack(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Creates the description window. |
||||||
|
* |
||||||
|
* @return The description window. |
||||||
|
*/ |
||||||
|
private AutoCompleteDescWindow createDescriptionWindow() { |
||||||
|
AutoCompleteDescWindow dw = new AutoCompleteDescWindow(this, ac); |
||||||
|
dw.applyComponentOrientation(ac.getTextComponentOrientation()); |
||||||
|
Dimension size = preferredDescWindowSize; |
||||||
|
if (size == null) { |
||||||
|
size = getSize(); |
||||||
|
} |
||||||
|
dw.setSize(size); |
||||||
|
return dw; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Creates the mappings from keys to Actions we'll be putting into the |
||||||
|
* text component's ActionMap and InputMap. |
||||||
|
*/ |
||||||
|
private void createKeyActionPairs() { |
||||||
|
|
||||||
|
// Actions we'll install.
|
||||||
|
EnterAction enterAction = new EnterAction(); |
||||||
|
escapeKap = new KeyActionPair("Escape", new EscapeAction()); |
||||||
|
upKap = new KeyActionPair("Up", new UpAction()); |
||||||
|
downKap = new KeyActionPair("Down", new DownAction()); |
||||||
|
leftKap = new KeyActionPair("Left", new LeftAction()); |
||||||
|
rightKap = new KeyActionPair("Right", new RightAction()); |
||||||
|
enterKap = new KeyActionPair("Enter", enterAction); |
||||||
|
tabKap = new KeyActionPair("Tab", enterAction); |
||||||
|
homeKap = new KeyActionPair("Home", new HomeAction()); |
||||||
|
endKap = new KeyActionPair("End", new EndAction()); |
||||||
|
pageUpKap = new KeyActionPair("PageUp", new PageUpAction()); |
||||||
|
pageDownKap = new KeyActionPair("PageDown", new PageDownAction()); |
||||||
|
ctrlCKap = new KeyActionPair("CtrlC", new CopyAction()); |
||||||
|
|
||||||
|
// Buffers for the actions we replace.
|
||||||
|
oldEscape = new KeyActionPair(); |
||||||
|
oldUp = new KeyActionPair(); |
||||||
|
oldDown = new KeyActionPair(); |
||||||
|
oldLeft = new KeyActionPair(); |
||||||
|
oldRight = new KeyActionPair(); |
||||||
|
oldEnter = new KeyActionPair(); |
||||||
|
oldTab = new KeyActionPair(); |
||||||
|
oldHome = new KeyActionPair(); |
||||||
|
oldEnd = new KeyActionPair(); |
||||||
|
oldPageUp = new KeyActionPair(); |
||||||
|
oldPageDown = new KeyActionPair(); |
||||||
|
oldCtrlC = new KeyActionPair(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void doAutocomplete() { |
||||||
|
lastLine = ac.refreshPopupWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the copy keystroke to use for this platform. |
||||||
|
* |
||||||
|
* @return The copy keystroke. |
||||||
|
*/ |
||||||
|
private static final KeyStroke getCopyKeyStroke() { |
||||||
|
int key = KeyEvent.VK_C; |
||||||
|
int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); |
||||||
|
return KeyStroke.getKeyStroke(key, mask); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the default list cell renderer used when a completion provider |
||||||
|
* does not supply its own. |
||||||
|
* |
||||||
|
* @return The default list cell renderer. |
||||||
|
* @see #setListCellRenderer(ListCellRenderer) |
||||||
|
*/ |
||||||
|
public ListCellRenderer getListCellRenderer() { |
||||||
|
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list. |
||||||
|
getCellRenderer(); |
||||||
|
return dcr.getFallbackCellRenderer(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the selected value, or <code>null</code> if nothing is selected. |
||||||
|
* |
||||||
|
* @return The selected value. |
||||||
|
*/ |
||||||
|
public Completion getSelection() { |
||||||
|
return isShowing() ? (Completion) list.getSelectedValue() : lastSelection; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Inserts the currently selected completion. |
||||||
|
* |
||||||
|
* @see #getSelection() |
||||||
|
*/ |
||||||
|
private void insertSelectedCompletion() { |
||||||
|
Completion comp = getSelection(); |
||||||
|
ac.insertCompletion(comp); |
||||||
|
} |
||||||
|
|
||||||
|
public void installComp(AutoCompleteExtraRefreshComponent component){ |
||||||
|
this.component = component; |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshInstallComp() { |
||||||
|
component.refresh(getSelection().getReplacementText()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Registers keyboard actions to listen for in the text component and |
||||||
|
* intercept. |
||||||
|
* |
||||||
|
* @see #uninstallKeyBindings() |
||||||
|
*/ |
||||||
|
private void installKeyBindings() { |
||||||
|
|
||||||
|
if (AutoCompletion.isDebug()) { |
||||||
|
FineLoggerFactory.getLogger().debug("PopupWindow: Installing keybindings"); |
||||||
|
} |
||||||
|
|
||||||
|
if (escapeKap == null) { // Lazily create actions.
|
||||||
|
createKeyActionPairs(); |
||||||
|
} |
||||||
|
|
||||||
|
JTextComponent comp = ac.getTextComponent(); |
||||||
|
InputMap im = comp.getInputMap(); |
||||||
|
ActionMap am = comp.getActionMap(); |
||||||
|
|
||||||
|
replaceAction(im, am, KeyEvent.VK_ESCAPE, escapeKap, oldEscape); |
||||||
|
if (AutoCompletion.isDebug() && oldEscape.action == escapeKap.action) { |
||||||
|
Thread.dumpStack(); |
||||||
|
} |
||||||
|
replaceAction(im, am, KeyEvent.VK_UP, upKap, oldUp); |
||||||
|
replaceAction(im, am, KeyEvent.VK_LEFT, leftKap, oldLeft); |
||||||
|
replaceAction(im, am, KeyEvent.VK_DOWN, downKap, oldDown); |
||||||
|
replaceAction(im, am, KeyEvent.VK_RIGHT, rightKap, oldRight); |
||||||
|
replaceAction(im, am, KeyEvent.VK_ENTER, enterKap, oldEnter); |
||||||
|
replaceAction(im, am, KeyEvent.VK_TAB, tabKap, oldTab); |
||||||
|
replaceAction(im, am, KeyEvent.VK_HOME, homeKap, oldHome); |
||||||
|
replaceAction(im, am, KeyEvent.VK_END, endKap, oldEnd); |
||||||
|
replaceAction(im, am, KeyEvent.VK_PAGE_UP, pageUpKap, oldPageUp); |
||||||
|
replaceAction(im, am, KeyEvent.VK_PAGE_DOWN, pageDownKap, oldPageDown); |
||||||
|
|
||||||
|
// Make Ctrl+C copy from description window. This isn't done
|
||||||
|
// automagically because the desc. window is not focusable, and copying
|
||||||
|
// from text components can only be done from focused components.
|
||||||
|
KeyStroke ks = getCopyKeyStroke(); |
||||||
|
oldCtrlC.key = im.get(ks); |
||||||
|
im.put(ks, ctrlCKap.key); |
||||||
|
oldCtrlC.action = am.get(ctrlCKap.key); |
||||||
|
am.put(ctrlCKap.key, ctrlCKap.action); |
||||||
|
|
||||||
|
comp.addCaretListener(this); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (e.getClickCount() == 2 && e.getButton() == 1) { |
||||||
|
insertSelectedCompletion(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
refreshInstallComp(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void mouseReleased(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Positions the description window relative to the completion choices |
||||||
|
* window. We assume there is room on one side of the other for this |
||||||
|
* entire window to fit. |
||||||
|
*/ |
||||||
|
private void positionDescWindow() { |
||||||
|
|
||||||
|
boolean showDescWindow = descWindow != null && ac.isShowDescWindow(); |
||||||
|
if (!showDescWindow) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Don't use getLocationOnScreen() as this throws an exception if
|
||||||
|
// window isn't visible yet, but getLocation() doesn't, and is in
|
||||||
|
// screen coordinates!
|
||||||
|
Point p = getLocation(); |
||||||
|
Rectangle screenBounds = Util.getScreenBoundsForPoint(p.x, p.y); |
||||||
|
//Dimension screenSize = getToolkit().getScreenSize();
|
||||||
|
//int totalH = Math.max(getHeight(), descWindow.getHeight());
|
||||||
|
|
||||||
|
// Try to position to the right first (LTR)
|
||||||
|
int x; |
||||||
|
if (ac.getTextComponentOrientation().isLeftToRight()) { |
||||||
|
x = getX() + getWidth() + DIS; |
||||||
|
if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit
|
||||||
|
x = getX() - DIS - descWindow.getWidth(); |
||||||
|
} |
||||||
|
} else { // RTL
|
||||||
|
x = getX() - DIS - descWindow.getWidth(); |
||||||
|
if (x < screenBounds.x) { // Doesn't fit
|
||||||
|
x = getX() + getWidth() + DIS; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int y = getY(); |
||||||
|
if (aboveCaret) { |
||||||
|
y = y + getHeight() - descWindow.getHeight(); |
||||||
|
} |
||||||
|
|
||||||
|
if (x != descWindow.getX() || y != descWindow.getY()) { |
||||||
|
descWindow.setLocation(x, y); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* "Puts back" the original key/Action pair for a keystroke. This is used |
||||||
|
* when this popup is hidden. |
||||||
|
* |
||||||
|
* @param im The input map. |
||||||
|
* @param am The action map. |
||||||
|
* @param key The keystroke whose key/Action pair to change. |
||||||
|
* @param kap The (original) key/Action pair. |
||||||
|
* @see #replaceAction(InputMap, ActionMap, int, KeyActionPair, KeyActionPair) |
||||||
|
*/ |
||||||
|
private void putBackAction(InputMap im, ActionMap am, int key, |
||||||
|
KeyActionPair kap) { |
||||||
|
KeyStroke ks = KeyStroke.getKeyStroke(key, 0); |
||||||
|
am.put(im.get(ks), kap.action); // Original action for the "new" key
|
||||||
|
im.put(ks, kap.key); // Original key for the keystroke.
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces a key/Action pair in an InputMap and ActionMap with a new |
||||||
|
* pair. |
||||||
|
* |
||||||
|
* @param im The input map. |
||||||
|
* @param am The action map. |
||||||
|
* @param key The keystroke whose information to replace. |
||||||
|
* @param kap The new key/Action pair for <code>key</code>. |
||||||
|
* @param old A buffer in which to place the old key/Action pair. |
||||||
|
* @see #putBackAction(InputMap, ActionMap, int, KeyActionPair) |
||||||
|
*/ |
||||||
|
private void replaceAction(InputMap im, ActionMap am, int key, |
||||||
|
KeyActionPair kap, KeyActionPair old) { |
||||||
|
KeyStroke ks = KeyStroke.getKeyStroke(key, 0); |
||||||
|
old.key = im.get(ks); |
||||||
|
im.put(ks, kap.key); |
||||||
|
old.action = am.get(kap.key); |
||||||
|
am.put(kap.key, kap.action); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the first item in the completion list. |
||||||
|
* |
||||||
|
* @see #selectLastItem() |
||||||
|
*/ |
||||||
|
private void selectFirstItem() { |
||||||
|
if (model.getSize() > 0) { |
||||||
|
list.setSelectedIndex(0); |
||||||
|
list.ensureIndexIsVisible(0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the last item in the completion list. |
||||||
|
* |
||||||
|
* @see #selectFirstItem() |
||||||
|
*/ |
||||||
|
private void selectLastItem() { |
||||||
|
int index = model.getSize() - 1; |
||||||
|
if (index > -1) { |
||||||
|
list.setSelectedIndex(index); |
||||||
|
list.ensureIndexIsVisible(index); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the next item in the completion list. |
||||||
|
* |
||||||
|
* @see #selectPreviousItem() |
||||||
|
*/ |
||||||
|
private void selectNextItem() { |
||||||
|
int index = list.getSelectedIndex(); |
||||||
|
if (index > -1) { |
||||||
|
index = (index + 1) % model.getSize(); |
||||||
|
list.setSelectedIndex(index); |
||||||
|
list.ensureIndexIsVisible(index); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the completion item one "page down" from the currently selected |
||||||
|
* one. |
||||||
|
* |
||||||
|
* @see #selectPageUpItem() |
||||||
|
*/ |
||||||
|
private void selectPageDownItem() { |
||||||
|
int visibleRowCount = list.getVisibleRowCount(); |
||||||
|
int i = Math.min(list.getModel().getSize() - 1, |
||||||
|
list.getSelectedIndex() + visibleRowCount); |
||||||
|
list.setSelectedIndex(i); |
||||||
|
list.ensureIndexIsVisible(i); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the completion item one "page up" from the currently selected |
||||||
|
* one. |
||||||
|
* |
||||||
|
* @see #selectPageDownItem() |
||||||
|
*/ |
||||||
|
private void selectPageUpItem() { |
||||||
|
int visibleRowCount = list.getVisibleRowCount(); |
||||||
|
int i = Math.max(0, list.getSelectedIndex() - visibleRowCount); |
||||||
|
list.setSelectedIndex(i); |
||||||
|
list.ensureIndexIsVisible(i); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Selects the previous item in the completion list. |
||||||
|
* |
||||||
|
* @see #selectNextItem() |
||||||
|
*/ |
||||||
|
private void selectPreviousItem() { |
||||||
|
int index = list.getSelectedIndex(); |
||||||
|
switch (index) { |
||||||
|
case 0: |
||||||
|
index = list.getModel().getSize() - 1; |
||||||
|
break; |
||||||
|
case -1: // Check for an empty list (would be an error)
|
||||||
|
index = list.getModel().getSize() - 1; |
||||||
|
if (index == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
index = index - 1; |
||||||
|
break; |
||||||
|
} |
||||||
|
list.setSelectedIndex(index); |
||||||
|
list.ensureIndexIsVisible(index); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the completions to display in the choices list. The first |
||||||
|
* completion is selected. |
||||||
|
* |
||||||
|
* @param completions The completions to display. |
||||||
|
*/ |
||||||
|
public void setCompletions(List<Completion> completions) { |
||||||
|
model.setContents(completions); |
||||||
|
selectFirstItem(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the size of the description window. |
||||||
|
* |
||||||
|
* @param size The new size. This cannot be <code>null</code>. |
||||||
|
*/ |
||||||
|
public void setDescriptionWindowSize(Dimension size) { |
||||||
|
if (descWindow != null) { |
||||||
|
descWindow.setSize(size); |
||||||
|
} else { |
||||||
|
preferredDescWindowSize = size; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the default list cell renderer to use when a completion provider |
||||||
|
* does not supply its own. |
||||||
|
* |
||||||
|
* @param renderer The renderer to use. If this is <code>null</code>, |
||||||
|
* a default renderer is used. |
||||||
|
* @see #getListCellRenderer() |
||||||
|
*/ |
||||||
|
public void setListCellRenderer(ListCellRenderer renderer) { |
||||||
|
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list. |
||||||
|
getCellRenderer(); |
||||||
|
dcr.setFallbackCellRenderer(renderer); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the location of this window to be "good" relative to the specified |
||||||
|
* rectangle. That rectangle should be the location of the text |
||||||
|
* component's caret, in screen coordinates. |
||||||
|
* |
||||||
|
* @param r The text component's caret position, in screen coordinates. |
||||||
|
*/ |
||||||
|
public void setLocationRelativeTo(Rectangle r) { |
||||||
|
|
||||||
|
// Multi-monitor support - make sure the completion window (and
|
||||||
|
// description window, if applicable) both fit in the same window in
|
||||||
|
// a multi-monitor environment. To do this, we decide which monitor
|
||||||
|
// the rectangle "r" is in, and use that one (just pick top-left corner
|
||||||
|
// as the defining point).
|
||||||
|
Rectangle screenBounds = Util.getScreenBoundsForPoint(r.x, r.y); |
||||||
|
//Dimension screenSize = getToolkit().getScreenSize();
|
||||||
|
|
||||||
|
boolean showDescWindow = descWindow != null && ac.isShowDescWindow(); |
||||||
|
int totalH = getHeight(); |
||||||
|
if (showDescWindow) { |
||||||
|
totalH = Math.max(totalH, descWindow.getHeight()); |
||||||
|
} |
||||||
|
|
||||||
|
// Try putting our stuff "below" the caret first. We assume that the
|
||||||
|
// entire height of our stuff fits on the screen one way or the other.
|
||||||
|
aboveCaret = false; |
||||||
|
int y = r.y + r.height + VERTICAL_SPACE; |
||||||
|
if (y + totalH > screenBounds.height) { |
||||||
|
y = r.y - VERTICAL_SPACE - getHeight(); |
||||||
|
aboveCaret = true; |
||||||
|
} |
||||||
|
|
||||||
|
// Get x-coordinate of completions. Try to align left edge with the
|
||||||
|
// caret first.
|
||||||
|
int x = r.x; |
||||||
|
if (!ac.getTextComponentOrientation().isLeftToRight()) { |
||||||
|
x -= getWidth(); // RTL => align right edge
|
||||||
|
} |
||||||
|
if (x < screenBounds.x) { |
||||||
|
x = screenBounds.x; |
||||||
|
} else if (x + getWidth() > screenBounds.x + screenBounds.width) { // completions don't fit
|
||||||
|
x = screenBounds.x + screenBounds.width - getWidth(); |
||||||
|
} |
||||||
|
|
||||||
|
setLocation(x, y); |
||||||
|
|
||||||
|
// Position the description window, if necessary.
|
||||||
|
if (showDescWindow) { |
||||||
|
positionDescWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Toggles the visibility of this popup window. |
||||||
|
* |
||||||
|
* @param visible Whether this window should be visible. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void setVisible(boolean visible) { |
||||||
|
|
||||||
|
if (visible != isVisible()) { |
||||||
|
|
||||||
|
if (visible) { |
||||||
|
installKeyBindings(); |
||||||
|
lastLine = ac.getLineOfCaret(); |
||||||
|
selectFirstItem(); |
||||||
|
if (descWindow == null && ac.isShowDescWindow()) { |
||||||
|
descWindow = createDescriptionWindow(); |
||||||
|
positionDescWindow(); |
||||||
|
} |
||||||
|
// descWindow needs a kick-start the first time it's displayed.
|
||||||
|
// Also, the newly-selected item in the choices list is
|
||||||
|
// probably different from the previous one anyway.
|
||||||
|
if (descWindow != null) { |
||||||
|
Completion c = (Completion) list.getSelectedValue(); |
||||||
|
if (c != null) { |
||||||
|
descWindow.setDescriptionFor(c); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
uninstallKeyBindings(); |
||||||
|
} |
||||||
|
|
||||||
|
super.setVisible(visible); |
||||||
|
|
||||||
|
// Some languages, such as Java, can use quite a lot of memory
|
||||||
|
// when displaying hundreds of completion choices. We pro-actively
|
||||||
|
// clear our list model here to make them available for GC.
|
||||||
|
// Otherwise, they stick around, and consider the following: a
|
||||||
|
// user starts code-completion for Java 5 SDK classes, then hides
|
||||||
|
// the dialog, then changes the "class path" to use a Java 6 SDK
|
||||||
|
// instead. On pressing Ctrl+space, a new array of Completions is
|
||||||
|
// created. If this window holds on to the previous Completions,
|
||||||
|
// you're getting roughly 2x the necessary Completions in memory
|
||||||
|
// until the Completions are actually passed to this window.
|
||||||
|
if (!visible) { // Do after super.setVisible(false)
|
||||||
|
lastSelection = (Completion) list.getSelectedValue(); |
||||||
|
model.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
// Must set descWindow's visibility one way or the other each time,
|
||||||
|
// because of the way child JWindows' visibility is handled - in
|
||||||
|
// some ways it's dependent on the parent, in other ways it's not.
|
||||||
|
if (descWindow != null) { |
||||||
|
descWindow.setVisible(visible && ac.isShowDescWindow()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Stops intercepting certain keystrokes from the text component. |
||||||
|
* |
||||||
|
* @see #installKeyBindings() |
||||||
|
*/ |
||||||
|
private void uninstallKeyBindings() { |
||||||
|
|
||||||
|
if (AutoCompletion.isDebug()) { |
||||||
|
FineLoggerFactory.getLogger().debug("PopupWindow: Removing keybindings"); |
||||||
|
} |
||||||
|
|
||||||
|
JTextComponent comp = ac.getTextComponent(); |
||||||
|
InputMap im = comp.getInputMap(); |
||||||
|
ActionMap am = comp.getActionMap(); |
||||||
|
|
||||||
|
putBackAction(im, am, KeyEvent.VK_ESCAPE, oldEscape); |
||||||
|
putBackAction(im, am, KeyEvent.VK_UP, oldUp); |
||||||
|
putBackAction(im, am, KeyEvent.VK_DOWN, oldDown); |
||||||
|
putBackAction(im, am, KeyEvent.VK_LEFT, oldLeft); |
||||||
|
putBackAction(im, am, KeyEvent.VK_RIGHT, oldRight); |
||||||
|
putBackAction(im, am, KeyEvent.VK_ENTER, oldEnter); |
||||||
|
putBackAction(im, am, KeyEvent.VK_TAB, oldTab); |
||||||
|
putBackAction(im, am, KeyEvent.VK_HOME, oldHome); |
||||||
|
putBackAction(im, am, KeyEvent.VK_END, oldEnd); |
||||||
|
putBackAction(im, am, KeyEvent.VK_PAGE_UP, oldPageUp); |
||||||
|
putBackAction(im, am, KeyEvent.VK_PAGE_DOWN, oldPageDown); |
||||||
|
|
||||||
|
// Ctrl+C
|
||||||
|
KeyStroke ks = getCopyKeyStroke(); |
||||||
|
am.put(im.get(ks), oldCtrlC.action); // Original action
|
||||||
|
im.put(ks, oldCtrlC.key); // Original key
|
||||||
|
|
||||||
|
comp.removeCaretListener(this); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Updates the <tt>LookAndFeel</tt> of this window and the description |
||||||
|
* window. |
||||||
|
*/ |
||||||
|
public void updateUI() { |
||||||
|
SwingUtilities.updateComponentTreeUI(this); |
||||||
|
if (descWindow != null) { |
||||||
|
descWindow.updateUI(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Called when a new item is selected in the popup list. |
||||||
|
* |
||||||
|
* @param e The event. |
||||||
|
*/ |
||||||
|
public void valueChanged(ListSelectionEvent e) { |
||||||
|
if (!e.getValueIsAdjusting()) { |
||||||
|
Object value = list.getSelectedValue(); |
||||||
|
if (value != null && descWindow != null) { |
||||||
|
descWindow.setDescriptionFor((Completion) value); |
||||||
|
positionDescWindow(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class CopyAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean doNormalCopy = false; |
||||||
|
if (descWindow != null && descWindow.isVisible()) { |
||||||
|
doNormalCopy = !descWindow.copy(); |
||||||
|
} |
||||||
|
if (doNormalCopy) { |
||||||
|
ac.getTextComponent().copy(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class DownAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectNextItem(); |
||||||
|
refreshInstallComp(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class EndAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectLastItem(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class EnterAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
insertSelectedCompletion(); |
||||||
|
refreshInstallComp(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class EscapeAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
setVisible(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class HomeAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectFirstItem(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* A mapping from a key (an Object) to an Action. |
||||||
|
*/ |
||||||
|
private static class KeyActionPair { |
||||||
|
|
||||||
|
public Object key; |
||||||
|
public Action action; |
||||||
|
|
||||||
|
public KeyActionPair() { |
||||||
|
} |
||||||
|
|
||||||
|
public KeyActionPair(Object key, Action a) { |
||||||
|
this.key = key; |
||||||
|
this.action = a; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class LeftAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
JTextComponent comp = ac.getTextComponent(); |
||||||
|
Caret c = comp.getCaret(); |
||||||
|
int dot = c.getDot(); |
||||||
|
if (dot > 0) { |
||||||
|
c.setDot(--dot); |
||||||
|
// Ensure moving left hasn't moved us up a line, thus
|
||||||
|
// hiding the popup window.
|
||||||
|
if (comp.isVisible()) { |
||||||
|
if (lastLine != -1) { |
||||||
|
doAutocomplete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class PageDownAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectPageDownItem(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class PageUpAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectPageUpItem(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* The actual list of completion choices in this popup window. |
||||||
|
*/ |
||||||
|
private class PopupList extends JList { |
||||||
|
|
||||||
|
public PopupList(CompletionListModel model) { |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setUI(ListUI ui) { |
||||||
|
if (Util.getUseSubstanceRenderers() && |
||||||
|
SUBSTANCE_LIST_UI.equals(ui.getClass().getName())) { |
||||||
|
// Substance requires its special ListUI be installed for
|
||||||
|
// its renderers to actually render (!), but long completion
|
||||||
|
// lists (e.g. PHPCompletionProvider in RSTALanguageSupport)
|
||||||
|
// will simply populate too slowly on initial display (when
|
||||||
|
// calculating preferred size of all items), so in this case
|
||||||
|
// we give a prototype cell value.
|
||||||
|
CompletionProvider p = ac.getCompletionProvider(); |
||||||
|
BasicCompletion bc = new BasicCompletion(p, "Hello world"); |
||||||
|
setPrototypeCellValue(bc); |
||||||
|
} else { |
||||||
|
// Our custom UI that is faster for long HTML completion lists.
|
||||||
|
ui = new FastListUI(); |
||||||
|
setPrototypeCellValue(null); |
||||||
|
} |
||||||
|
super.setUI(ui); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class RightAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
JTextComponent comp = ac.getTextComponent(); |
||||||
|
Caret c = comp.getCaret(); |
||||||
|
int dot = c.getDot(); |
||||||
|
if (dot < comp.getDocument().getLength()) { |
||||||
|
c.setDot(++dot); |
||||||
|
// Ensure moving right hasn't moved us up a line, thus
|
||||||
|
// hiding the popup window.
|
||||||
|
if (comp.isVisible()) { |
||||||
|
if (lastLine != -1) { |
||||||
|
doAutocomplete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class UpAction extends AbstractAction { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (isVisible()) { |
||||||
|
selectPreviousItem(); |
||||||
|
refreshInstallComp(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@ |
|||||||
|
package com.fr.design.gui.autocomplete; |
||||||
|
|
||||||
|
import java.awt.Window; |
||||||
|
|
||||||
|
public class JSAutoCompletePopupWindow extends AutoCompleteWithExtraRefreshPopupWindow { |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* |
||||||
|
* @param parent The parent window (hosting the text component). |
||||||
|
* @param ac The auto-completion instance. |
||||||
|
*/ |
||||||
|
public JSAutoCompletePopupWindow(Window parent, AutoCompletion ac) { |
||||||
|
super(parent, ac); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package com.fr.design.gui.autocomplete; |
||||||
|
|
||||||
|
public class JSImplPaneAutoCompletion extends AutoCompletionWithExtraRefresh{ |
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* |
||||||
|
* @param provider The completion provider. This cannot be |
||||||
|
* <code>null</code>. |
||||||
|
*/ |
||||||
|
public JSImplPaneAutoCompletion(CompletionProvider provider) { |
||||||
|
super(provider); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected AutoCompleteWithExtraRefreshPopupWindow createAutoCompletePopupWindow() { |
||||||
|
JSAutoCompletePopupWindow popupWindow = new JSAutoCompletePopupWindow(getParentWindow(),this); |
||||||
|
popupWindow.applyComponentOrientation( |
||||||
|
getTextComponentOrientation()); |
||||||
|
if (getCellRender() != null) { |
||||||
|
popupWindow.setListCellRenderer(getCellRender()); |
||||||
|
} |
||||||
|
if (getPreferredChoicesWindowSize() != null) { |
||||||
|
popupWindow.setSize(getPreferredChoicesWindowSize()); |
||||||
|
} |
||||||
|
if (getPreferredDescWindowSize() != null) { |
||||||
|
popupWindow.setDescriptionWindowSize( |
||||||
|
getPreferredDescWindowSize()); |
||||||
|
} |
||||||
|
return popupWindow; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package com.fr.design.gui.ilable; |
||||||
|
|
||||||
|
import javax.swing.JLabel; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.FontMetrics; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class UIAutoChangeLineLabel extends JLabel { |
||||||
|
private final String text; |
||||||
|
private final int width; |
||||||
|
|
||||||
|
|
||||||
|
public UIAutoChangeLineLabel(String text, int width) { |
||||||
|
super(text); |
||||||
|
this.text = text; |
||||||
|
this.width = width; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void doLayout() { |
||||||
|
super.doLayout(); |
||||||
|
this.setText(wrapperHtmlText()); |
||||||
|
} |
||||||
|
|
||||||
|
private String wrapperHtmlText() { |
||||||
|
List<String> stringList = autoChangeLine(this.getWidth()); |
||||||
|
StringBuilder builder = new StringBuilder("<html>"); |
||||||
|
for (String s : stringList) { |
||||||
|
//用THML标签进行拼接,以实现自动换行
|
||||||
|
builder.append(s).append("<br/>"); |
||||||
|
} |
||||||
|
builder.append("</html>"); |
||||||
|
return builder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private List<String> autoChangeLine(int width) { |
||||||
|
List<String> result = new ArrayList<>(); |
||||||
|
if (width <= 0) { |
||||||
|
result.add(this.text); |
||||||
|
} else { |
||||||
|
|
||||||
|
char[] chars = this.text.toCharArray(); |
||||||
|
//获取字体计算大小
|
||||||
|
FontMetrics fontMetrics = this.getFontMetrics(this.getFont()); |
||||||
|
int start = 0; |
||||||
|
int len = 0; |
||||||
|
while (start + len < this.text.length()) { |
||||||
|
while (true) { |
||||||
|
len++; |
||||||
|
if (start + len > this.text.length()) |
||||||
|
break; |
||||||
|
if (fontMetrics.charsWidth(chars, start, len) |
||||||
|
> width) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
result.add(String.copyValueOf(chars, start, len - 1)); |
||||||
|
start = start + len - 1; |
||||||
|
len = 0; |
||||||
|
} |
||||||
|
if (this.text.length() - start > 0) { |
||||||
|
result.add(String.copyValueOf(chars, start, this.text.length() - start)); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() { |
||||||
|
Dimension preferredSize = super.getPreferredSize(); |
||||||
|
List<String> stringList = autoChangeLine(width); |
||||||
|
FontMetrics fontMetrics = this.getFontMetrics(this.getFont()); |
||||||
|
return new Dimension(preferredSize.width, fontMetrics.getHeight() * stringList.size()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,858 @@ |
|||||||
|
package com.fr.design.javascript; |
||||||
|
|
||||||
|
import com.fr.design.border.UIRoundedBorder; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent; |
||||||
|
import com.fr.design.gui.autocomplete.BasicCompletion; |
||||||
|
import com.fr.design.gui.autocomplete.CompletionCellRenderer; |
||||||
|
import com.fr.design.gui.autocomplete.CompletionProvider; |
||||||
|
import com.fr.design.gui.autocomplete.DefaultCompletionProvider; |
||||||
|
import com.fr.design.gui.autocomplete.JSImplPaneAutoCompletion; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itextarea.UITextArea; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.javascript.jsapi.JSAPITreeHelper; |
||||||
|
import com.fr.design.javascript.jsapi.JSAPIUserObject; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.general.CloudCenter; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.http.HttpToolbox; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONException; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Desktop; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.FocusAdapter; |
||||||
|
import java.awt.event.FocusEvent; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.KeyListener; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.io.IOException; |
||||||
|
import java.net.URI; |
||||||
|
import java.net.URISyntaxException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Comparator; |
||||||
|
import java.util.List; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultListCellRenderer; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JPopupMenu; |
||||||
|
import javax.swing.JScrollPane; |
||||||
|
import javax.swing.JTree; |
||||||
|
import javax.swing.event.ListSelectionEvent; |
||||||
|
import javax.swing.event.ListSelectionListener; |
||||||
|
import javax.swing.event.TreeSelectionEvent; |
||||||
|
import javax.swing.event.TreeSelectionListener; |
||||||
|
import javax.swing.tree.DefaultMutableTreeNode; |
||||||
|
import javax.swing.tree.DefaultTreeCellRenderer; |
||||||
|
import javax.swing.tree.DefaultTreeModel; |
||||||
|
import javax.swing.tree.TreeNode; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
|
||||||
|
public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener { |
||||||
|
|
||||||
|
//搜索关键词输入框
|
||||||
|
private UITextField keyWordTextField = new UITextField(16); |
||||||
|
//搜索出的提示列表
|
||||||
|
private JList tipsList; |
||||||
|
private DefaultListModel tipsListModel = new DefaultListModel(); |
||||||
|
|
||||||
|
private JList interfaceNameList; |
||||||
|
private DefaultListModel interfaceNameModel; |
||||||
|
|
||||||
|
private JTree moduleTree; |
||||||
|
|
||||||
|
private DefaultCompletionProvider completionProvider; |
||||||
|
private JSImplPaneAutoCompletion autoCompletion; |
||||||
|
|
||||||
|
//函数说明文本框
|
||||||
|
private UITextArea descriptionTextArea; |
||||||
|
|
||||||
|
private JPopupMenu popupMenu; |
||||||
|
|
||||||
|
private InterfaceAndDescriptionPanel interfaceAndDescriptionPanel; |
||||||
|
private JList helpDOCList; |
||||||
|
|
||||||
|
private int ifHasBeenWriten = 0; |
||||||
|
private int currentPosition = 0; |
||||||
|
private int beginPosition = 0; |
||||||
|
private int insertPosition = 0; |
||||||
|
private static final String SEPARATOR = "_"; |
||||||
|
|
||||||
|
private static final int KEY_10 = 10; |
||||||
|
//上下左右
|
||||||
|
private static final int KEY_37 = 37; |
||||||
|
private static final int KEY_38 = 38; |
||||||
|
private static final int KEY_39 = 39; |
||||||
|
private static final int KEY_40 = 40; |
||||||
|
|
||||||
|
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com"; |
||||||
|
|
||||||
|
private static final String DOCUMENT_SEARCH_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_search"); |
||||||
|
|
||||||
|
private String currentValue; |
||||||
|
|
||||||
|
public JSContentWithDescriptionPane(String[] args) { |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
//===============================
|
||||||
|
this.initFunctionTitle(args); |
||||||
|
JPanel jsParaAndSearchPane = new JPanel(new BorderLayout()); |
||||||
|
|
||||||
|
//js函数声明面板
|
||||||
|
JPanel jsParaPane = createJSParaPane(); |
||||||
|
|
||||||
|
jsParaPane.setPreferredSize(new Dimension(650, 80)); |
||||||
|
//右上角的搜索提示面板
|
||||||
|
JPanel tipsPane = createTipsPane(); |
||||||
|
|
||||||
|
jsParaAndSearchPane.add(jsParaPane, BorderLayout.CENTER); |
||||||
|
jsParaAndSearchPane.add(tipsPane, BorderLayout.EAST); |
||||||
|
|
||||||
|
initPopTips(); |
||||||
|
|
||||||
|
//js文本编辑面板
|
||||||
|
UIScrollPane contentTextAreaPanel = createContentTextAreaPanel(); |
||||||
|
initContextAreaListener(); |
||||||
|
|
||||||
|
contentTextAreaPanel.setPreferredSize(new Dimension(850, 250)); |
||||||
|
//js函数结束标签
|
||||||
|
UILabel endBracketsLabel = new UILabel(); |
||||||
|
endBracketsLabel.setText("}"); |
||||||
|
|
||||||
|
//结尾括号和复用函数按钮面板
|
||||||
|
JPanel endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
endBracketsPanel.add(endBracketsLabel, BorderLayout.WEST); |
||||||
|
|
||||||
|
JPanel northPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
northPanel.add(jsParaAndSearchPane, BorderLayout.NORTH); |
||||||
|
|
||||||
|
northPanel.add(contentTextAreaPanel, BorderLayout.CENTER); |
||||||
|
northPanel.add(endBracketsPanel, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
//主编辑框,也就是面板的正中间部分
|
||||||
|
this.add(northPanel, BorderLayout.CENTER); |
||||||
|
|
||||||
|
//函数分类和函数说明面板==================================
|
||||||
|
JPanel functionNameAndDescriptionPanel = createInterfaceAndDescriptionPanel(); |
||||||
|
functionNameAndDescriptionPanel.setPreferredSize(new Dimension(880, 220)); |
||||||
|
|
||||||
|
this.add(functionNameAndDescriptionPanel, BorderLayout.SOUTH); |
||||||
|
} |
||||||
|
|
||||||
|
private void initContextAreaListener() { |
||||||
|
contentTextArea.addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyTyped(KeyEvent e) { |
||||||
|
if ((e.getKeyChar() >= 'A' && e.getKeyChar() <= 'z') || e.getKeyChar() == '_') { |
||||||
|
if (autoCompletion != null) { |
||||||
|
autoCompletion.doCompletion(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyReleased(KeyEvent e) { |
||||||
|
contentTextArea.setForeground(Color.black); |
||||||
|
} |
||||||
|
}); |
||||||
|
contentTextArea.addKeyListener(this); |
||||||
|
contentTextArea.addFocusListener(new FocusAdapter() { |
||||||
|
@Override |
||||||
|
public void focusGained(FocusEvent e) { |
||||||
|
if (autoCompletion == null) { |
||||||
|
installAutoCompletion(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void focusLost(FocusEvent e) { |
||||||
|
uninstallAutoCompletion(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyTyped(KeyEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (ifHasBeenWriten == 0) { |
||||||
|
this.contentTextArea.setText(StringUtils.EMPTY); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyReleased(KeyEvent e) { |
||||||
|
int key = e.getKeyCode(); |
||||||
|
if (key == KEY_38 || key == KEY_40 || key == KEY_37 || key == KEY_39 || key == KEY_10) //如果是删除符号 ,为了可读性 没有和其他按键的程序相融合
|
||||||
|
{ |
||||||
|
currentPosition = contentTextArea.getCaretPosition(); |
||||||
|
insertPosition = currentPosition; |
||||||
|
beginPosition = getBeginPosition(); |
||||||
|
} else { |
||||||
|
if (contentTextArea.getText().trim().length() == 0) { |
||||||
|
insertPosition = 0; |
||||||
|
} else { |
||||||
|
contentTextArea.setForeground(Color.black); |
||||||
|
currentPosition = contentTextArea.getCaretPosition(); |
||||||
|
beginPosition = getBeginPosition(); |
||||||
|
insertPosition = beginPosition; |
||||||
|
ifHasBeenWriten = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int getBeginPosition() { |
||||||
|
int i = currentPosition; |
||||||
|
String textArea = contentTextArea.getText(); |
||||||
|
for (; i > 0; i--) { |
||||||
|
String tested = textArea.substring(i - 1, i).toUpperCase(); |
||||||
|
char[] testedChar = tested.toCharArray(); |
||||||
|
if (isChar(testedChar[0]) || isNum(testedChar[0])) { |
||||||
|
continue; |
||||||
|
} else { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return i; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isNum(char tested) { |
||||||
|
return tested >= '0' && tested <= '9'; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isChar(char tested) { |
||||||
|
return tested >= 'A' && tested <= 'Z' || tested >= 'a' && tested < 'z'; |
||||||
|
} |
||||||
|
|
||||||
|
public class InterfaceAndDescriptionPanel extends JPanel implements AutoCompleteExtraRefreshComponent { |
||||||
|
@Override |
||||||
|
public void refresh(String replacementText) { |
||||||
|
fixInterfaceNameList(replacementText); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void fixInterfaceNameList(String interfaceName) { |
||||||
|
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) moduleTree.getModel(); |
||||||
|
TreeNode root = (TreeNode) defaultTreeModel.getRoot(); |
||||||
|
String directCategory = JSAPITreeHelper.getDirectCategory(interfaceName); |
||||||
|
if (directCategory == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
setModuleTreeSelection(root, directCategory, defaultTreeModel); |
||||||
|
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel(); |
||||||
|
interfaceNameModel.clear(); |
||||||
|
List<String> interfaceNames = JSAPITreeHelper.getNames(directCategory); |
||||||
|
int index = 0; |
||||||
|
for (int i = 0; i < interfaceNames.size(); i++) { |
||||||
|
interfaceNameModel.addElement(interfaceNames.get(i)); |
||||||
|
if (StringUtils.equals(interfaceNames.get(i), interfaceName)) { |
||||||
|
index = i; |
||||||
|
} |
||||||
|
} |
||||||
|
interfaceNameList.setSelectedIndex(index); |
||||||
|
interfaceNameList.ensureIndexIsVisible(index); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean setModuleTreeSelection(TreeNode node, String directCategory, DefaultTreeModel treeModel) { |
||||||
|
|
||||||
|
DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) node; |
||||||
|
Object userObject = defaultMutableTreeNode.getUserObject(); |
||||||
|
if (userObject instanceof JSAPIUserObject) { |
||||||
|
String value = ((JSAPIUserObject) userObject).getValue(); |
||||||
|
if (StringUtils.equals(value, directCategory)) { |
||||||
|
moduleTree.setSelectionPath(new TreePath(treeModel.getPathToRoot(node))); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
for (int i = 0; i < node.getChildCount(); i++) { |
||||||
|
if (setModuleTreeSelection(node.getChildAt(i), directCategory, treeModel)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createInterfaceAndDescriptionPanel() { |
||||||
|
interfaceAndDescriptionPanel = new InterfaceAndDescriptionPanel(); |
||||||
|
interfaceAndDescriptionPanel.setLayout(new BorderLayout(4, 4)); |
||||||
|
JPanel interfacePanel = new JPanel(new BorderLayout(4, 4)); |
||||||
|
interfaceAndDescriptionPanel.add(interfacePanel, BorderLayout.WEST); |
||||||
|
JPanel descriptionAndDocumentPanel = new JPanel(new BorderLayout(4, 4)); |
||||||
|
//函数说明和帮助文档框
|
||||||
|
initDescriptionArea(descriptionAndDocumentPanel); |
||||||
|
|
||||||
|
//模块和接口面板
|
||||||
|
initInterfaceModuleTree(interfacePanel); |
||||||
|
initInterfaceNameList(interfacePanel); |
||||||
|
|
||||||
|
initHelpDocumentPane(descriptionAndDocumentPanel); |
||||||
|
|
||||||
|
interfaceAndDescriptionPanel.add(descriptionAndDocumentPanel, BorderLayout.CENTER); |
||||||
|
return interfaceAndDescriptionPanel; |
||||||
|
} |
||||||
|
|
||||||
|
private void doHelpDocumentSearch() { |
||||||
|
Object value = interfaceNameList.getSelectedValue(); |
||||||
|
if (value != null) { |
||||||
|
String url = DOCUMENT_SEARCH_URL + value.toString(); |
||||||
|
try { |
||||||
|
String result = HttpToolbox.get(url); |
||||||
|
JSONObject jsonObject = new JSONObject(result); |
||||||
|
JSONArray jsonArray = jsonObject.optJSONArray("list"); |
||||||
|
if (jsonArray != null) { |
||||||
|
DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel(); |
||||||
|
helpDOCModel.clear(); |
||||||
|
for (int i = 0; i < jsonArray.length(); i++) { |
||||||
|
JSONObject resultJSONObject = jsonArray.optJSONObject(i); |
||||||
|
String docURL = resultJSONObject.optString("url"); |
||||||
|
String name = resultJSONObject.optString("title").trim(); |
||||||
|
HelpDocument helpDocument = new HelpDocument(docURL, name); |
||||||
|
helpDOCModel.addElement(helpDocument); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (JSONException e) { |
||||||
|
FineLoggerFactory.getLogger().debug(e.getMessage(), e); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initHelpDocumentPane(JPanel descriptionAndDocumentPanel) { |
||||||
|
UIScrollPane helpDOCScrollPane; |
||||||
|
if (isNetworkOk()) { |
||||||
|
helpDOCList = new JList(new DefaultListModel()); |
||||||
|
initHelpDOCListRender(); |
||||||
|
initHelpDOCListListener(); |
||||||
|
helpDOCScrollPane = new UIScrollPane(helpDOCList); |
||||||
|
doHelpDocumentSearch(); |
||||||
|
} else { |
||||||
|
UILabel label1 = new UILabel(Toolkit.i18nText("Fine-Design_Net_Connect_Failed"), 0); |
||||||
|
label1.setPreferredSize(new Dimension(180, 20)); |
||||||
|
UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Reload"), 0); |
||||||
|
label2.setPreferredSize(new Dimension(180, 20)); |
||||||
|
label2.setForeground(Color.blue); |
||||||
|
JPanel labelPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0); |
||||||
|
labelPane.setBackground(Color.WHITE); |
||||||
|
labelPane.add(label1); |
||||||
|
labelPane.add(label2); |
||||||
|
JPanel containerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
containerPanel.add(labelPane, BorderLayout.CENTER); |
||||||
|
helpDOCScrollPane = new UIScrollPane(containerPanel); |
||||||
|
label2.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
descriptionAndDocumentPanel.removeAll(); |
||||||
|
initHelpDocumentPane(descriptionAndDocumentPanel); |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
helpDOCScrollPane.setPreferredSize(new Dimension(200, 200)); |
||||||
|
helpDOCScrollPane.setBorder(null); |
||||||
|
descriptionAndDocumentPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Relevant_Cases"), helpDOCScrollPane), BorderLayout.EAST); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void initHelpDOCListListener() { |
||||||
|
helpDOCList.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (e.getClickCount() == 2) { |
||||||
|
Object value = helpDOCList.getSelectedValue(); |
||||||
|
if (value instanceof HelpDocument) { |
||||||
|
String url = ((HelpDocument) value).getDocumentUrl(); |
||||||
|
try { |
||||||
|
Desktop.getDesktop().browse(new URI(url)); |
||||||
|
} catch (IOException ex) { |
||||||
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||||
|
} catch (URISyntaxException ex) { |
||||||
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void initHelpDOCListRender() { |
||||||
|
helpDOCList.setCellRenderer(new DefaultListCellRenderer() { |
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||||
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||||
|
if (value instanceof HelpDocument) { |
||||||
|
this.setText(((HelpDocument) value).getName()); |
||||||
|
this.setForeground(Color.BLUE); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isNetworkOk() { |
||||||
|
try { |
||||||
|
HttpToolbox.get(URL_FOR_TEST_NETWORK); |
||||||
|
return true; |
||||||
|
} catch (Exception ignore) { |
||||||
|
// 网络异常
|
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class HelpDocument { |
||||||
|
private String documentUrl; |
||||||
|
|
||||||
|
|
||||||
|
private String name; |
||||||
|
|
||||||
|
public HelpDocument(String documentUrl, String name) { |
||||||
|
this.documentUrl = documentUrl; |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDocumentUrl() { |
||||||
|
return documentUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initDescriptionArea(JPanel descriptionPanel) { |
||||||
|
descriptionTextArea = new UITextArea(); |
||||||
|
UIScrollPane descriptionScrollPane = new UIScrollPane(descriptionTextArea); |
||||||
|
descriptionScrollPane.setPreferredSize(new Dimension(300, 200)); |
||||||
|
descriptionPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Interface_Description"), descriptionScrollPane), BorderLayout.CENTER); |
||||||
|
descriptionTextArea.setBackground(Color.white); |
||||||
|
descriptionTextArea.setLineWrap(true); |
||||||
|
descriptionTextArea.setWrapStyleWord(true); |
||||||
|
descriptionTextArea.setEditable(false); |
||||||
|
} |
||||||
|
|
||||||
|
private void installAutoCompletion() { |
||||||
|
CompletionProvider provider = createCompletionProvider(); |
||||||
|
autoCompletion = new JSImplPaneAutoCompletion(provider); |
||||||
|
autoCompletion.setListCellRenderer(new CompletionCellRenderer()); |
||||||
|
autoCompletion.install(contentTextArea); |
||||||
|
autoCompletion.installExtraRefreshComponent(interfaceAndDescriptionPanel); |
||||||
|
} |
||||||
|
|
||||||
|
private void uninstallAutoCompletion() { |
||||||
|
if (autoCompletion != null) { |
||||||
|
autoCompletion.uninstall(); |
||||||
|
autoCompletion = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private CompletionProvider createCompletionProvider() { |
||||||
|
if (completionProvider == null) { |
||||||
|
completionProvider = new DefaultCompletionProvider(); |
||||||
|
for (String name : JSAPITreeHelper.getAllNames()) { |
||||||
|
completionProvider.addCompletion(new BasicCompletion(completionProvider, name)); |
||||||
|
} |
||||||
|
} |
||||||
|
return completionProvider; |
||||||
|
} |
||||||
|
|
||||||
|
private void initInterfaceModuleTree(JPanel interfacePanel) { |
||||||
|
moduleTree = new JTree(); |
||||||
|
UIScrollPane moduleTreePane = new UIScrollPane(moduleTree); |
||||||
|
moduleTreePane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
||||||
|
interfacePanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Module"), moduleTreePane), BorderLayout.WEST); |
||||||
|
moduleTreePane.setPreferredSize(new Dimension(180, 200)); |
||||||
|
|
||||||
|
moduleTree.setRootVisible(false); |
||||||
|
moduleTree.setShowsRootHandles(true); |
||||||
|
moduleTree.setCellRenderer(moduleTreeCellRender); |
||||||
|
DefaultTreeModel moduleTreeModel = (DefaultTreeModel) moduleTree.getModel(); |
||||||
|
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) moduleTreeModel.getRoot(); |
||||||
|
rootNode.removeAllChildren(); |
||||||
|
|
||||||
|
JSAPITreeHelper.createJSAPITree(rootNode); |
||||||
|
moduleTreeModel.reload(); |
||||||
|
|
||||||
|
initModuleTreeSelectionListener(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initModuleTreeSelectionListener() { |
||||||
|
moduleTree.addTreeSelectionListener(new TreeSelectionListener() { |
||||||
|
@Override |
||||||
|
public void valueChanged(TreeSelectionEvent e) { |
||||||
|
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) moduleTree.getLastSelectedPathComponent(); |
||||||
|
Object selectedValue = selectedTreeNode.getUserObject(); |
||||||
|
if (null == selectedValue) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (selectedValue instanceof JSAPIUserObject) { |
||||||
|
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel(); |
||||||
|
interfaceNameModel.clear(); |
||||||
|
String text = ((JSAPIUserObject) selectedValue).getValue(); |
||||||
|
List<String> allInterfaceNames = JSAPITreeHelper.getNames(text); |
||||||
|
for (String interfaceName : allInterfaceNames) { |
||||||
|
interfaceNameModel.addElement(interfaceName); |
||||||
|
} |
||||||
|
if (interfaceNameModel.size() > 0) { |
||||||
|
interfaceNameList.setSelectedIndex(0); |
||||||
|
setDescription(interfaceNameList.getSelectedValue().toString()); |
||||||
|
interfaceNameList.ensureIndexIsVisible(0); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private DefaultTreeCellRenderer moduleTreeCellRender = new DefaultTreeCellRenderer() { |
||||||
|
public Component getTreeCellRendererComponent(JTree tree, |
||||||
|
Object value, boolean selected, boolean expanded, |
||||||
|
boolean leaf, int row, boolean hasFocus) { |
||||||
|
super.getTreeCellRendererComponent(tree, value, selected, |
||||||
|
expanded, leaf, row, hasFocus); |
||||||
|
|
||||||
|
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value; |
||||||
|
Object userObj = treeNode.getUserObject(); |
||||||
|
if (userObj instanceof JSAPIUserObject) { |
||||||
|
this.setText(((JSAPIUserObject) userObj).getDisplayText()); |
||||||
|
this.setIcon(null); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
private void initInterfaceNameList(JPanel interfacePanel) { |
||||||
|
interfaceNameList = new JList(new DefaultListModel()); |
||||||
|
UIScrollPane interfaceNamePanelScrollPane = new UIScrollPane(interfaceNameList); |
||||||
|
interfaceNamePanelScrollPane.setPreferredSize(new Dimension(180, 200)); |
||||||
|
interfacePanel.add( |
||||||
|
this.createNamePane(Toolkit.i18nText("Fine-Design_Interface") + ":", interfaceNamePanelScrollPane), |
||||||
|
BorderLayout.CENTER); |
||||||
|
|
||||||
|
interfaceNamePanelScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
||||||
|
initInterfaceNameModule(); |
||||||
|
initInterfaceNameListSelectionListener(); |
||||||
|
initInterfaceNameListMouseListener(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initInterfaceNameModule() { |
||||||
|
moduleTree.setSelectionPath(moduleTree.getPathForRow(0)); |
||||||
|
} |
||||||
|
|
||||||
|
private void setDescription(String interfaceName) { |
||||||
|
StringBuilder il8Key = new StringBuilder(); |
||||||
|
moduleTree.getSelectionPath().getPath(); |
||||||
|
Object obj = moduleTree.getSelectionPath().getPath()[moduleTree.getSelectionPath().getPath().length - 1]; |
||||||
|
Object userObject = ((DefaultMutableTreeNode) obj).getUserObject(); |
||||||
|
if (userObject instanceof JSAPIUserObject) { |
||||||
|
il8Key.append(JSAPITreeHelper.getDirectCategory(interfaceName)); |
||||||
|
} |
||||||
|
interfaceName = interfaceName.toUpperCase(); |
||||||
|
if (!interfaceName.startsWith(SEPARATOR)) { |
||||||
|
interfaceName = SEPARATOR + interfaceName; |
||||||
|
} |
||||||
|
il8Key.append(interfaceName); |
||||||
|
descriptionTextArea.setText(Toolkit.i18nText(il8Key.toString())); |
||||||
|
descriptionTextArea.moveCaretPosition(0); |
||||||
|
} |
||||||
|
|
||||||
|
private void initInterfaceNameListSelectionListener() { |
||||||
|
interfaceNameList.addListSelectionListener(new ListSelectionListener() { |
||||||
|
|
||||||
|
public void valueChanged(ListSelectionEvent evt) { |
||||||
|
Object selectedValue = interfaceNameList.getSelectedValue(); |
||||||
|
if (selectedValue == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String interfaceName = selectedValue.toString(); |
||||||
|
if (!StringUtils.equals(interfaceName, currentValue)) { |
||||||
|
setDescription(interfaceName); |
||||||
|
doHelpDocumentSearch(); |
||||||
|
currentValue = interfaceName; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initInterfaceNameListMouseListener() { |
||||||
|
interfaceNameList.addMouseListener(new MouseAdapter() { |
||||||
|
public void mouseClicked(MouseEvent evt) { |
||||||
|
if (evt.getClickCount() >= 2) { |
||||||
|
Object selectedValue = interfaceNameList.getSelectedValue(); |
||||||
|
String interfaceName = selectedValue.toString(); |
||||||
|
applyText(interfaceName); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void applyText(String text) { |
||||||
|
if (text == null || text.length() <= 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (ifHasBeenWriten == 0) { |
||||||
|
contentTextArea.setForeground(Color.black); |
||||||
|
contentTextArea.setText(StringUtils.EMPTY); |
||||||
|
ifHasBeenWriten = 1; |
||||||
|
insertPosition = 0; |
||||||
|
} |
||||||
|
String textAll = contentTextArea.getText(); |
||||||
|
currentPosition = contentTextArea.getCaretPosition(); |
||||||
|
int insert = 0; |
||||||
|
int current = 0; |
||||||
|
if (insertPosition <= currentPosition) { |
||||||
|
insert = insertPosition; |
||||||
|
current = currentPosition; |
||||||
|
} else { |
||||||
|
insert = currentPosition; |
||||||
|
current = insertPosition; |
||||||
|
} |
||||||
|
String beforeIndexOfInsertString = textAll.substring(0, insert); |
||||||
|
String afterIndexofInsertString = textAll.substring(current); |
||||||
|
contentTextArea.setText(beforeIndexOfInsertString + text + afterIndexofInsertString); |
||||||
|
contentTextArea.getText(); |
||||||
|
contentTextArea.requestFocus(); |
||||||
|
insertPosition = contentTextArea.getCaretPosition(); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createNamePane(String name, JComponent comp) { |
||||||
|
JPanel namePane = new JPanel(new BorderLayout(4, 4)); |
||||||
|
namePane.add(new UILabel(name), BorderLayout.NORTH); |
||||||
|
namePane.add(comp, BorderLayout.CENTER); |
||||||
|
return namePane; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createTipsPane() { |
||||||
|
JPanel tipsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
tipsPane.setLayout(new BorderLayout(4, 4)); |
||||||
|
tipsPane.setBorder(BorderFactory.createEmptyBorder(30, 2, 0, 0)); |
||||||
|
JPanel searchPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
searchPane.setLayout(new BorderLayout(4, 4)); |
||||||
|
searchPane.add(keyWordTextField, BorderLayout.CENTER); |
||||||
|
|
||||||
|
//搜索按钮
|
||||||
|
UIButton searchButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Search")); |
||||||
|
searchButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
String toFind = keyWordTextField.getText(); |
||||||
|
search(toFind); |
||||||
|
popTips(); |
||||||
|
tipsList.requestFocusInWindow(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
keyWordTextField.addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (e.getKeyChar() == KeyEvent.VK_ENTER) { |
||||||
|
e.consume(); |
||||||
|
String toFind = keyWordTextField.getText(); |
||||||
|
search(toFind); |
||||||
|
popTips(); |
||||||
|
tipsList.requestFocusInWindow(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
searchPane.add(searchButton, BorderLayout.EAST); |
||||||
|
tipsPane.add(searchPane, BorderLayout.NORTH); |
||||||
|
|
||||||
|
tipsList = new JList(tipsListModel); |
||||||
|
tipsList.addMouseListener(tipsListMouseListener); |
||||||
|
tipsList.addListSelectionListener(tipsListSelectionListener); |
||||||
|
tipsList.addKeyListener(tipListKeyListener); |
||||||
|
|
||||||
|
return tipsPane; |
||||||
|
} |
||||||
|
|
||||||
|
private void search(String key) { |
||||||
|
tipsListModel.removeAllElements(); |
||||||
|
tipsListModel.clear(); |
||||||
|
key = key.replaceAll(StringUtils.BLANK, StringUtils.EMPTY); |
||||||
|
ArrayList<String> list = new ArrayList<>(); |
||||||
|
if (!StringUtils.isEmpty(key)) { |
||||||
|
List<String> allNames = JSAPITreeHelper.getAllNames(); |
||||||
|
for (String name : allNames) { |
||||||
|
if (searchResult(key, name)) { |
||||||
|
list.add(name); |
||||||
|
} |
||||||
|
} |
||||||
|
String finalKey = key; |
||||||
|
Collections.sort(list, new Comparator<String>() { |
||||||
|
@Override |
||||||
|
public int compare(String o1, String o2) { |
||||||
|
int result; |
||||||
|
boolean o1StartWidth = o1.toLowerCase().startsWith(finalKey.toLowerCase()); |
||||||
|
boolean o2StartWidth = o2.toLowerCase().startsWith(finalKey.toLowerCase()); |
||||||
|
if (o1StartWidth) { |
||||||
|
result = o2StartWidth ? o1.compareTo(o2) : -1; |
||||||
|
} else { |
||||||
|
result = o2StartWidth ? 1 : o1.compareTo(o2); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
}); |
||||||
|
for (String name : list) { |
||||||
|
tipsListModel.addElement(name); |
||||||
|
} |
||||||
|
if (!tipsListModel.isEmpty()) { |
||||||
|
tipsList.setSelectedIndex(0); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean searchResult(String key, String interfaceName) { |
||||||
|
if (StringUtils.isBlank(key) || StringUtils.isBlank(interfaceName)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
int length = key.length(); |
||||||
|
String temp = interfaceName.toUpperCase(); |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
String check = key.substring(i, i + 1); |
||||||
|
int index = temp.indexOf(check.toUpperCase()); |
||||||
|
if (index == -1) { |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
temp = temp.substring(index + 1); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private void initPopTips() { |
||||||
|
popupMenu = new JPopupMenu(); |
||||||
|
JScrollPane tipsScrollPane = new JScrollPane(tipsList); |
||||||
|
popupMenu.add(tipsScrollPane); |
||||||
|
tipsScrollPane.setPreferredSize(new Dimension(220, 146)); |
||||||
|
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
||||||
|
} |
||||||
|
|
||||||
|
private void popTips() { |
||||||
|
popupMenu.show(keyWordTextField, 0, 23); |
||||||
|
} |
||||||
|
|
||||||
|
private ListSelectionListener tipsListSelectionListener = new ListSelectionListener() { |
||||||
|
@Override |
||||||
|
public void valueChanged(ListSelectionEvent e) { |
||||||
|
Object selectValue = tipsList.getSelectedValue(); |
||||||
|
if (selectValue == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String interfaceName = selectValue.toString(); |
||||||
|
fixInterfaceNameList(interfaceName); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private KeyListener tipListKeyListener = new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (e.getKeyChar() == KeyEvent.VK_ENTER) { |
||||||
|
Object selectValue = tipsList.getSelectedValue(); |
||||||
|
if (selectValue == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
tipListValueSelectAction(selectValue.toString()); |
||||||
|
if (popupMenu != null) { |
||||||
|
popupMenu.setVisible(false); |
||||||
|
} |
||||||
|
contentTextArea.requestFocusInWindow(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private void tipListValueSelectAction(String value) { |
||||||
|
if (ifHasBeenWriten == 0) { |
||||||
|
contentTextArea.setForeground(Color.black); |
||||||
|
contentTextArea.setText(StringUtils.EMPTY); |
||||||
|
} |
||||||
|
contentTextArea.setForeground(Color.black); |
||||||
|
currentPosition = contentTextArea.getCaretPosition(); |
||||||
|
String output = value; |
||||||
|
String textAll = contentTextArea.getText(); |
||||||
|
String textReplaced; |
||||||
|
int position = 0; |
||||||
|
if (insertPosition <= currentPosition) { |
||||||
|
textReplaced = textAll.substring(0, insertPosition) + output + textAll.substring(currentPosition); |
||||||
|
position = insertPosition + output.length(); |
||||||
|
} else { |
||||||
|
textReplaced = textAll.substring(0, currentPosition) + output + textAll.substring(insertPosition); |
||||||
|
position = currentPosition + output.length(); |
||||||
|
} |
||||||
|
contentTextArea.setText(textReplaced); |
||||||
|
contentTextArea.setCaretPosition(position); |
||||||
|
insertPosition = position; |
||||||
|
ifHasBeenWriten = 1; |
||||||
|
tipsListModel.removeAllElements(); |
||||||
|
} |
||||||
|
|
||||||
|
private MouseListener tipsListMouseListener = new MouseAdapter() { |
||||||
|
String singlePressContent; |
||||||
|
|
||||||
|
String doublePressContent; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
int index = tipsList.getSelectedIndex(); |
||||||
|
if (index != -1) { |
||||||
|
if (e.getClickCount() == 1) { |
||||||
|
singlePressContent = (String) tipsListModel.getElementAt(index); |
||||||
|
} else if (e.getClickCount() == 2) { |
||||||
|
doublePressContent = (String) tipsListModel.getElementAt(index); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseReleased(MouseEvent e) { |
||||||
|
int index = tipsList.getSelectedIndex(); |
||||||
|
if (index != -1) { |
||||||
|
if (e.getClickCount() == 1) { |
||||||
|
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), singlePressContent)) { |
||||||
|
singleClickActuator(singlePressContent); |
||||||
|
} |
||||||
|
} else if (e.getClickCount() == 2) { |
||||||
|
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), doublePressContent)) { |
||||||
|
doubleClickActuator(doublePressContent); |
||||||
|
} |
||||||
|
if (popupMenu != null) { |
||||||
|
popupMenu.setVisible(false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void singleClickActuator(String currentLineContent) { |
||||||
|
setDescription(currentLineContent); |
||||||
|
fixInterfaceNameList(currentLineContent); |
||||||
|
} |
||||||
|
|
||||||
|
private void doubleClickActuator(String currentLineContent) { |
||||||
|
tipListValueSelectAction(currentLineContent); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.fr.design.javascript; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.js.JavaScriptImpl; |
||||||
|
|
||||||
|
|
||||||
|
public class NewJavaScriptImplPane extends JavaScriptImplPane { |
||||||
|
public NewJavaScriptImplPane(String[] args) { |
||||||
|
super(args); |
||||||
|
} |
||||||
|
|
||||||
|
protected JSContentPane createJSContentPane(String[] defaultArgs){ |
||||||
|
return new JSContentWithDescriptionPane(defaultArgs); |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(JavaScriptImpl javaScript) { |
||||||
|
if (javaScript != null) { |
||||||
|
populateBean(javaScript); |
||||||
|
} else { |
||||||
|
jsPane.reset(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
|
||||||
|
public class CategoryTreeNodesUserObject implements JSAPIUserObject { |
||||||
|
private String value; |
||||||
|
|
||||||
|
public CategoryTreeNodesUserObject(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDisplayText() { |
||||||
|
return Toolkit.i18nText(value); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import javax.swing.tree.DefaultMutableTreeNode; |
||||||
|
|
||||||
|
public class JSAPITreeHelper { |
||||||
|
private static final String JSAPI_PATH = "com/fr/design/javascript/jsapi/jsapi.json"; |
||||||
|
private static final String CATEGORY_PATH = "com/fr/design/javascript/jsapi/category.json"; |
||||||
|
private static JSONObject categoryJSON ; |
||||||
|
private static JSONObject jsapiJSON ; |
||||||
|
|
||||||
|
static { |
||||||
|
jsapiJSON = createJSON(JSAPI_PATH); |
||||||
|
categoryJSON = createJSON(CATEGORY_PATH); |
||||||
|
} |
||||||
|
|
||||||
|
private static JSONObject createJSON(String path) { |
||||||
|
StringBuilder jsonString = new StringBuilder(StringUtils.EMPTY); |
||||||
|
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IOUtils.readResource(path)))) { |
||||||
|
String s; |
||||||
|
while ((s = bufferedReader.readLine()) != null) { |
||||||
|
jsonString.append(s); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return new JSONObject(jsonString.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static void createJSAPITree(DefaultMutableTreeNode rootNode) { |
||||||
|
createJSAPITree(categoryJSON, rootNode); |
||||||
|
} |
||||||
|
|
||||||
|
public static String getDirectCategory(String name) { |
||||||
|
if (jsapiJSON != null) { |
||||||
|
Iterator<String> it = jsapiJSON.keys(); |
||||||
|
while (it.hasNext()) { |
||||||
|
String key = it.next(); |
||||||
|
JSONArray nameArray = jsapiJSON.optJSONArray(key); |
||||||
|
for (int i = 0; i < nameArray.length(); i++) { |
||||||
|
if (StringUtils.equals(nameArray.getString(i), name)) { |
||||||
|
return key; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static void createJSAPITree(JSONObject jsonObject, DefaultMutableTreeNode rootNode) { |
||||||
|
if (jsonObject != null && rootNode != null) { |
||||||
|
Iterator<String> it = jsonObject.keys(); |
||||||
|
while (it.hasNext()) { |
||||||
|
String key = it.next(); |
||||||
|
JSONObject subNode = jsonObject.optJSONObject(key); |
||||||
|
if (subNode.size() == 0) { |
||||||
|
rootNode.add(new DefaultMutableTreeNode(new CategoryTreeNodesUserObject(key))); |
||||||
|
} else { |
||||||
|
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(new CategoryTreeNodesUserObject(key)); |
||||||
|
rootNode.add(treeNode); |
||||||
|
createJSAPITree(subNode, treeNode); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static List<String> getAllSubNodes(String name) { |
||||||
|
return getAllSubNodes(name, categoryJSON); |
||||||
|
} |
||||||
|
|
||||||
|
public static List<String> getAllNames() { |
||||||
|
ArrayList<String> result = new ArrayList<>(); |
||||||
|
if (jsapiJSON != null) { |
||||||
|
Iterator<String> it = jsapiJSON.keys(); |
||||||
|
while (it.hasNext()) { |
||||||
|
String key = it.next(); |
||||||
|
JSONArray nameArray = jsapiJSON.optJSONArray(key); |
||||||
|
for (int i = 0; i < nameArray.length(); i++) { |
||||||
|
result.add(nameArray.getString(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public static List<String> getNames(String category) { |
||||||
|
ArrayList<String> result = new ArrayList<>(); |
||||||
|
List<String> subCategories = getAllSubNodes(category); |
||||||
|
if (jsapiJSON != null) { |
||||||
|
for (String subCategory : subCategories) { |
||||||
|
if (jsapiJSON.containsKey(subCategory)) { |
||||||
|
JSONArray nameArray = jsapiJSON.optJSONArray(subCategory); |
||||||
|
for (int i = 0; i < nameArray.length(); i++) { |
||||||
|
result.add(nameArray.getString(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private static List<String> getAllSubNodes(String name, JSONObject jsonObject) { |
||||||
|
ArrayList<String> result = new ArrayList<>(); |
||||||
|
if (jsonObject != null) { |
||||||
|
Iterator<String> it = jsonObject.keys(); |
||||||
|
while (it.hasNext()) { |
||||||
|
String key = it.next(); |
||||||
|
JSONObject subNode = jsonObject.optJSONObject(key); |
||||||
|
if (subNode.size() == 0) { |
||||||
|
if (StringUtils.equals(key, name)) { |
||||||
|
result.add(key); |
||||||
|
return result; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (StringUtils.equals(key, name)) { |
||||||
|
result.add(key); |
||||||
|
result.addAll(getAllSubNodes(subNode)); |
||||||
|
return result; |
||||||
|
} else { |
||||||
|
result.addAll(getAllSubNodes(name, subNode)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private static List<String> getAllSubNodes(JSONObject jsonObject) { |
||||||
|
ArrayList<String> result = new ArrayList<>(); |
||||||
|
if (jsonObject != null) { |
||||||
|
Iterator<String> it = jsonObject.keys(); |
||||||
|
while (it.hasNext()) { |
||||||
|
String key = it.next(); |
||||||
|
JSONObject subNode = jsonObject.optJSONObject(key); |
||||||
|
if (subNode.size() == 0) { |
||||||
|
result.add(key); |
||||||
|
} else { |
||||||
|
result.add(key); |
||||||
|
result.addAll(getAllSubNodes(subNode)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
|
||||||
|
public interface JSAPIUserObject { |
||||||
|
|
||||||
|
String getValue(); |
||||||
|
|
||||||
|
String getDisplayText(); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
import com.fr.js.JavaScriptImpl; |
||||||
|
|
||||||
|
public interface JSImplPopulateAction { |
||||||
|
void populate(JavaScriptImpl javaScript); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
import com.fr.js.JavaScriptImpl; |
||||||
|
|
||||||
|
public interface JSImplUpdateAction { |
||||||
|
void update(JavaScriptImpl javaScript); |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
package com.fr.design.report.fit; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.form.fit.common.LightTool; |
||||||
|
import com.fr.form.main.BodyScaleAttrTransformer; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
import com.fr.form.ui.container.WBodyLayoutType; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
|
||||||
|
public enum FormFitAttrModelType { |
||||||
|
PLAIN_FORM_FIT_ATTR_MODEL { |
||||||
|
@Override |
||||||
|
public FitAttrModel getFitAttrModel() { |
||||||
|
return new FrmFitAttrModel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Item[] getFitLayoutScaleAttr() { |
||||||
|
return new Item[]{ |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN)}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Item[] getAbsoluteLayoutSaleAttr() { |
||||||
|
return new Item[]{ |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fit"), WAbsoluteLayout.STATE_FIT), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), WAbsoluteLayout.STATE_FIXED) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getScaleAttrShowIndex(WFitLayout wFitLayout) { |
||||||
|
int scale = wFitLayout.getScaleAttr(); |
||||||
|
if (wFitLayout.getBodyLayoutType() == WBodyLayoutType.FIT) { |
||||||
|
return BodyScaleAttrTransformer.getFitBodyCompStateFromScaleAttr(scale); |
||||||
|
} else { |
||||||
|
return BodyScaleAttrTransformer.getAbsoluteBodyCompStateFromScaleAttr(scale); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType) { |
||||||
|
if (wBodyLayoutType == WBodyLayoutType.FIT) { |
||||||
|
if (showIndex == 0) { |
||||||
|
return WFitLayout.SCALE_FULL; |
||||||
|
} else { |
||||||
|
return WFitLayout.SCALE_HOR; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (showIndex == 0) { |
||||||
|
return WFitLayout.SCALE_FULL; |
||||||
|
} else { |
||||||
|
return WFitLayout.SCALE_NO; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
}, |
||||||
|
NEW_FORM_FIT_ATTR_MODEL { |
||||||
|
@Override |
||||||
|
public FitAttrModel getFitAttrModel() { |
||||||
|
return new AdaptiveFrmFitAttrModel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Item[] getFitLayoutScaleAttr() { |
||||||
|
return new Item[]{ |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Item[] getAbsoluteLayoutSaleAttr() { |
||||||
|
return new Item[]{ |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN), |
||||||
|
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getScaleAttrShowIndex(WFitLayout wFitLayout) { |
||||||
|
int scale = wFitLayout.getScaleAttr(); |
||||||
|
if (scale == WFitLayout.SCALE_NO) { |
||||||
|
return 2; |
||||||
|
} else if (scale == WFitLayout.SCALE_HOR) { |
||||||
|
return 1; |
||||||
|
} else { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType) { |
||||||
|
if (showIndex == 0) { |
||||||
|
return WFitLayout.SCALE_FULL; |
||||||
|
} else if (showIndex == 1) { |
||||||
|
return WFitLayout.SCALE_HOR; |
||||||
|
} else { |
||||||
|
return WFitLayout.SCALE_NO; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
public abstract FitAttrModel getFitAttrModel(); |
||||||
|
|
||||||
|
public abstract Item[] getFitLayoutScaleAttr(); |
||||||
|
|
||||||
|
public abstract Item[] getAbsoluteLayoutSaleAttr(); |
||||||
|
|
||||||
|
public abstract int getScaleAttrShowIndex(WFitLayout wFitLayout); |
||||||
|
|
||||||
|
public abstract int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType); |
||||||
|
|
||||||
|
|
||||||
|
public static FormFitAttrModelType parse(Form form) { |
||||||
|
return LightTool.containNewFormFlag(form) ? NEW_FORM_FIT_ATTR_MODEL : PLAIN_FORM_FIT_ATTR_MODEL; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
package com.fr.design.report.fit; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
public class FormFitConfigPane extends ReportFitConfigPane { |
||||||
|
private static final int DEFAULT_ITEM = 0; |
||||||
|
private static final int CUSTOM_ITEM = 1; |
||||||
|
|
||||||
|
public FormFitConfigPane(FitAttrModel fitAttrModel) { |
||||||
|
this(fitAttrModel, false); |
||||||
|
} |
||||||
|
|
||||||
|
public FormFitConfigPane(FitAttrModel fitAttrModel, boolean globalConfig) { |
||||||
|
super(fitAttrModel, globalConfig); |
||||||
|
} |
||||||
|
|
||||||
|
protected JPanel initECConfigPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
if (fitAttrModel.getFitTypeNames().length != 0) { |
||||||
|
Component[] ecComponents = new Component[fitAttrModel.getFitTypeNames().length + 1]; |
||||||
|
initRadioGroup(ecConfigRadioGroup, fitAttrModel.getFitName(), fitAttrModel.getFitTypeNames(), ecComponents); |
||||||
|
jPanel.add(createSubAttrPane(ecComponents), BorderLayout.CENTER); |
||||||
|
jPanel.add(createTipPane(), BorderLayout.SOUTH); |
||||||
|
} |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createTipPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); |
||||||
|
UILabel label1 = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_FIT_Config_Tip1")); |
||||||
|
jPanel.add(label1); |
||||||
|
label1.setForeground(Color.lightGray); |
||||||
|
UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_FIT_Config_Tip2")); |
||||||
|
jPanel.add(label2); |
||||||
|
label2.setForeground(Color.lightGray); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
protected void refreshPreviewJPanel() { |
||||||
|
previewJPanel.refreshPreview(fontRadioGroup.isFontFit()); |
||||||
|
} |
||||||
|
|
||||||
|
protected void populateECConfigRadioGroup(int fitStateInPC) { |
||||||
|
ecConfigRadioGroup.selectIndexButton(fitStateInPC == 0 ? DEFAULT_ITEM : CUSTOM_ITEM); |
||||||
|
} |
||||||
|
|
||||||
|
protected void updateECConfigRadioGroup(ReportFitAttr reportFitAttr) { |
||||||
|
reportFitAttr.setFitStateInPC(ecConfigRadioGroup.getSelectRadioIndex()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
package com.fr.design.report.fit; |
||||||
|
|
||||||
|
import com.fr.base.GraphHelper; |
||||||
|
import com.fr.general.FRFont; |
||||||
|
|
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.FontMetrics; |
||||||
|
import java.awt.Graphics; |
||||||
|
|
||||||
|
|
||||||
|
public class NewFitPreviewPane extends JPanel { |
||||||
|
private boolean fitFont = false; |
||||||
|
private FitType fitType = FitType.DOUBLE_FIT; |
||||||
|
private static final Color DEFAULT_PAINT_COLOR = Color.decode("#419BF9"); |
||||||
|
private static final int FIT_FONT_SIZE = 15; |
||||||
|
private static final int NO_FIT_FONT_SIZE = 9; |
||||||
|
private static final Dimension NO_FIT_CONTAINER_DIMENSION = new Dimension(200, 136); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paint(Graphics g) { |
||||||
|
super.paint(g); |
||||||
|
g.setColor(Color.GRAY); |
||||||
|
GraphHelper.drawRect(g, 1, 1, this.getWidth() - 2, this.getHeight() - 2); |
||||||
|
g.setColor(DEFAULT_PAINT_COLOR); |
||||||
|
FRFont textFont = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, fitFont ? FIT_FONT_SIZE : NO_FIT_FONT_SIZE); |
||||||
|
g.setFont(textFont); |
||||||
|
Dimension dimension = calculateCellDimension(); |
||||||
|
GraphHelper.drawLine(g, 1, dimension.height, dimension.width * 2 - 1, dimension.height); |
||||||
|
GraphHelper.drawLine(g, dimension.width, 1, dimension.width, dimension.height * 2 - 1); |
||||||
|
GraphHelper.drawRect(g, 1, 1, dimension.width * 2 - 2, dimension.height * 2 - 2); |
||||||
|
double startX = calculateTextDrawStartX(dimension.width, this.getFontMetrics(textFont), "text1"); |
||||||
|
double startY = calculateTextDrawStartY(dimension.height); |
||||||
|
GraphHelper.drawString(g, "text1", startX, startY); |
||||||
|
GraphHelper.drawString(g, "text2", dimension.width + startX, startY); |
||||||
|
GraphHelper.drawString(g, "text3", startX, dimension.height + startY); |
||||||
|
GraphHelper.drawString(g, "text4", dimension.width + startX, dimension.height + startY); |
||||||
|
} |
||||||
|
|
||||||
|
private Dimension calculateCellDimension() { |
||||||
|
if (fitType == FitType.DOUBLE_FIT) { |
||||||
|
return new Dimension(this.getWidth() / 2, this.getHeight() / 2); |
||||||
|
} else if (fitType == FitType.NOT_FIT) { |
||||||
|
return new Dimension(NO_FIT_CONTAINER_DIMENSION.width / 2, NO_FIT_CONTAINER_DIMENSION.height / 2); |
||||||
|
} else { |
||||||
|
return new Dimension(this.getWidth() / 2, NO_FIT_CONTAINER_DIMENSION.height / 2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private double calculateTextDrawStartX(int containerWidth, FontMetrics fontMetrics, String text) { |
||||||
|
return (containerWidth - fontMetrics.stringWidth(text)) / 2.0D; |
||||||
|
} |
||||||
|
|
||||||
|
private double calculateTextDrawStartY(int containerHeight) { |
||||||
|
return containerHeight / 2.0D; |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshPreview(boolean fitFont, FitType fitType) { |
||||||
|
this.fitFont = fitFont; |
||||||
|
this.fitType = fitType; |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshPreview(boolean fitFont) { |
||||||
|
this.fitFont = fitFont; |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,172 @@ |
|||||||
|
package com.fr.design.report.fit; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIRadioButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.DesignSizeI18nManager; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.report.fit.menupane.FitRadioGroup; |
||||||
|
import com.fr.design.report.fit.menupane.FontRadioGroup; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
|
||||||
|
import static com.fr.design.i18n.Toolkit.i18nText; |
||||||
|
|
||||||
|
public class ReportFitConfigPane extends JPanel { |
||||||
|
public FontRadioGroup fontRadioGroup; |
||||||
|
public FitRadioGroup ecConfigRadioGroup; |
||||||
|
protected NewFitPreviewPane previewJPanel; |
||||||
|
protected FitAttrModel fitAttrModel; |
||||||
|
protected boolean globalConfig; |
||||||
|
|
||||||
|
|
||||||
|
public ReportFitConfigPane(FitAttrModel fitAttrModel, boolean globalConfig) { |
||||||
|
this.fitAttrModel = fitAttrModel; |
||||||
|
this.globalConfig = globalConfig; |
||||||
|
initComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponent() { |
||||||
|
JPanel contentJPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, FlowLayout.LEFT, 0, 0); |
||||||
|
this.add(contentJPanel); |
||||||
|
fontRadioGroup = new FontRadioGroup(); |
||||||
|
ecConfigRadioGroup = new FitRadioGroup(); |
||||||
|
contentJPanel.add(initAttrJPanel()); |
||||||
|
contentJPanel.add(initPreviewJPanel()); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initAttrJPanel() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
Component[] fontComponents = new Component[3]; |
||||||
|
initRadioGroup(fontRadioGroup, i18nText("Fine-Designer_Fit-Font"), new String[]{i18nText("Fine-Designer_Fit"), i18nText("Fine-Designer_Fit-No")}, fontComponents); |
||||||
|
jPanel.add(createSubAttrPane(fontComponents), BorderLayout.NORTH); |
||||||
|
jPanel.add(initECConfigPane(), BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
protected JPanel initECConfigPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
Component[] ecComponents = new Component[fitAttrModel.getFitTypeNames().length + 1]; |
||||||
|
initRadioGroup(ecConfigRadioGroup, fitAttrModel.getFitName(), fitAttrModel.getFitTypeNames(), ecComponents); |
||||||
|
jPanel.add(createSubAttrPane(ecComponents), BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected JPanel createSubAttrPane(Component[] components) { |
||||||
|
double[] rowSize = new double[]{20}; |
||||||
|
double[] columnSize = new double[components.length]; |
||||||
|
for (int i = 0; i < columnSize.length; i++) { |
||||||
|
if (i == 0) { |
||||||
|
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth(); |
||||||
|
} else { |
||||||
|
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.column").getWidth(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
JPanel attrJPanel = TableLayoutHelper.createTableLayoutPane(new Component[][]{components}, rowSize, columnSize); |
||||||
|
attrJPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); |
||||||
|
return attrJPanel; |
||||||
|
} |
||||||
|
|
||||||
|
protected void initRadioGroup(FitRadioGroup fitRadioGroup, String name, String[] options, Component[] components) { |
||||||
|
components[0] = new UILabel(name); |
||||||
|
for (int i = 0; i < options.length; i++) { |
||||||
|
|
||||||
|
if (options[i] != null) { |
||||||
|
UIRadioButton fontFitRadio = new UIRadioButton(options[i]); |
||||||
|
fitRadioGroup.add(fontFitRadio); |
||||||
|
components[i + 1] = fontFitRadio; |
||||||
|
} else { |
||||||
|
components[i + 1] = null; |
||||||
|
} |
||||||
|
} |
||||||
|
fitRadioGroup.addActionListener(getPreviewActionListener()); |
||||||
|
} |
||||||
|
|
||||||
|
private ActionListener getPreviewActionListener() { |
||||||
|
return new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
refreshPreviewJPanel(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshPreviewJPanel(FitType fitType) { |
||||||
|
previewJPanel.refreshPreview(fontRadioGroup.isFontFit(), fitType); |
||||||
|
} |
||||||
|
|
||||||
|
protected void refreshPreviewJPanel() { |
||||||
|
previewJPanel.refreshPreview(fontRadioGroup.isFontFit(), FitType.parse(updateBean())); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initPreviewJPanel() { |
||||||
|
JPanel wrapperPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
previewJPanel = new NewFitPreviewPane(); |
||||||
|
wrapperPane.add(previewJPanel, BorderLayout.CENTER); |
||||||
|
int leftIndent = globalConfig ? (int) DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth() : 0; |
||||||
|
wrapperPane.setBorder(BorderFactory.createEmptyBorder(0, leftIndent, 0, 0)); |
||||||
|
wrapperPane.setPreferredSize(new Dimension(300 + leftIndent, 204)); |
||||||
|
return wrapperPane; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void populateBean(ReportFitAttr ob) { |
||||||
|
fontRadioGroup.selectIndexButton(ob.isFitFont() ? 0 : 1); |
||||||
|
populateECConfigRadioGroup(ob.fitStateInPC()); |
||||||
|
refreshPreviewJPanel(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void populateECConfigRadioGroup(int fitStateInPC){ |
||||||
|
ecConfigRadioGroup.selectIndexButton(getOptionIndex(fitStateInPC)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void updateECConfigRadioGroup(ReportFitAttr reportFitAttr){ |
||||||
|
reportFitAttr.setFitStateInPC(getStateInPC(ecConfigRadioGroup.getSelectRadioIndex())); |
||||||
|
} |
||||||
|
|
||||||
|
public ReportFitAttr updateBean() { |
||||||
|
ReportFitAttr reportFitAttr = new ReportFitAttr(); |
||||||
|
reportFitAttr.setFitFont(fontRadioGroup.isFontFit()); |
||||||
|
updateECConfigRadioGroup(reportFitAttr); |
||||||
|
return reportFitAttr; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected int getStateInPC(int index) { |
||||||
|
FitType[] fitTypes = fitAttrModel.getFitTypes(); |
||||||
|
if (index > fitTypes.length - 1) { |
||||||
|
return index; |
||||||
|
} |
||||||
|
return fitTypes[index].getState(); |
||||||
|
} |
||||||
|
|
||||||
|
protected int getOptionIndex(int state) { |
||||||
|
FitType[] fitTypes = fitAttrModel.getFitTypes(); |
||||||
|
for (int i = 0; i < fitTypes.length; i++) { |
||||||
|
if (ComparatorUtils.equals(state, fitTypes[i].getState())) { |
||||||
|
return i; |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
super.setEnabled(enabled); |
||||||
|
fontRadioGroup.setEnabled(enabled); |
||||||
|
ecConfigRadioGroup.setEnabled(enabled); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
{ |
||||||
|
"Fine-Design_JSAPI_Public_Module": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Universal": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_FR": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_FS": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Mobile": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget_Get": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget_Universal": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Button_Widget_Peculiar": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Combobox_Widget_Peculiar": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Marquee": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Scrollbar": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Style": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Row_Height_Col_Width": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Value": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Radius": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Page": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Page_Jump": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Page_Number_Get": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Export": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Cpt": { |
||||||
|
"Fine-Design_JSAPI_Cpt_Page_Preview": { |
||||||
|
"Fine-Design_JSAPI_Cpt_Page_Preview_Folding_Tree": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Cpt_Write_Preview": {}, |
||||||
|
"Fine-Design_JSAPI_Cpt_View_Preview": { |
||||||
|
"Fine-Design_JSAPI_Cpt_View_Preview_Report_Location": {} |
||||||
|
} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Form": { |
||||||
|
"Fine-Design_JSAPI_Form_Component_Get": {}, |
||||||
|
"Fine-Design_JSAPI_Form_Component_Universal": {}, |
||||||
|
"Fine-Design_JSAPI_Form_Component_Tab": {} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
{ |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Universal": ["_g()", "getParameterContainer", "parameterCommit", "loadContentPane", "getPreviewType"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_FR": [ "servletURL", "serverURL", "server", "fineServletURL", "SessionMgr.getSessionID", "showDialog", "closeDialog", |
||||||
|
"doHyperlinkByGet", "doHyperlinkByPost", "doURLPrint", "Msg", "remoteEvaluate", "jsonEncode", "jsonDecode", |
||||||
|
"ajax", "isEmpty", "isArray", "cellStr2ColumnRow", "columnRow2CellStr"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_FS": ["signOut", "tabPane.closeActiveTab", "tabPane.addItem"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Mobile": ["location", "Mobile.getDeviceInfo"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget_Get": ["this", "this.options.form", "getWidgetByName"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget_Universal": ["getValue", "getText", "setValue", "visible", "invisible", "setVisible", "isVisible", "setEnable", "isEnabled", |
||||||
|
"reset", "getType", "setWaterMark", "fireEvent", "setPopupStyle"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar":["setMaxAndMinDate"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Button_Widget_Peculiar":["doClick"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Combobox_Widget_Peculiar":["setName4Empty"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Marquee":["startMarquee", "stopMarquee"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Scrollbar":["setHScrollBarVisible", "setVScrollBarVisible"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Style":["addEffect"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Row_Height_Col_Width":["setRowHeight", "setColWidth"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Value":["getCellValue", "setCellValue"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Table_Cell_Radius":["setCellRadius"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar":["toolBarFloat", "setStyle","getToolbar"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button":["changeFormat"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Page_Jump":["gotoPreviousPage", "gotoNextPage", "gotoLastPage", "gotoFirstPage", "gotoPage"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Page_Number_Get":["getCurrentPageIndex", "getReportTotalPage", "currentPageIndex", "reportTotalPage"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Report_Export":["exportReportToExcel", "exportReportToImage", "exportReportToPDF", "exportReportToWord"], |
||||||
|
"Fine-Design_JSAPI_Cpt_Page_Preview_Folding_Tree":["expandNodeLayer", "collapseNodeLayer", "expandAllNodeLayer", "collapseAllNodeLayer"], |
||||||
|
"Fine-Design_JSAPI_Cpt_Write_Preview":["getWidgetByCell", "appendReportRC", "appendReportRow", |
||||||
|
"deleteReportRC", "deleteRows", "refreshAllSheets", "loadSheetByIndex", "loadSheetByName", "isDirtyPage", |
||||||
|
"isAutoStash", "writeReport", "verifyAndWriteReport", "verifyReport", "importExcel", "importExcel_Clean", |
||||||
|
"importExcel_Append", "importExcel_Cover", "stash", "clear"], |
||||||
|
"Fine-Design_JSAPI_Cpt_View_Preview_Report_Location":["centerReport"], |
||||||
|
"Fine-Design_JSAPI_Form_Component_Get":["getAllWidgets"], |
||||||
|
"Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "showCardByIndex", "getShowIndex", "setTitleVisible"] |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package com.fr.design.javascript.jsapi; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import javax.swing.tree.DefaultMutableTreeNode; |
||||||
|
import junit.framework.TestCase; |
||||||
|
|
||||||
|
public class JSAPITreeHelperTest extends TestCase { |
||||||
|
public void testGetName(){ |
||||||
|
List<String> names = JSAPITreeHelper.getNames("Fine-Design_JSAPI_Public_Module_Toolbar"); |
||||||
|
assertEquals(names.size(),4); |
||||||
|
assertTrue(names.contains( "toolBarFloat")); |
||||||
|
assertTrue(names.contains( "setStyle")); |
||||||
|
assertTrue(names.contains( "getToolbar")); |
||||||
|
assertTrue(names.contains( "changeFormat")); |
||||||
|
List<String> allNames = JSAPITreeHelper.getAllNames(); |
||||||
|
assertEquals(allNames.size(),16); |
||||||
|
} |
||||||
|
|
||||||
|
public void testGetDirectCategory(){ |
||||||
|
String directCategory = JSAPITreeHelper.getDirectCategory("_g()"); |
||||||
|
assertEquals(directCategory,"Fine-Design_JSAPI_Public_Module_Global_Universal"); |
||||||
|
directCategory = JSAPITreeHelper.getDirectCategory("showCardByIndex"); |
||||||
|
assertEquals(directCategory,"Fine-Design_JSAPI_Form_Component_Tab"); |
||||||
|
} |
||||||
|
|
||||||
|
public void testCreateJSAPITree(){ |
||||||
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(); |
||||||
|
JSAPITreeHelper.createJSAPITree(rootNode); |
||||||
|
assertEquals(2,rootNode.getChildCount()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
{ |
||||||
|
"Fine-Design_JSAPI_Public_Module": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Universal": {}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Mobile": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Widget": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar": {} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar": { |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button": {} |
||||||
|
} |
||||||
|
}, |
||||||
|
"Fine-Design_JSAPI_Form": { |
||||||
|
"Fine-Design_JSAPI_Form_Component_Tab": {} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
{ |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Universal": ["_g()", "getParameterContainer", "parameterCommit", "loadContentPane", "getPreviewType"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Global_Mobile": ["location", "Mobile.getDeviceInfo"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar":["setMaxAndMinDate"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar":["toolBarFloat", "setStyle","getToolbar"], |
||||||
|
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button":["changeFormat"], |
||||||
|
"Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "showCardByIndex", "getShowIndex", "setTitleVisible"] |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.design.actions.JTemplateAction; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.design.report.fit.FormFitAttrModelType; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.report.fit.FitProvider; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
public class FormFitAttrAction extends JTemplateAction { |
||||||
|
private static final MenuKeySet REPORT_FIT_ATTR = new MenuKeySet() { |
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
return 'T'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
return Toolkit.i18nText("Fine-Designer_PC_Fit_Attr"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public FormFitAttrAction(JTemplate jTemplate) { |
||||||
|
super(jTemplate); |
||||||
|
initMenuStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initMenuStyle() { |
||||||
|
this.setMenuKeySet(REPORT_FIT_ATTR); |
||||||
|
this.setName(getMenuKeySet().getMenuKeySetName() + "..."); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon("/com/fr/design/images/reportfit/fit"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Action触发事件 |
||||||
|
* |
||||||
|
* @param e 事件 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
final JTemplate jwb = getEditingComponent(); |
||||||
|
if (jwb == null || !(jwb.getTarget() instanceof Form)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
JForm jForm = (JForm) jwb; |
||||||
|
Form wbTpl = jForm.getTarget(); |
||||||
|
ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); |
||||||
|
FormFitAttrPane formFitAttrPane = new FormFitAttrPane(jForm, FormFitAttrModelType.parse(wbTpl)); |
||||||
|
showReportFitDialog(fitAttr, jwb, wbTpl, formFitAttrPane); |
||||||
|
} |
||||||
|
|
||||||
|
private void showReportFitDialog(ReportFitAttr fitAttr, final JTemplate jwb, final FitProvider wbTpl, final BasicBeanPane<ReportFitAttr> attrPane) { |
||||||
|
attrPane.populateBean(fitAttr); |
||||||
|
UIDialog dialog = attrPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
fireEditingOk(jwb, wbTpl, attrPane.updateBean(), fitAttr); |
||||||
|
} |
||||||
|
}, new Dimension(660, 600)); |
||||||
|
dialog.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void fireEditingOk(final JTemplate jwb, final FitProvider wbTpl, ReportFitAttr newReportFitAttr, ReportFitAttr oldReportFitAttr) { |
||||||
|
wbTpl.setReportFitAttr(newReportFitAttr); |
||||||
|
jwb.fireTargetModified(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,377 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.design.designer.creator.XOccupiedLayout; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWFitLayout; |
||||||
|
import com.fr.design.designer.creator.XWScaleLayout; |
||||||
|
import com.fr.design.designer.properties.items.FRLayoutTypeItems; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.dialog.FineJOptionPane; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.FormSelectionUtils; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.design.report.fit.FitType; |
||||||
|
import com.fr.design.report.fit.FormFitAttrModelType; |
||||||
|
import com.fr.design.report.fit.FormFitConfigPane; |
||||||
|
import com.fr.design.report.fit.ReportFitConfigPane; |
||||||
|
import com.fr.design.widget.FRWidgetFactory; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.form.ui.container.WAbsoluteBodyLayout; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
import com.fr.form.ui.container.WBodyLayoutType; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
import com.fr.form.ui.container.WSortLayout; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.act.BorderPacker; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultComboBoxModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
|
||||||
|
import static com.fr.design.i18n.Toolkit.i18nText; |
||||||
|
import static javax.swing.JOptionPane.*; |
||||||
|
|
||||||
|
public class FormFitAttrPane extends BasicBeanPane<ReportFitAttr> { |
||||||
|
|
||||||
|
private UIComboBox layoutComboBox; |
||||||
|
private UIComboBox scaleComboBox; |
||||||
|
private FormFitAttrModelType fitAttrModelType; |
||||||
|
|
||||||
|
protected UIComboBox itemChoose; |
||||||
|
|
||||||
|
private JForm jForm; |
||||||
|
private ReportFitConfigPane fitConfigPane; |
||||||
|
|
||||||
|
public FormFitAttrPane(JForm jForm, FormFitAttrModelType fitAttrModelType) { |
||||||
|
this.fitAttrModelType = fitAttrModelType; |
||||||
|
this.jForm = jForm; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(12, 5, 0, 5)); |
||||||
|
this.add(createReportFitSettingPane(), BorderLayout.CENTER); |
||||||
|
this.add(createReportLayoutSettingPane(), BorderLayout.NORTH); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private JPanel createReportLayoutSettingPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Layout")); |
||||||
|
jPanel.add(createAreaScalePane(), BorderLayout.CENTER); |
||||||
|
jPanel.setPreferredSize(new Dimension(640, 84)); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
protected String[] getItemNames() { |
||||||
|
return new String[]{Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single")}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private JPanel createReportFitSettingPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Content_Attr")); |
||||||
|
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
jPanel.add(contentPane, BorderLayout.CENTER); |
||||||
|
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Settings")); |
||||||
|
label.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); |
||||||
|
contentPane.add(label, BorderLayout.WEST); |
||||||
|
label.setPreferredSize(new Dimension(100, 0)); |
||||||
|
label.setVerticalAlignment(SwingConstants.TOP); |
||||||
|
itemChoose = new UIComboBox(getItemNames()); |
||||||
|
itemChoose.setPreferredSize(new Dimension(160, 20)); |
||||||
|
Form form = jForm.getTarget(); |
||||||
|
itemChoose.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
if (e.getStateChange() == ItemEvent.SELECTED) { |
||||||
|
if (isTemplateSingleSet()) { |
||||||
|
if (form != null) { |
||||||
|
ReportFitAttr fitAttr = form.getReportFitAttr(); |
||||||
|
populate(fitAttr); |
||||||
|
} |
||||||
|
} else { |
||||||
|
populate(fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
JPanel centerPane = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); |
||||||
|
centerPane.add(itemChoose); |
||||||
|
centerPane.add(fitConfigPane = new FormFitConfigPane(this.fitAttrModelType.getFitAttrModel())); |
||||||
|
contentPane.add(centerPane, BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(ReportFitAttr reportFitAttr) { |
||||||
|
if (reportFitAttr == null) { |
||||||
|
reportFitAttr = fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr(); |
||||||
|
} |
||||||
|
|
||||||
|
this.setEnabled(isTemplateSingleSet()); |
||||||
|
fitConfigPane.populateBean(reportFitAttr); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public ReportFitAttr updateBean() { |
||||||
|
updateLayoutType(); |
||||||
|
if (!isTemplateSingleSet()) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
return fitConfigPane.updateBean(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void updateLayoutType() { |
||||||
|
XLayoutContainer xLayoutContainer = this.jForm.getRootComponent(); |
||||||
|
if (xLayoutContainer == null || !xLayoutContainer.acceptType(XWFitLayout.class)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
XWFitLayout xwFitLayout = (XWFitLayout) xLayoutContainer; |
||||||
|
WFitLayout wFitLayout = xwFitLayout.toData(); |
||||||
|
int state = layoutComboBox.getSelectedIndex(); |
||||||
|
WBodyLayoutType selectType = WBodyLayoutType.parse(state); |
||||||
|
if (selectType != wFitLayout.getBodyLayoutType()) { |
||||||
|
wFitLayout.setLayoutType(selectType); |
||||||
|
//从自适应布局切换到绝对布局
|
||||||
|
if (selectType == WBodyLayoutType.ABSOLUTE) { |
||||||
|
switchLayoutFromFit2Absolute(xwFitLayout); |
||||||
|
} else { |
||||||
|
//从绝对布局切换到自适应布局
|
||||||
|
switchLayoutFromAbsolute2Fit(xwFitLayout); |
||||||
|
} |
||||||
|
} |
||||||
|
wFitLayout.setCompatibleScaleAttr(fitAttrModelType.parseScaleAttrFromShowIndex(this.scaleComboBox.getSelectedIndex(), wFitLayout.getBodyLayoutType())); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void switchLayoutFromFit2Absolute(XWFitLayout xWFitLayout) { |
||||||
|
try { |
||||||
|
WFitLayout layout = xWFitLayout.toData(); |
||||||
|
WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body"); |
||||||
|
wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED); |
||||||
|
// 切换布局类型时,保留body背景样式
|
||||||
|
wAbsoluteBodyLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); |
||||||
|
wAbsoluteBodyLayout.setBorderStyle((BorderPacker) (layout.getBorderStyle().clone())); |
||||||
|
Component[] components = xWFitLayout.getComponents(); |
||||||
|
Rectangle[] backupBounds = getBackupBoundsFromFitLayout(xWFitLayout); |
||||||
|
xWFitLayout.removeAll(); |
||||||
|
layout.resetStyle(); |
||||||
|
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent(); |
||||||
|
xWFitLayout.setFixLayout(false); |
||||||
|
xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0); |
||||||
|
for (int i = 0; i < components.length; i++) { |
||||||
|
XCreator xCreator = (XCreator) components[i]; |
||||||
|
xCreator.setBounds(backupBounds[i]); |
||||||
|
//部分控件被ScaleLayout包裹着,绝对布局里面要放出来
|
||||||
|
if (xCreator.acceptType(XWScaleLayout.class)) { |
||||||
|
if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { |
||||||
|
Component component = xCreator.getComponent(0); |
||||||
|
component.setBounds(xCreator.getBounds()); |
||||||
|
} |
||||||
|
} |
||||||
|
if (!xCreator.acceptType(XOccupiedLayout.class)) { |
||||||
|
xwAbsoluteBodyLayout.add(xCreator); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
copyLayoutAttr(layout, xwAbsoluteBodyLayout.toData()); |
||||||
|
xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); |
||||||
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
formDesigner.getSelectionModel().setSelectedCreators( |
||||||
|
FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); |
||||||
|
if (xwAbsoluteBodyLayout.toData() != null) { |
||||||
|
xwAbsoluteBodyLayout.toData().setBorderStyleFollowingTheme(wAbsoluteBodyLayout.isBorderStyleFollowingTheme()); |
||||||
|
xwAbsoluteBodyLayout.toData().setBorderStyle(wAbsoluteBodyLayout.getBorderStyle()); |
||||||
|
} |
||||||
|
xwAbsoluteBodyLayout.refreshStylePreviewEffect(); |
||||||
|
if (xWFitLayout.toData() != null) { |
||||||
|
xWFitLayout.toData().resetStyle(); |
||||||
|
} |
||||||
|
xWFitLayout.refreshStylePreviewEffect(); |
||||||
|
formDesigner.switchBodyLayout(xwAbsoluteBodyLayout); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Rectangle[] getBackupBoundsFromFitLayout(XWFitLayout xWFitLayout) { |
||||||
|
int count = xWFitLayout.getComponentCount(); |
||||||
|
Rectangle[] rectangles = new Rectangle[count]; |
||||||
|
for (int i = 0; i < count; i++) { |
||||||
|
rectangles[i] = xWFitLayout.getComponent(i).getBounds(); |
||||||
|
} |
||||||
|
return rectangles; |
||||||
|
} |
||||||
|
|
||||||
|
protected void copyLayoutAttr(WSortLayout srcLayout, WSortLayout destLayout) { |
||||||
|
destLayout.clearListeners(); |
||||||
|
destLayout.clearMobileWidgetList(); |
||||||
|
for (int i = 0, len = srcLayout.getMobileWidgetListSize(); i < len; i++) { |
||||||
|
destLayout.addMobileWidget(srcLayout.getMobileWidget(i)); |
||||||
|
} |
||||||
|
destLayout.setSorted(true); |
||||||
|
for (int i = 0, len = srcLayout.getListenerSize(); i < len; i++) { |
||||||
|
destLayout.addListener(srcLayout.getListener(i)); |
||||||
|
} |
||||||
|
srcLayout.clearListeners(); |
||||||
|
srcLayout.clearMobileWidgetList(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void switchLayoutFromAbsolute2Fit(XWFitLayout xwFitLayout) { |
||||||
|
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = getAbsoluteBodyLayout(xwFitLayout); |
||||||
|
if (xwAbsoluteBodyLayout == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
WAbsoluteBodyLayout layout = xwAbsoluteBodyLayout.toData(); |
||||||
|
WFitLayout wFitLayout = xwFitLayout.toData(); |
||||||
|
wFitLayout.resetStyle(); |
||||||
|
xwFitLayout.switch2FitBodyLayout(xwAbsoluteBodyLayout); |
||||||
|
// 切换布局类型时,保留body背景样式
|
||||||
|
if (wFitLayout != null) { |
||||||
|
wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); |
||||||
|
wFitLayout.setBorderStyle(layout.getBorderStyle()); |
||||||
|
} |
||||||
|
copyLayoutAttr(layout, xwFitLayout.toData()); |
||||||
|
|
||||||
|
copyLayoutAttr(layout, xwFitLayout.toData()); |
||||||
|
xwFitLayout.refreshStylePreviewEffect(); |
||||||
|
} |
||||||
|
|
||||||
|
private XWAbsoluteBodyLayout getAbsoluteBodyLayout(XWFitLayout xwFitLayout) { |
||||||
|
if (xwFitLayout != null && xwFitLayout.getComponentCount() > 0) { |
||||||
|
Component component = xwFitLayout.getComponent(0); |
||||||
|
if (component instanceof XWAbsoluteBodyLayout) { |
||||||
|
return (XWAbsoluteBodyLayout) component; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createAreaScalePane() { |
||||||
|
initLayoutComboBox(); |
||||||
|
|
||||||
|
UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); |
||||||
|
UILabel scaleModeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Scale_Setting")); |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
{layoutTypeLabel, layoutComboBox}, |
||||||
|
{scaleModeLabel, scaleComboBox} |
||||||
|
}; |
||||||
|
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components, |
||||||
|
TableLayoutHelper.FILL_LASTCOLUMN, 20, IntervalConstants.INTERVAL_L1); |
||||||
|
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
containerPane.add(contentPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
return containerPane; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void initLayoutComboBox() { |
||||||
|
Item[] items = FRLayoutTypeItems.ITEMS; |
||||||
|
DefaultComboBoxModel model = new DefaultComboBoxModel(); |
||||||
|
for (Item item : items) { |
||||||
|
model.addElement(item); |
||||||
|
} |
||||||
|
scaleComboBox = new UIComboBox(model); |
||||||
|
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getFitLayoutScaleAttr())); |
||||||
|
layoutComboBox = new UIComboBox(model); |
||||||
|
layoutComboBox.setPreferredSize(new Dimension(160, 20)); |
||||||
|
scaleComboBox.setPreferredSize(new Dimension(160, 20)); |
||||||
|
WFitLayout wFitLayout = jForm.getTarget().getWFitLayout(); |
||||||
|
layoutComboBox.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
int selectIndex = layoutComboBox.getSelectedIndex(); |
||||||
|
if (selectIndex == 0) { |
||||||
|
if (wFitLayout.getBodyLayoutType() == WBodyLayoutType.ABSOLUTE) { |
||||||
|
int selVal = FineJOptionPane.showConfirmDialog( |
||||||
|
FormFitAttrPane.this, |
||||||
|
Toolkit.i18nText("Fine-Design_Form_Layout_Switch_Tip"), |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Alert"), |
||||||
|
OK_CANCEL_OPTION, |
||||||
|
WARNING_MESSAGE |
||||||
|
); |
||||||
|
if (OK_OPTION != selVal) { |
||||||
|
layoutComboBox.setSelectedIndex(1); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getFitLayoutScaleAttr())); |
||||||
|
} else { |
||||||
|
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getAbsoluteLayoutSaleAttr())); |
||||||
|
} |
||||||
|
scaleComboBox.setSelectedIndex(0); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
scaleComboBox.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
WBodyLayoutType selectBodyType = WBodyLayoutType.parse(layoutComboBox.getSelectedIndex()); |
||||||
|
int state = fitAttrModelType.parseScaleAttrFromShowIndex(scaleComboBox.getSelectedIndex(), selectBodyType); |
||||||
|
fitConfigPane.refreshPreviewJPanel(FitType.parseByFitState(state)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(ReportFitAttr reportFitAttr) { |
||||||
|
WFitLayout wFitLayout = jForm.getTarget().getWFitLayout(); |
||||||
|
layoutComboBox.setSelectedIndex(wFitLayout.getBodyLayoutType().getTypeValue()); |
||||||
|
scaleComboBox.setSelectedIndex(fitAttrModelType.getScaleAttrShowIndex(wFitLayout)); |
||||||
|
|
||||||
|
if (reportFitAttr == null) { |
||||||
|
itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings")); |
||||||
|
} else { |
||||||
|
itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single")); |
||||||
|
} |
||||||
|
if (reportFitAttr == null) { |
||||||
|
reportFitAttr = fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr(); |
||||||
|
} |
||||||
|
setEnabled(isTemplateSingleSet()); |
||||||
|
fitConfigPane.populateBean(reportFitAttr); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isTemplateSingleSet() { |
||||||
|
return ComparatorUtils.equals(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single"), itemChoose.getSelectedItem()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
super.setEnabled(enabled); |
||||||
|
fitConfigPane.setEnabled(enabled); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return i18nText("Fine-Designer_PC_Fit_Attr"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.design.sort.celldscolumn; |
||||||
|
|
||||||
|
import com.fr.design.data.DesignTableDataManager; |
||||||
|
import com.fr.design.data.tabledata.wrapper.TableDataWrapper; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.sort.common.AbstractSortGroupPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortItemPane; |
||||||
|
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
|
||||||
|
public class CellDSColumnSortGroupPane extends AbstractSortGroupPane { |
||||||
|
DSColumn dsColumn; |
||||||
|
|
||||||
|
public CellDSColumnSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) { |
||||||
|
super(sortGroupPaneWidth, sortGroupPaneRightWidth); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateDsColumn(DSColumn dsColumn) { |
||||||
|
this.dsColumn = dsColumn; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression) { |
||||||
|
CellDSColumnSortItemPane cellDSColumnSortItemPane = new CellDSColumnSortItemPane(sortItemPaneWidth, sortItemPaneRightWidth); |
||||||
|
java.util.Map<String, TableDataWrapper> tableDataWrapperMap = |
||||||
|
DesignTableDataManager.getAllEditingDataSet(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTarget()); |
||||||
|
TableDataWrapper tableDataWrapper = tableDataWrapperMap.get(dsColumn.getDSName()); |
||||||
|
if (tableDataWrapper != null) { |
||||||
|
java.util.List<String> columnNameList = tableDataWrapper.calculateColumnNameList(); |
||||||
|
String[] columnNames = new String[columnNameList.size()]; |
||||||
|
columnNameList.toArray(columnNames); |
||||||
|
cellDSColumnSortItemPane.sortAreaUiComboBox.removeAllItems(); |
||||||
|
for (String columnName : columnNames) { |
||||||
|
cellDSColumnSortItemPane.sortAreaUiComboBox.addItem(columnName); |
||||||
|
} |
||||||
|
} |
||||||
|
cellDSColumnSortItemPane.populateBean(sortExpression); |
||||||
|
return cellDSColumnSortItemPane; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.design.sort.celldscolumn; |
||||||
|
|
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.sort.common.AbstractSortItemPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
|
||||||
|
public class CellDSColumnSortItemPane extends AbstractSortItemPane { |
||||||
|
|
||||||
|
UIComboBox sortAreaUiComboBox; |
||||||
|
|
||||||
|
public CellDSColumnSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) { |
||||||
|
super(sortItemPaneWidth, sortItemPaneRightWidth); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initMainSortAreaPane(JPanel sortAreaPane) { |
||||||
|
sortAreaUiComboBox = new UIComboBox(new String[0]); |
||||||
|
sortAreaUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
sortAreaPane.add(sortAreaUiComboBox); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortExpression sortExpression) { |
||||||
|
sortAreaUiComboBox.setSelectedItem(sortExpression.getSortArea()); |
||||||
|
super.populateBean(sortExpression); |
||||||
|
} |
||||||
|
|
||||||
|
public SortExpression updateBean() { |
||||||
|
SortExpression sortExpression = super.updateBean(); |
||||||
|
if (sortExpression != null && sortAreaUiComboBox.getSelectedItem() != null) { |
||||||
|
sortExpression.setSortArea(sortAreaUiComboBox.getSelectedItem().toString()); |
||||||
|
} |
||||||
|
return sortExpression; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.fr.design.sort.celldscolumn; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.general.data.TableDataColumn; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||||
|
import com.fr.report.core.sort.common.CellSortAttr; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
|
||||||
|
public class CellDSColumnSortPane extends AbstractSortPane { |
||||||
|
|
||||||
|
public CellDSColumnSortPane() { |
||||||
|
super(220, 150); |
||||||
|
//this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initSortGroupPane() { |
||||||
|
sortGroupPane = new CellDSColumnSortGroupPane(sortPaneWidth, sortPaneRightWidth); |
||||||
|
this.add(sortGroupPane); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected CellSortAttr getCellSortAttr(TemplateCellElement cellElement) { |
||||||
|
if (cellElement.getValue() instanceof DSColumn) { |
||||||
|
DSColumn dsColumn = ((DSColumn) cellElement.getValue()); |
||||||
|
if (dsColumn.getCellSortAttr() == null) { |
||||||
|
dsColumn.setCellSortAttr(new CellSortAttr()); |
||||||
|
} |
||||||
|
return dsColumn.getCellSortAttr(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
protected void populateSortArea(TemplateCellElement cellElement) { |
||||||
|
super.populateSortArea(cellElement); |
||||||
|
if (cellElement.getValue() instanceof DSColumn) { |
||||||
|
DSColumn dsColumn = ((DSColumn) cellElement.getValue()); |
||||||
|
TableDataColumn tableDataColumn = dsColumn.getColumn(); |
||||||
|
if (tableDataColumn instanceof TableDataColumn) { |
||||||
|
selfSortArea = TableDataColumn.getColumnName(tableDataColumn); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(TemplateCellElement cellElement) { |
||||||
|
if (cellElement.getValue() instanceof DSColumn) { |
||||||
|
DSColumn dsColumn = ((DSColumn) cellElement.getValue()); |
||||||
|
if (sortGroupPane != null) { |
||||||
|
((CellDSColumnSortGroupPane) sortGroupPane).populateDsColumn(dsColumn); |
||||||
|
} |
||||||
|
} |
||||||
|
super.populateBean(cellElement); |
||||||
|
} |
||||||
|
|
||||||
|
protected boolean needSortHeaderPane() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.fr.design.sort.cellexpand; |
||||||
|
|
||||||
|
import com.fr.design.sort.common.AbstractSortGroupPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortItemPane; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
|
||||||
|
public class CellExpandSortGroupPane extends AbstractSortGroupPane { |
||||||
|
|
||||||
|
public CellExpandSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) { |
||||||
|
super(sortGroupPaneWidth, sortGroupPaneRightWidth); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression) { |
||||||
|
AbstractSortItemPane abstractSortItemPane = new CellExpandSortItemPane( sortItemPaneWidth, sortItemPaneRightWidth); |
||||||
|
abstractSortItemPane.populateBean(sortExpression); |
||||||
|
return abstractSortItemPane; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.design.sort.cellexpand; |
||||||
|
|
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.design.sort.common.SortColumnRowPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortItemPane; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
import com.fr.stable.ColumnRow; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
public class CellExpandSortItemPane extends AbstractSortItemPane { |
||||||
|
SortColumnRowPane columnRowPane; |
||||||
|
|
||||||
|
public CellExpandSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) { |
||||||
|
super(sortItemPaneWidth, sortItemPaneRightWidth); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initMainSortAreaPane(JPanel sortAreaPane) { |
||||||
|
columnRowPane = new SortColumnRowPane(sortItemPaneRightWidth + 4, AbstractSortPane.PANE_COMPONENT_HEIGHT); |
||||||
|
sortAreaPane.add(columnRowPane); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortExpression sortExpression) { |
||||||
|
columnRowPane.populateBean(ColumnRow.valueOf(sortExpression.getSortArea())); |
||||||
|
super.populateBean(sortExpression); |
||||||
|
} |
||||||
|
|
||||||
|
public SortExpression updateBean() { |
||||||
|
SortExpression sortExpression = super.updateBean(); |
||||||
|
if (sortExpression != null) { |
||||||
|
ColumnRow columnRow = columnRowPane.updateBean(); |
||||||
|
sortExpression.setSortArea(columnRow == null ? null : columnRow.toString()); |
||||||
|
} |
||||||
|
return sortExpression; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.fr.design.sort.cellexpand; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.design.mainframe.cell.settingpane.CellExpandAttrPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.cell.cellattr.CellExpandAttr; |
||||||
|
import com.fr.report.core.sort.common.CellSortAttr; |
||||||
|
|
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
public class CellExpandSortPane extends AbstractSortPane { |
||||||
|
CellExpandAttrPane cellExpandAttrPane; |
||||||
|
|
||||||
|
public CellExpandSortPane(CellExpandAttrPane cellExpandAttrPane) { |
||||||
|
super(227, 155); |
||||||
|
this.cellExpandAttrPane = cellExpandAttrPane; |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initSortGroupPane() { |
||||||
|
sortGroupPane = new CellExpandSortGroupPane(sortPaneWidth, sortPaneRightWidth); |
||||||
|
this.add(sortGroupPane); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected CellSortAttr getCellSortAttr(TemplateCellElement cellElement) { |
||||||
|
CellExpandAttr cellExpandAttr = cellElement.getCellExpandAttr(); |
||||||
|
if (cellExpandAttr != null) { |
||||||
|
if (cellExpandAttr.getCellSortAttr() == null) { |
||||||
|
cellExpandAttr.setCellSortAttr(new CellSortAttr()); |
||||||
|
} |
||||||
|
return cellExpandAttr.getCellSortAttr(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,152 @@ |
|||||||
|
package com.fr.design.sort.common; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.event.ComponentChangeListener; |
||||||
|
import com.fr.design.event.ComponentChangeObserver; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.report.core.sort.sortexpression.CellSortExpression; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractSortGroupPane extends JPanel implements ComponentChangeObserver { |
||||||
|
|
||||||
|
private static final int SECOND_SORT_LENGTH_REDUCTION = 13; |
||||||
|
|
||||||
|
protected int sortGroupPaneWidth; |
||||||
|
protected int sortGroupPaneRightWidth; |
||||||
|
List<SortExpression> sortExpressions; |
||||||
|
List<SortUIExpandablePane> sortUIExpandablePanes = new ArrayList<>(); |
||||||
|
AddSortItemBar addSortItemBar; |
||||||
|
JPanel sortItemListPane; |
||||||
|
UIButton uiButton; |
||||||
|
String selfSortArea; |
||||||
|
|
||||||
|
ComponentChangeListener componentChangeListener; |
||||||
|
|
||||||
|
public AbstractSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) { |
||||||
|
this.sortGroupPaneRightWidth = sortGroupPaneRightWidth; |
||||||
|
this.sortGroupPaneWidth = sortGroupPaneWidth; |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
addSortItemBar = new AddSortItemBar(this); |
||||||
|
sortItemListPane = new JPanel(); |
||||||
|
sortItemListPane.setLayout(new BoxLayout(sortItemListPane, BoxLayout.Y_AXIS)); |
||||||
|
this.add(sortItemListPane); |
||||||
|
this.add(addSortItemBar); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(List<SortExpression> sortExpressions, String selfSortArea) { |
||||||
|
this.sortItemListPane.removeAll(); |
||||||
|
this.selfSortArea = selfSortArea; |
||||||
|
this.sortExpressions = sortExpressions; |
||||||
|
this.sortUIExpandablePanes = new ArrayList<>(); |
||||||
|
for (int i = 0; i < sortExpressions.size(); i++) { |
||||||
|
addSortItem(sortExpressions.get(i)); |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression); |
||||||
|
|
||||||
|
public List<SortExpression> updateBean() { |
||||||
|
List<SortExpression> sortExpressions = new ArrayList<>(); |
||||||
|
for (SortUIExpandablePane sortUIExpandablePane : sortUIExpandablePanes) { |
||||||
|
SortExpression sortExpression = null; |
||||||
|
if (sortUIExpandablePane != null) { |
||||||
|
AbstractSortItemPane abstractSortItemPane |
||||||
|
= (AbstractSortItemPane) sortUIExpandablePane.getContentPane(); |
||||||
|
if (abstractSortItemPane != null) { |
||||||
|
sortExpression = abstractSortItemPane.updateBean(); |
||||||
|
} |
||||||
|
} |
||||||
|
if (sortExpression != null) { |
||||||
|
sortExpressions.add(sortExpression); |
||||||
|
} |
||||||
|
} |
||||||
|
return sortExpressions; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void removeSortItem(int no) { |
||||||
|
if (no < sortExpressions.size()) { |
||||||
|
sortItemListPane.remove(sortUIExpandablePanes.get(no)); |
||||||
|
sortExpressions.remove(no); |
||||||
|
sortUIExpandablePanes.remove(no); |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSortItem(SortUIExpandablePane sortUIExpandablePane) { |
||||||
|
for (int i = 0; i < sortUIExpandablePanes.size(); i++) { |
||||||
|
if (sortUIExpandablePanes.get(i) == sortUIExpandablePane) { |
||||||
|
removeSortItem(i); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void registerChangeListener(ComponentChangeListener componentChangeListener) { |
||||||
|
this.componentChangeListener = componentChangeListener; |
||||||
|
} |
||||||
|
|
||||||
|
public void addSortItem(SortExpression sortExpression) { |
||||||
|
int sortItemPaneWidth = sortGroupPaneWidth - SECOND_SORT_LENGTH_REDUCTION; |
||||||
|
int sortItemPaneRightWidth = sortGroupPaneRightWidth - SECOND_SORT_LENGTH_REDUCTION; |
||||||
|
|
||||||
|
if (sortExpression == null) { |
||||||
|
sortExpression = new CellSortExpression(selfSortArea); |
||||||
|
sortExpressions.add(sortExpression); |
||||||
|
} |
||||||
|
|
||||||
|
AbstractSortItemPane abstractSortItemPane = |
||||||
|
refreshSortItemPane(sortItemPaneWidth, sortItemPaneRightWidth, sortExpression); |
||||||
|
|
||||||
|
SortUIExpandablePane sortUIExpandablePane = new SortUIExpandablePane(abstractSortItemPane, this); |
||||||
|
sortItemListPane.add(sortUIExpandablePane); |
||||||
|
sortUIExpandablePanes.add(sortUIExpandablePane); |
||||||
|
if (componentChangeListener != null) { |
||||||
|
componentChangeListener.initListener(sortUIExpandablePane); |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
class AddSortItemBar extends JPanel { |
||||||
|
AbstractSortGroupPane sortGroupPane; |
||||||
|
|
||||||
|
AddSortItemBar(AbstractSortGroupPane sortGroupPane) { |
||||||
|
init(); |
||||||
|
this.sortGroupPane = sortGroupPane; |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 5)); |
||||||
|
} |
||||||
|
|
||||||
|
void init() { |
||||||
|
uiButton = new UIButton(Toolkit.i18nText("Fine-Design_Sort_Add_Second_Sort"), |
||||||
|
IconUtils.readIcon("/com/fr/design/images/sort/add.png")); |
||||||
|
uiButton.setPreferredSize(new Dimension(sortGroupPaneWidth - 4, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
this.add(uiButton); |
||||||
|
uiButton.addActionListener(new ActionListener() { |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
sortGroupPane.addSortItem(null); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,153 @@ |
|||||||
|
package com.fr.design.sort.common; |
||||||
|
|
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.sort.expressionpane.CellSortExpressionPane; |
||||||
|
import com.fr.design.sort.expressionpane.CustomSequenceSortExpressionPane; |
||||||
|
import com.fr.design.sort.expressionpane.FormulaSortExpressionPane; |
||||||
|
import com.fr.design.sort.expressionpane.SortExpressionPane; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
import com.fr.report.core.sort.common.SortRule; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public abstract class AbstractSortItemPane extends JPanel { |
||||||
|
protected int sortItemPaneWidth; |
||||||
|
protected int sortItemPaneRightWidth; |
||||||
|
List<SortExpressionPane> sortExpressionPanes = new ArrayList<>(); |
||||||
|
SortExpressionPane currentSortExpressionPane = null; |
||||||
|
JPanel sortBasisPanel = null; |
||||||
|
UIComboBox sortRuleUiComboBox; |
||||||
|
UIComboBox sortBasisUiComboBox; |
||||||
|
JPanel sortAreaPane; |
||||||
|
JPanel sortRulePane; |
||||||
|
|
||||||
|
public AbstractSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) { |
||||||
|
this.sortItemPaneWidth = sortItemPaneWidth; |
||||||
|
this.sortItemPaneRightWidth = sortItemPaneRightWidth; |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
registerSortExpressionPanes(); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
initSortAreaPane(); |
||||||
|
initSortBasisPanel(); |
||||||
|
initSortRulePane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void registerSortExpressionPanes() { |
||||||
|
sortExpressionPanes.add(new CellSortExpressionPane(sortItemPaneRightWidth)); |
||||||
|
sortExpressionPanes.add(new FormulaSortExpressionPane(sortItemPaneRightWidth)); |
||||||
|
sortExpressionPanes.add(new CustomSequenceSortExpressionPane(sortItemPaneWidth, sortItemPaneRightWidth)); |
||||||
|
} |
||||||
|
|
||||||
|
void initSortAreaPane() { |
||||||
|
sortAreaPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP)); |
||||||
|
sortAreaPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Area"), SwingConstants.LEFT)); |
||||||
|
sortAreaPane.add(AbstractSortPane.createIntervalUILabel()); |
||||||
|
initMainSortAreaPane(sortAreaPane); |
||||||
|
this.add(sortAreaPane); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void initMainSortAreaPane(JPanel sortAreaPane); |
||||||
|
|
||||||
|
void initSortRulePane() { |
||||||
|
sortRulePane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP)); |
||||||
|
sortRuleUiComboBox = new UIComboBox(new String[]{SortRule.ASC.getDescription(), |
||||||
|
SortRule.DES.getDescription(), SortRule.NO_SORT.getDescription()}); |
||||||
|
sortRuleUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
sortRulePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Rule"), SwingConstants.LEFT)); |
||||||
|
sortRulePane.add(AbstractSortPane.createIntervalUILabel()); |
||||||
|
sortRulePane.add(sortRuleUiComboBox); |
||||||
|
this.add(sortRulePane); |
||||||
|
} |
||||||
|
|
||||||
|
void initSortBasisPanel() { |
||||||
|
sortBasisPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP)); |
||||||
|
sortBasisUiComboBox = new UIComboBox(getSortNames()); |
||||||
|
sortBasisUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
sortBasisUiComboBox.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
if (sortExpressionPanes.get(sortBasisUiComboBox.getSelectedIndex()) != currentSortExpressionPane) { |
||||||
|
if (currentSortExpressionPane != null) { |
||||||
|
currentSortExpressionPane.setVisible(false); |
||||||
|
} |
||||||
|
currentSortExpressionPane = sortExpressionPanes.get(sortBasisUiComboBox.getSelectedIndex()); |
||||||
|
refreshCurrentSortExpressionPane(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
sortBasisPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Basis"), SwingConstants.LEFT)); |
||||||
|
sortBasisPanel.add(AbstractSortPane.createIntervalUILabel()); |
||||||
|
sortBasisPanel.add(sortBasisUiComboBox); |
||||||
|
this.add(sortBasisPanel); |
||||||
|
for (SortExpressionPane sortExpressionPane : sortExpressionPanes) { |
||||||
|
this.add(sortExpressionPane); |
||||||
|
sortExpressionPane.setVisible(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void refreshCurrentSortExpressionPane() { |
||||||
|
currentSortExpressionPane.setVisible(true); |
||||||
|
sortAreaPane.setVisible(currentSortExpressionPane.needSortArea()); |
||||||
|
sortRulePane.setVisible(currentSortExpressionPane.needSortRule()); |
||||||
|
} |
||||||
|
|
||||||
|
private String[] getSortNames() { |
||||||
|
String[] sortNames = new String[sortExpressionPanes.size()]; |
||||||
|
for (int i = 0; i < sortExpressionPanes.size(); i++) { |
||||||
|
sortNames[i] = sortExpressionPanes.get(i).getSortName(); |
||||||
|
} |
||||||
|
return sortNames; |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortExpression sortExpression) { |
||||||
|
if (sortExpression.getSortRule() == SortRule.ASC) { |
||||||
|
sortRuleUiComboBox.setSelectedIndex(0); |
||||||
|
} else if (sortExpression.getSortRule() == SortRule.DES) { |
||||||
|
sortRuleUiComboBox.setSelectedIndex(1); |
||||||
|
} else if (sortExpression.getSortRule() == SortRule.NO_SORT) { |
||||||
|
sortRuleUiComboBox.setSelectedIndex(2); |
||||||
|
} |
||||||
|
for (int i = 0; i < sortExpressionPanes.size(); i++) { |
||||||
|
if (StringUtils.equals(sortExpression.getSortName(), sortExpressionPanes.get(i).getSortName())) { |
||||||
|
if (currentSortExpressionPane != null) { |
||||||
|
currentSortExpressionPane.setVisible(false); |
||||||
|
} |
||||||
|
currentSortExpressionPane = sortExpressionPanes.get(i); |
||||||
|
currentSortExpressionPane.populateBean(sortExpression); |
||||||
|
sortBasisUiComboBox.setSelectedIndex(i); |
||||||
|
refreshCurrentSortExpressionPane(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
public SortExpression updateBean() { |
||||||
|
SortExpression sortExpression = currentSortExpressionPane.updateBean(); |
||||||
|
if (sortExpression != null) { |
||||||
|
String sortRule = sortRuleUiComboBox.getSelectedItem().toString(); |
||||||
|
if (StringUtils.isNotBlank(sortRule)) { |
||||||
|
sortExpression.setSortRule(SortRule.parse(sortRule)); |
||||||
|
} |
||||||
|
} |
||||||
|
return sortExpression; |
||||||
|
} |
||||||
|
|
||||||
|
protected void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
package com.fr.design.sort.common; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.sort.header.SortHeaderPane; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.core.sort.common.CellSortAttr; |
||||||
|
import com.fr.report.core.sort.sortexpression.CellSortExpression; |
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
import com.fr.stable.ColumnRow; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractSortPane extends JPanel { |
||||||
|
protected int sortPaneWidth; |
||||||
|
protected int sortPaneRightWidth; |
||||||
|
public static final int PANE_COMPONENT_HEIGHT = 20; |
||||||
|
public static final int PANE_COMPONENT_V_GAP = 4; |
||||||
|
public static final int PANE_COMPONENT_H_GAP = 14; |
||||||
|
protected AbstractSortGroupPane sortGroupPane; |
||||||
|
protected SortHeaderPane sortHeaderPane; |
||||||
|
protected String selfSortArea; |
||||||
|
protected String defaultHeaderArea; |
||||||
|
|
||||||
|
public AbstractSortPane(int sortPaneWidth, int sortPaneRightWidth) { |
||||||
|
this.sortPaneWidth = sortPaneWidth; |
||||||
|
this.sortPaneRightWidth = sortPaneRightWidth; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
initSortGroupPane(); |
||||||
|
if (needSortHeaderPane()) { |
||||||
|
sortHeaderPane = new SortHeaderPane(sortPaneWidth, sortPaneRightWidth + 5); |
||||||
|
this.add(sortHeaderPane); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract void initSortGroupPane(); |
||||||
|
|
||||||
|
|
||||||
|
protected boolean needSortHeaderPane() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract CellSortAttr getCellSortAttr(TemplateCellElement cellElement); |
||||||
|
|
||||||
|
public void populateBean(TemplateCellElement cellElement) { |
||||||
|
populateSortArea(cellElement); |
||||||
|
List<SortExpression> sortExpressions = null; |
||||||
|
CellSortAttr cellSortAttr = getCellSortAttr(cellElement); |
||||||
|
if (cellSortAttr != null) { |
||||||
|
sortExpressions = cellSortAttr.getSortExpressions(); |
||||||
|
} |
||||||
|
if (sortExpressions == null) { |
||||||
|
sortExpressions = new ArrayList<>(); |
||||||
|
} |
||||||
|
sortGroupPane.populateBean(sortExpressions, selfSortArea); |
||||||
|
if (needSortHeaderPane()) { |
||||||
|
SortHeader sortHeader = null; |
||||||
|
if (cellSortAttr != null) { |
||||||
|
sortHeader = cellSortAttr.getSortHeader(); |
||||||
|
} |
||||||
|
sortHeaderPane.populateBean(sortHeader, defaultHeaderArea); |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void populateSortArea(TemplateCellElement cellElement) { |
||||||
|
int row = cellElement.getRow(); |
||||||
|
int column = cellElement.getColumn(); |
||||||
|
selfSortArea = ColumnRow.valueOf(column, row).toString(); |
||||||
|
if (row > 0) { |
||||||
|
defaultHeaderArea = ColumnRow.valueOf(column, row - 1).toString(); |
||||||
|
} else { |
||||||
|
defaultHeaderArea = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void updateBean(TemplateCellElement cellElement) { |
||||||
|
List<SortExpression> sortExpressions = sortGroupPane.updateBean(); |
||||||
|
CellSortAttr cellSortAttr = getCellSortAttr(cellElement); |
||||||
|
cellSortAttr.setSortExpressions(sortExpressions); |
||||||
|
if (needSortHeaderPane()) { |
||||||
|
SortHeader sortHeader = sortHeaderPane.updateBean(cellElement); |
||||||
|
if (sortHeader != null) { |
||||||
|
sortHeader.setSortArea(selfSortArea); |
||||||
|
} |
||||||
|
cellSortAttr.setSortHeader(sortHeader); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public static UILabel createIntervalUILabel() { |
||||||
|
return createIntervalUILabel(PANE_COMPONENT_H_GAP); |
||||||
|
} |
||||||
|
|
||||||
|
public static UILabel createIntervalUILabel(int vGap) { |
||||||
|
UILabel uiLabel = new UILabel(); |
||||||
|
uiLabel.setPreferredSize(new Dimension(vGap, 10)); |
||||||
|
return uiLabel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,277 @@ |
|||||||
|
package com.fr.design.sort.common; |
||||||
|
|
||||||
|
import com.fr.base.Style; |
||||||
|
import com.fr.base.background.ColorBackground; |
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.designer.TargetComponent; |
||||||
|
import com.fr.design.event.UIObserver; |
||||||
|
import com.fr.design.event.UIObserverListener; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.ElementCasePane; |
||||||
|
import com.fr.design.selection.SelectionEvent; |
||||||
|
import com.fr.design.selection.SelectionListener; |
||||||
|
import com.fr.design.sort.header.HeaderAreaPane; |
||||||
|
import com.fr.grid.selection.CellSelection; |
||||||
|
import com.fr.grid.selection.Selection; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.cell.DefaultTemplateCellElement; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.cell.cellattr.CellExpandAttr; |
||||||
|
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||||
|
import com.fr.report.core.sort.common.CellSortable; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
import com.fr.report.elementcase.TemplateElementCase; |
||||||
|
import com.fr.stable.ColumnRow; |
||||||
|
import com.fr.stable.EssentialUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class SortColumnRowPane extends JPanel implements UIObserver { |
||||||
|
int paneWidth; |
||||||
|
int paneHeight; |
||||||
|
int jTextFieldWidth; |
||||||
|
JTextField colJTextField; |
||||||
|
JTextField rowJTextField; |
||||||
|
UIButton selectButton; |
||||||
|
private boolean isAlreadyAddListener = false; |
||||||
|
private CellSelection oldSelection; |
||||||
|
private SelectionListener gridSelectionChangeListener; |
||||||
|
UIObserverListener uiObserverListener; |
||||||
|
private final static Icon DISABLED_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_disabled.svg"); |
||||||
|
private final static Icon ENABLE_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_normal.svg"); |
||||||
|
private boolean enabled; |
||||||
|
|
||||||
|
HeaderAreaPane.CellSelectionManager cellSelectionManager; |
||||||
|
|
||||||
|
public SortColumnRowPane(int paneWidth, int paneHeight) { |
||||||
|
this.paneWidth = paneWidth; |
||||||
|
this.paneHeight = paneHeight; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
initSize(); |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||||
|
intUILabel(); |
||||||
|
initTextField(); |
||||||
|
initSelectButton(); |
||||||
|
this.setSize(new Dimension(paneWidth, paneHeight)); |
||||||
|
} |
||||||
|
|
||||||
|
void initSize() { |
||||||
|
jTextFieldWidth = (paneWidth - 40) / 2; |
||||||
|
} |
||||||
|
|
||||||
|
void intUILabel() { |
||||||
|
UILabel uiLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/buttonicon/propertiestab/cellelement_normal.png")); |
||||||
|
this.add(uiLabel); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isAvailableColumnRow(ColumnRow columnRow) { |
||||||
|
return columnRow != null && columnRow.getRow() != -1 && columnRow.getColumn() != -1; |
||||||
|
} |
||||||
|
|
||||||
|
void initTextField() { |
||||||
|
colJTextField = new JTextField(); |
||||||
|
colJTextField.setEditable(false); |
||||||
|
rowJTextField = new JTextField(); |
||||||
|
rowJTextField.setEditable(false); |
||||||
|
colJTextField.setPreferredSize(new Dimension(jTextFieldWidth, paneHeight)); |
||||||
|
rowJTextField.setPreferredSize(new Dimension(jTextFieldWidth, paneHeight)); |
||||||
|
this.add(colJTextField); |
||||||
|
this.add(rowJTextField); |
||||||
|
} |
||||||
|
|
||||||
|
void initSelectButton() { |
||||||
|
selectButton = new UIButton(ENABLE_ICON); |
||||||
|
selectButton.addMouseListener(new SelectActionListener(this)); |
||||||
|
this.add(selectButton); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(ColumnRow columnRow, boolean enabled, HeaderAreaPane.CellSelectionManager cellSelectionManager) { |
||||||
|
this.cellSelectionManager = cellSelectionManager; |
||||||
|
populateBean(columnRow, enabled); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(ColumnRow columnRow) { |
||||||
|
populateBean(columnRow, true); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(ColumnRow columnRow, boolean enabled) { |
||||||
|
this.enabled = enabled; |
||||||
|
if (SortColumnRowPane.isAvailableColumnRow(columnRow)) { |
||||||
|
colJTextField.setText(EssentialUtils.convertIntToABC(columnRow.column + 1)); |
||||||
|
rowJTextField.setText(String.valueOf(columnRow.row + 1)); |
||||||
|
} else { |
||||||
|
colJTextField.setText(StringUtils.EMPTY); |
||||||
|
rowJTextField.setText(StringUtils.EMPTY); |
||||||
|
} |
||||||
|
if (enabled) { |
||||||
|
selectButton.setIcon(ENABLE_ICON); |
||||||
|
} else { |
||||||
|
selectButton.setIcon(DISABLED_ICON); |
||||||
|
} |
||||||
|
selectButton.setEnabled(false); |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setColumnRow(ColumnRow columnRow) { |
||||||
|
populateBean(columnRow); |
||||||
|
uiObserverListener.doChange(); |
||||||
|
} |
||||||
|
|
||||||
|
public ColumnRow updateBean() { |
||||||
|
if (StringUtils.isNotBlank(colJTextField.getText()) && StringUtils.isNotBlank(rowJTextField.getText())) { |
||||||
|
return ColumnRow.valueOf(colJTextField.getText() + rowJTextField.getText()); |
||||||
|
} |
||||||
|
return ColumnRow.ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void registerChangeListener(UIObserverListener listener) { |
||||||
|
this.uiObserverListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean shouldResponseChangeListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
class SelectActionListener extends MouseAdapter { |
||||||
|
SortColumnRowPane columnRowPane; |
||||||
|
ColumnRow oldColumnRow; |
||||||
|
|
||||||
|
Map<ColumnRow, Style> disableHeaderCellsStyleMap = new HashMap<>(); |
||||||
|
java.util.List<TemplateCellElement> tempHeaderCells = new ArrayList<>(); |
||||||
|
|
||||||
|
SelectActionListener(SortColumnRowPane columnRowPane) { |
||||||
|
this.columnRowPane = columnRowPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (enabled) { |
||||||
|
ElementCasePane elementCasePane = getCurrentElementCase(); |
||||||
|
if (elementCasePane == null || isAlreadyAddListener) { |
||||||
|
return; |
||||||
|
} |
||||||
|
oldColumnRow = columnRowPane.updateBean(); |
||||||
|
prepareSelectHeader(elementCasePane); |
||||||
|
gridSelectionChangeListener = new SelectionListener() { |
||||||
|
@Override |
||||||
|
public void selectionChanged(SelectionEvent e) { |
||||||
|
completeSelectHeader(elementCasePane); |
||||||
|
} |
||||||
|
}; |
||||||
|
elementCasePane.addSelectionChangeListener(gridSelectionChangeListener); |
||||||
|
isAlreadyAddListener = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void prepareSelectHeader(ElementCasePane elementCasePane) { |
||||||
|
ashDisableHeaderCellsStyle(elementCasePane.getEditingElementCase()); |
||||||
|
oldSelection = (CellSelection) elementCasePane.getSelection(); |
||||||
|
elementCasePane.getGrid().setNotShowingTableSelectPane(false); |
||||||
|
elementCasePane.setRepeatSelection(true); |
||||||
|
elementCasePane.setEditable(false); |
||||||
|
elementCasePane.repaint(10); |
||||||
|
} |
||||||
|
|
||||||
|
private void completeSelectHeader(ElementCasePane elementCasePane) { |
||||||
|
Selection selection = elementCasePane.getSelection(); |
||||||
|
if (selection instanceof CellSelection) { |
||||||
|
CellSelection cellselection = (CellSelection) selection; |
||||||
|
ColumnRow columnRow = ColumnRow.valueOf(cellselection.getColumn(), cellselection.getRow()); |
||||||
|
elementCasePane.setOldSelecton(oldSelection); |
||||||
|
oldSelection.getQuickEditor(elementCasePane); |
||||||
|
if (cellSelectionManager == null || !cellSelectionManager.isNotSelectables(columnRow)) { |
||||||
|
if (cellSelectionManager != null) { |
||||||
|
cellSelectionManager.removeNotSelectables(oldColumnRow); |
||||||
|
cellSelectionManager.addNotSelectables(columnRow); |
||||||
|
} |
||||||
|
columnRowPane.setColumnRow(columnRow); |
||||||
|
} |
||||||
|
restoreDisableHeaderCellsStyle(elementCasePane.getEditingElementCase()); |
||||||
|
} |
||||||
|
elementCasePane.removeSelectionChangeListener(gridSelectionChangeListener); |
||||||
|
isAlreadyAddListener = false; |
||||||
|
elementCasePane.getGrid().setNotShowingTableSelectPane(true); |
||||||
|
elementCasePane.setRepeatSelection(false); |
||||||
|
elementCasePane.setEditable(true); |
||||||
|
elementCasePane.repaint(); |
||||||
|
oldColumnRow = null; |
||||||
|
} |
||||||
|
|
||||||
|
private void ashDisableHeaderCellsStyle(TemplateElementCase elementCase) { |
||||||
|
if (cellSelectionManager != null) { |
||||||
|
java.util.List<ColumnRow> notSelectables = cellSelectionManager.getNotSelectables(); |
||||||
|
disableHeaderCellsStyleMap = new HashMap<>(); |
||||||
|
tempHeaderCells = new ArrayList<>(); |
||||||
|
for (ColumnRow columnRow : notSelectables) { |
||||||
|
TemplateCellElement templateCellElement |
||||||
|
= elementCase.getTemplateCellElement(columnRow.column, columnRow.row); |
||||||
|
if (templateCellElement == null) { |
||||||
|
templateCellElement = new DefaultTemplateCellElement(columnRow.column, columnRow.row); |
||||||
|
elementCase.addCellElement(templateCellElement); |
||||||
|
tempHeaderCells.add(templateCellElement); |
||||||
|
} |
||||||
|
Style style = templateCellElement.getStyle(); |
||||||
|
disableHeaderCellsStyleMap.put(columnRow, style); |
||||||
|
style = style.deriveBackground(ColorBackground.getInstance(Color.gray)); |
||||||
|
templateCellElement.setStyle(style); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void restoreDisableHeaderCellsStyle(TemplateElementCase elementCase) { |
||||||
|
if (cellSelectionManager != null) { |
||||||
|
try { |
||||||
|
for (ColumnRow headerColumnRow : disableHeaderCellsStyleMap.keySet()) { |
||||||
|
TemplateCellElement headerTemplateCellElement |
||||||
|
= elementCase.getTemplateCellElement(headerColumnRow.column, headerColumnRow.row); |
||||||
|
headerTemplateCellElement.setStyle(disableHeaderCellsStyleMap.get(headerColumnRow)); |
||||||
|
} |
||||||
|
for (TemplateCellElement templateCellElement : tempHeaderCells) { |
||||||
|
elementCase.removeCellElement(templateCellElement); |
||||||
|
} |
||||||
|
disableHeaderCellsStyleMap = new HashMap<>(); |
||||||
|
tempHeaderCells = new ArrayList<>(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public static ElementCasePane getCurrentElementCase() { |
||||||
|
try { |
||||||
|
TargetComponent targetComponent |
||||||
|
= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane(); |
||||||
|
if (targetComponent instanceof ElementCasePane) { |
||||||
|
return (ElementCasePane) targetComponent; |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
package com.fr.design.sort.common; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.event.UIObserver; |
||||||
|
import com.fr.design.event.UIObserverListener; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
|
||||||
|
public class SortUIExpandablePane extends JPanel { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
private HeaderPane headerPane; |
||||||
|
private AbstractSortItemPane contentPane; |
||||||
|
private AbstractSortGroupPane sortGroupPane; |
||||||
|
|
||||||
|
private JPanel wrapPane; |
||||||
|
private SortUIExpandablePane self = this; |
||||||
|
|
||||||
|
public JPanel getContentPane() { |
||||||
|
return contentPane; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public SortUIExpandablePane(AbstractSortItemPane contentPane, AbstractSortGroupPane sortGroupPane) { |
||||||
|
super(); |
||||||
|
this.sortGroupPane = sortGroupPane; |
||||||
|
this.contentPane = contentPane; |
||||||
|
initComponents(); |
||||||
|
wrapPane.setBorder(BorderFactory.createLineBorder(new Color(217, 218, 221), 1)); |
||||||
|
wrapPane.setBackground(Color.WHITE); |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
wrapPane = new JPanel(); |
||||||
|
wrapPane.setLayout(new BorderLayout()); |
||||||
|
headerPane = new HeaderPane(sortGroupPane); |
||||||
|
headerPane.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
setContentPanelShow(!contentPane.isVisible()); |
||||||
|
} |
||||||
|
}); |
||||||
|
headerPane.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(217, 218, 221))); |
||||||
|
contentPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); |
||||||
|
wrapPane.add(headerPane, BorderLayout.NORTH); |
||||||
|
wrapPane.add(contentPane, BorderLayout.CENTER); |
||||||
|
setContentPanelShow(true); |
||||||
|
this.add(wrapPane); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void setContentPanelShow(Boolean show) { |
||||||
|
contentPane.setVisible(show); |
||||||
|
headerPane.setShow(show); |
||||||
|
} |
||||||
|
|
||||||
|
class HeaderPane extends JPanel implements UIObserver { |
||||||
|
UILabel iconUiLabel; |
||||||
|
UILabel closeButton; |
||||||
|
AbstractSortGroupPane sortGroupPane; |
||||||
|
UIObserverListener uiObserverListener; |
||||||
|
|
||||||
|
HeaderPane(AbstractSortGroupPane sortGroupPane) { |
||||||
|
this.sortGroupPane = sortGroupPane; |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0)); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
iconUiLabel = new UILabel(); |
||||||
|
this.add(iconUiLabel); |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Second_Sort")); |
||||||
|
this.add(uiLabel); |
||||||
|
this.add(AbstractSortPane.createIntervalUILabel(108)); |
||||||
|
|
||||||
|
closeButton = new UILabel(IconUtils.readIcon("/com/fr/design/images/control/close.png")); |
||||||
|
closeButton.setPreferredSize(new Dimension(16, 20)); |
||||||
|
this.add(closeButton); |
||||||
|
closeButton.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
sortGroupPane.removeSortItem(self); |
||||||
|
if (uiObserverListener != null) { |
||||||
|
uiObserverListener.doChange(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
this.setPreferredSize(new Dimension(contentPane.sortItemPaneWidth + 7, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
} |
||||||
|
|
||||||
|
public void setShow(boolean show) { |
||||||
|
if (show) { |
||||||
|
iconUiLabel.setIcon(IconUtils.readIcon("/com/fr/design/images/sort/down_arrow.png")); |
||||||
|
} else { |
||||||
|
iconUiLabel.setIcon(IconUtils.readIcon("/com/fr/design/images/sort/left_arrow.png")); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void registerChangeListener(UIObserverListener uiObserverListener) { |
||||||
|
this.uiObserverListener = uiObserverListener; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean shouldResponseChangeListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.report.core.sort.sortexpression.CellSortExpression; |
||||||
|
|
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
|
||||||
|
public class CellSortExpressionPane extends SortExpressionPane<CellSortExpression> { |
||||||
|
public CellSortExpressionPane(int with) { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getSortName() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Cell"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(CellSortExpression cellSortExpression) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CellSortExpression updateBean() { |
||||||
|
return new CellSortExpression(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,190 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.ilist.UIList; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.alphafine.listener.DocumentAdapter; |
||||||
|
import com.fr.design.mainframe.dnd.SerializableTransferable; |
||||||
|
import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.DocumentEvent; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.datatransfer.DataFlavor; |
||||||
|
import java.awt.datatransfer.Transferable; |
||||||
|
import java.awt.dnd.DnDConstants; |
||||||
|
import java.awt.dnd.DragGestureEvent; |
||||||
|
import java.awt.dnd.DragGestureListener; |
||||||
|
import java.awt.dnd.DragSource; |
||||||
|
import java.awt.dnd.DragSourceAdapter; |
||||||
|
import java.awt.dnd.DropTarget; |
||||||
|
import java.awt.dnd.DropTargetAdapter; |
||||||
|
import java.awt.dnd.DropTargetDropEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class CustomSequenceEditPane extends BasicPane { |
||||||
|
java.util.List<String> customSequence; |
||||||
|
JSplitPane jSplitPane; |
||||||
|
JPanel referenceSequencePanel; |
||||||
|
JPanel editSequencePanel; |
||||||
|
JTextArea jTextArea; |
||||||
|
|
||||||
|
CustomSequenceEditPane(java.util.List<String> customSequence) { |
||||||
|
this.customSequence = customSequence; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
void initComponents() { |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
initReferenceSequencePanel(); |
||||||
|
initEditSequencePanel(); |
||||||
|
initSplitPane(); |
||||||
|
} |
||||||
|
|
||||||
|
void initSplitPane() { |
||||||
|
jSplitPane = new JSplitPane(); |
||||||
|
this.add(jSplitPane); |
||||||
|
jSplitPane.setOneTouchExpandable(true); |
||||||
|
jSplitPane.setContinuousLayout(true); |
||||||
|
jSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); |
||||||
|
jSplitPane.setLeftComponent(referenceSequencePanel); |
||||||
|
jSplitPane.setRightComponent(editSequencePanel); |
||||||
|
jSplitPane.setDividerSize(10); |
||||||
|
jSplitPane.setDividerLocation(200); |
||||||
|
} |
||||||
|
|
||||||
|
void initReferenceSequencePanel() { |
||||||
|
referenceSequencePanel = new JPanel(); |
||||||
|
referenceSequencePanel.setLayout(new BoxLayout(referenceSequencePanel, BoxLayout.Y_AXIS)); |
||||||
|
JPanel titlePane = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Reference_Sequence")); |
||||||
|
titlePane.add(uiLabel); |
||||||
|
referenceSequencePanel.add(titlePane); |
||||||
|
UIScrollPane uiScrollPane = new UIScrollPane(getReferenceSequenceList()); |
||||||
|
uiScrollPane.setPreferredSize(new Dimension(200, 300)); |
||||||
|
referenceSequencePanel.add(uiScrollPane); |
||||||
|
referenceSequencePanel.setSize(new Dimension(200, 400)); |
||||||
|
} |
||||||
|
|
||||||
|
private UIList getReferenceSequenceList() { |
||||||
|
UIList uiList = new UIList(getReferenceSequenceModel()); |
||||||
|
new CustomSequenceEditDragSource(uiList, DnDConstants.ACTION_MOVE); |
||||||
|
return uiList; |
||||||
|
} |
||||||
|
|
||||||
|
private String[] getReferenceSequenceModel() { |
||||||
|
List<List<String>> customSequences = CustomSequenceSortExpression.getReferenceCustomSequences(); |
||||||
|
String[] listModel = new String[customSequences.size()]; |
||||||
|
for (int i = 0; i < customSequences.size(); i++) { |
||||||
|
listModel[i] = CustomSequenceSortExpression.customSequenceToString(customSequences.get(i), ","); |
||||||
|
} |
||||||
|
return listModel; |
||||||
|
} |
||||||
|
|
||||||
|
void initEditSequencePanel() { |
||||||
|
editSequencePanel = new JPanel(); |
||||||
|
editSequencePanel.setLayout(new BoxLayout(editSequencePanel, BoxLayout.Y_AXIS)); |
||||||
|
JPanel titlePane = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Input_Sequence")); |
||||||
|
titlePane.add(uiLabel); |
||||||
|
UILabel uiLabel2 = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Please_Interlace_Sequence_Elements")); |
||||||
|
uiLabel2.setForeground(Color.lightGray); |
||||||
|
titlePane.add(uiLabel2); |
||||||
|
editSequencePanel.add(titlePane); |
||||||
|
jTextArea = getTextArea(); |
||||||
|
UIScrollPane uiScrollPane = new UIScrollPane(jTextArea); |
||||||
|
uiScrollPane.setPreferredSize(new Dimension(475, 300)); |
||||||
|
editSequencePanel.add(uiScrollPane); |
||||||
|
editSequencePanel.setSize(new Dimension(475, 300)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
JTextArea getTextArea() { |
||||||
|
PlaceholderTextArea placeholderTextArea = new PlaceholderTextArea(10, 10, getPlaceholderText()); |
||||||
|
new CustomSequenceEditDropTarget(placeholderTextArea, CustomSequenceSortExpression.getReferenceCustomSequences()); |
||||||
|
placeholderTextArea.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, "\n")); |
||||||
|
placeholderTextArea.getDocument().addDocumentListener(new DocumentAdapter() { |
||||||
|
@Override |
||||||
|
protected void textChanged(DocumentEvent e) { |
||||||
|
placeholderTextArea.repaint(); |
||||||
|
} |
||||||
|
}); |
||||||
|
return placeholderTextArea; |
||||||
|
} |
||||||
|
|
||||||
|
String getPlaceholderText() { |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Please_Interlace_Sequence_Elements_Such_As") + "\n"); |
||||||
|
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_One") + "\n"); |
||||||
|
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_Two") + "\n"); |
||||||
|
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_Three") + "\n"); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Custom_Sequence"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class CustomSequenceEditDragSource extends DragSourceAdapter implements DragGestureListener { |
||||||
|
private DragSource source; |
||||||
|
|
||||||
|
public CustomSequenceEditDragSource(UIList uiList, int actions) { |
||||||
|
source = new DragSource(); |
||||||
|
source.createDefaultDragGestureRecognizer(uiList, actions, this); |
||||||
|
} |
||||||
|
|
||||||
|
public void dragGestureRecognized(DragGestureEvent dge) { |
||||||
|
Component comp = dge.getComponent(); |
||||||
|
if (comp instanceof UIList) { |
||||||
|
UIList uiList = (UIList) comp; |
||||||
|
source.startDrag(dge, DragSource.DefaultLinkDrop, new SerializableTransferable(uiList.getSelectedIndex()), this); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class CustomSequenceEditDropTarget extends DropTargetAdapter { |
||||||
|
java.util.List<java.util.List<String>> customSequences = new ArrayList<>(); |
||||||
|
|
||||||
|
public CustomSequenceEditDropTarget(PlaceholderTextArea jPanel, java.util.List<java.util.List<String>> customSequences) { |
||||||
|
new DropTarget(jPanel, this); |
||||||
|
this.customSequences = customSequences; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void drop(DropTargetDropEvent dtde) { |
||||||
|
try { |
||||||
|
Transferable transferable = dtde.getTransferable(); |
||||||
|
DataFlavor[] dataFlavors = transferable.getTransferDataFlavors(); |
||||||
|
if (dataFlavors.length == 1) { |
||||||
|
Integer index = (Integer) transferable.getTransferData(dataFlavors[0]); |
||||||
|
JTextArea jTextArea = (JTextArea) dtde.getDropTargetContext().getComponent(); |
||||||
|
String text = jTextArea.getText(); |
||||||
|
if (StringUtils.isNotEmpty(text) && !text.endsWith("\n")) { |
||||||
|
text += "\n"; |
||||||
|
} |
||||||
|
java.util.List<String> customSequence = customSequences.get(index); |
||||||
|
for (int i = 0; i < customSequence.size(); i++) { |
||||||
|
text += customSequence.get(i) + "\n"; |
||||||
|
} |
||||||
|
jTextArea.setText(text); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<String> updateBean() { |
||||||
|
return CustomSequenceSortExpression.stringToCustomSequence(jTextArea.getText(), "\n"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
public class CustomSequencePane extends JPanel { |
||||||
|
protected UITextField textField; |
||||||
|
protected UIButton button; |
||||||
|
List<String> customSequence; |
||||||
|
|
||||||
|
public CustomSequencePane(int width) { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0)); |
||||||
|
this.initComponents(width); |
||||||
|
} |
||||||
|
|
||||||
|
protected void initComponents(int width) { |
||||||
|
textField = new UITextField(); |
||||||
|
textField.setEditable(false); |
||||||
|
textField.setPreferredSize(new Dimension(width - 20, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
Icon icon = IconUtils.readIcon("/com/fr/design/images/sort/sequence.png"); |
||||||
|
button = new UIButton(icon); |
||||||
|
button.setBackground(Color.RED); |
||||||
|
button.setOpaque(false); |
||||||
|
button.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
||||||
|
button.setPreferredSize(new Dimension(20, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
MouseAdapter mouseAdapter = new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
CustomSequenceEditPane customSequenceEditPane = new CustomSequenceEditPane(customSequence); |
||||||
|
customSequenceEditPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
customSequence = customSequenceEditPane.updateBean(); |
||||||
|
textField.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, ",")); |
||||||
|
} |
||||||
|
}, new Dimension(700, 400)).setVisible(true); |
||||||
|
} |
||||||
|
}; |
||||||
|
button.addMouseListener(mouseAdapter); |
||||||
|
textField.addMouseListener(mouseAdapter); |
||||||
|
this.add(textField); |
||||||
|
this.add(button); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<String> updateBean() { |
||||||
|
return customSequence; |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(List<String> customSequence) { |
||||||
|
this.customSequence = customSequence; |
||||||
|
textField.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, ",")); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
public class CustomSequenceSortExpressionPane extends SortExpressionPane<CustomSequenceSortExpression> { |
||||||
|
CustomSequencePane customSequencePane; |
||||||
|
|
||||||
|
public CustomSequenceSortExpressionPane(int width, int rightWidth) { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 0)); |
||||||
|
customSequencePane = new CustomSequencePane(rightWidth + 5); |
||||||
|
this.add(customSequencePane); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getSortName() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Custom_Sequence"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(CustomSequenceSortExpression customSequenceSortExpression) { |
||||||
|
List<String> customSequence = customSequenceSortExpression.getCustomSequence(); |
||||||
|
customSequencePane.populateBean(customSequence); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CustomSequenceSortExpression updateBean() { |
||||||
|
List<String> customSequence = customSequencePane.updateBean(); |
||||||
|
return new CustomSequenceSortExpression(customSequence); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.design.formula.TinyFormulaPane; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.report.core.sort.sortexpression.FormulaSortExpression; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
public class FormulaSortExpressionPane extends SortExpressionPane<FormulaSortExpression> { |
||||||
|
|
||||||
|
TinyFormulaPane tinyFormulaPane; |
||||||
|
|
||||||
|
public FormulaSortExpressionPane(int width) { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 0)); |
||||||
|
tinyFormulaPane = new TinyFormulaPane(); |
||||||
|
tinyFormulaPane.setPreferredSize(new Dimension(width + 5, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
this.add(tinyFormulaPane); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getSortName() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Formula"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(FormulaSortExpression formulaSortExpression) { |
||||||
|
String formula = formulaSortExpression.getFormula(); |
||||||
|
tinyFormulaPane.getUITextField().setText(formula); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaSortExpression updateBean() { |
||||||
|
String formula = tinyFormulaPane.getUITextField().getText(); |
||||||
|
return new FormulaSortExpression(formula); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean needSortArea() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.fr.design.sort.expressionpane; |
||||||
|
|
||||||
|
import com.fr.report.core.sort.sortexpression.SortExpression; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class SortExpressionPane<T extends SortExpression> extends JPanel { |
||||||
|
|
||||||
|
public abstract String getSortName(); |
||||||
|
|
||||||
|
public abstract void populateBean(T sortExpression); |
||||||
|
|
||||||
|
public abstract T updateBean(); |
||||||
|
|
||||||
|
public boolean needSortArea() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean needSortRule() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,267 @@ |
|||||||
|
package com.fr.design.sort.header; |
||||||
|
|
||||||
|
import com.fr.design.designer.TargetComponent; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.ElementCasePane; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.design.sort.common.SortColumnRowPane; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.cell.cellattr.CellExpandAttr; |
||||||
|
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||||
|
import com.fr.report.core.sort.common.CellSortable; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
import com.fr.report.elementcase.TemplateElementCase; |
||||||
|
import com.fr.stable.ColumnRow; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
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.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
|
public class HeaderAreaPane extends JPanel { |
||||||
|
protected int headerAreaPaneWidth; |
||||||
|
protected int headerAreaPaneRightWidth; |
||||||
|
private CellSelectionManager cellSelectionManager = new CellSelectionManager(); |
||||||
|
|
||||||
|
|
||||||
|
AreaJLayeredPane areaJLayeredPane; |
||||||
|
|
||||||
|
HeaderAreaPane(int headerAreaPaneWidth, int headerAreaPaneRightWidth) { |
||||||
|
this.headerAreaPaneWidth = headerAreaPaneWidth; |
||||||
|
this.headerAreaPaneRightWidth = headerAreaPaneRightWidth; |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
void initComponents() { |
||||||
|
initUILabel(); |
||||||
|
initLayeredPane(); |
||||||
|
} |
||||||
|
|
||||||
|
void initUILabel() { |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Area"), SwingConstants.LEFT); |
||||||
|
this.add(uiLabel); |
||||||
|
this.add(AbstractSortPane.createIntervalUILabel()); |
||||||
|
} |
||||||
|
|
||||||
|
void initLayeredPane() { |
||||||
|
areaJLayeredPane = new AreaJLayeredPane(); |
||||||
|
this.add(areaJLayeredPane); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(ColumnRow columnRow, boolean showHeaderArea) { |
||||||
|
boolean enabled = true; |
||||||
|
ElementCasePane elementCasePane = getCurrentElementCase(); |
||||||
|
if (elementCasePane != null) { |
||||||
|
enabled = elementCasePane.isSelectedOneCell(); |
||||||
|
} |
||||||
|
areaJLayeredPane.populateBean(columnRow, showHeaderArea, enabled); |
||||||
|
} |
||||||
|
|
||||||
|
public ColumnRow updateBean(TemplateCellElement cellElement) { |
||||||
|
ElementCasePane elementCasePane = getCurrentElementCase(); |
||||||
|
if (elementCasePane != null) { |
||||||
|
if (!elementCasePane.isSelectedOneCell()) { |
||||||
|
return getOldColumnRow(cellElement); |
||||||
|
} |
||||||
|
} |
||||||
|
return areaJLayeredPane.updateBean(); |
||||||
|
} |
||||||
|
|
||||||
|
private ColumnRow getOldColumnRow(TemplateCellElement cellElement) { |
||||||
|
try { |
||||||
|
SortHeader sortHeader |
||||||
|
= cellElement.getCellExpandAttr().getCellSortAttr().getSortHeader(); |
||||||
|
String headerArea = sortHeader.getHeaderArea(); |
||||||
|
if (headerArea == null) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
return ColumnRow.valueOf(headerArea); |
||||||
|
} |
||||||
|
} catch (Exception ignore) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ElementCasePane getCurrentElementCase() { |
||||||
|
try { |
||||||
|
TargetComponent targetComponent |
||||||
|
= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane(); |
||||||
|
if (targetComponent instanceof ElementCasePane) { |
||||||
|
return (ElementCasePane) targetComponent; |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
class AreaJLayeredPane extends JPanel { |
||||||
|
SortColumnRowPane columnRowPane; |
||||||
|
JLayeredPane jLayeredPane; |
||||||
|
UIComboBox uiComboBox; |
||||||
|
boolean populateBeaning; |
||||||
|
|
||||||
|
AreaJLayeredPane() { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
initUIComboBox(); |
||||||
|
initJLayeredPane(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void initUIComboBox() { |
||||||
|
uiComboBox = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_None"), Toolkit.i18nText("Fine-Design_Basic_Custom")}); |
||||||
|
uiComboBox.setSize(new Dimension(headerAreaPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
uiComboBox.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
if (e.getStateChange() != uiComboBox.getSelectedIndex()) { |
||||||
|
setSortColumnRowPaneShow(uiComboBox.getSelectedIndex() == 1); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
}); |
||||||
|
uiComboBox.setEnabled(false); |
||||||
|
} |
||||||
|
|
||||||
|
void setSortColumnRowPaneShow(boolean show) { |
||||||
|
if (show) { |
||||||
|
jLayeredPane.setLayer(columnRowPane, JLayeredPane.POPUP_LAYER); |
||||||
|
jLayeredPane.setLayer(uiComboBox, JLayeredPane.MODAL_LAYER); |
||||||
|
if (!populateBeaning) { |
||||||
|
ColumnRow columnRow = columnRowPane.updateBean(); |
||||||
|
if (cellSelectionManager.isNotSelectables(columnRow)) { |
||||||
|
columnRowPane.setColumnRow(ColumnRow.ERROR); |
||||||
|
} else { |
||||||
|
cellSelectionManager.addNotSelectables(columnRow); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
jLayeredPane.setLayer(uiComboBox, JLayeredPane.POPUP_LAYER); |
||||||
|
jLayeredPane.setLayer(columnRowPane, JLayeredPane.MODAL_LAYER); |
||||||
|
if (!populateBeaning) { |
||||||
|
cellSelectionManager.removeNotSelectables(columnRowPane.updateBean()); |
||||||
|
} |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
void initJLayeredPane() { |
||||||
|
jLayeredPane = new JLayeredPane(); |
||||||
|
columnRowPane = new SortColumnRowPane(headerAreaPaneRightWidth - 18, AbstractSortPane.PANE_COMPONENT_HEIGHT); |
||||||
|
jLayeredPane.setPreferredSize(new Dimension(headerAreaPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
jLayeredPane.add(columnRowPane, JLayeredPane.MODAL_LAYER); |
||||||
|
jLayeredPane.add(uiComboBox, JLayeredPane.POPUP_LAYER); |
||||||
|
this.add(jLayeredPane); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(ColumnRow columnRow, boolean showHeaderArea, boolean enabled) { |
||||||
|
populateBeaning = true; |
||||||
|
cellSelectionManager.build(); |
||||||
|
columnRowPane.populateBean(columnRow, enabled, cellSelectionManager); |
||||||
|
if (showHeaderArea) { |
||||||
|
uiComboBox.setSelectedIndex(1); |
||||||
|
} else { |
||||||
|
uiComboBox.setSelectedIndex(0); |
||||||
|
} |
||||||
|
uiComboBox.setEnabled(enabled); |
||||||
|
populateBeaning = false; |
||||||
|
} |
||||||
|
|
||||||
|
public ColumnRow updateBean() { |
||||||
|
if (uiComboBox.getSelectedIndex() == 0) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
return columnRowPane.updateBean(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static class CellSelectionManager { |
||||||
|
ElementCasePane elementCase; |
||||||
|
java.util.List<ColumnRow> notSelectables = new ArrayList<>(); |
||||||
|
|
||||||
|
void build() { |
||||||
|
ElementCasePane elementCase = SortColumnRowPane.getCurrentElementCase(); |
||||||
|
if (elementCase != null && this.elementCase != elementCase) { |
||||||
|
this.elementCase = elementCase; |
||||||
|
notSelectables = new ArrayList<>(); |
||||||
|
buildNotSelectables(elementCase.getEditingElementCase()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public java.util.List<ColumnRow> getNotSelectables() { |
||||||
|
return this.notSelectables; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public boolean isNotSelectables(ColumnRow columnRow) { |
||||||
|
return notSelectables != null && notSelectables.contains(columnRow); |
||||||
|
} |
||||||
|
|
||||||
|
public void addNotSelectables(ColumnRow columnRow) { |
||||||
|
if (columnRow != null) { |
||||||
|
removeNotSelectables(columnRow); |
||||||
|
notSelectables.add(columnRow); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void removeNotSelectables(ColumnRow columnRow) { |
||||||
|
notSelectables.remove(columnRow); |
||||||
|
} |
||||||
|
|
||||||
|
private void buildNotSelectables(TemplateElementCase elementCase) { |
||||||
|
Iterator iterator = elementCase.cellIterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
TemplateCellElement templateCellElement = (TemplateCellElement) iterator.next(); |
||||||
|
CellExpandAttr cellExpandAttr = templateCellElement.getCellExpandAttr(); |
||||||
|
if (cellExpandAttr != null) { |
||||||
|
handleDisableHeaderCell(cellExpandAttr); |
||||||
|
} |
||||||
|
Object value = templateCellElement.getValue(); |
||||||
|
if (value instanceof DSColumn) { |
||||||
|
handleDisableHeaderCell((DSColumn) value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void handleDisableHeaderCell(CellSortable cellSortable) { |
||||||
|
if (cellSortable.getCellSortAttr() != null) { |
||||||
|
SortHeader sortHeader = cellSortable.getCellSortAttr().getSortHeader(); |
||||||
|
if (sortHeader != null) { |
||||||
|
String headerArea = sortHeader.getHeaderArea(); |
||||||
|
if (headerArea != null) { |
||||||
|
ColumnRow headerColumnRow = ColumnRow.valueOf(headerArea); |
||||||
|
addNotSelectables(headerColumnRow); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.design.sort.header; |
||||||
|
|
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.sort.common.AbstractSortPane; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
public class HeaderSettingPane extends JPanel { |
||||||
|
protected int headerSettingPaneWidth; |
||||||
|
protected int headerSettingPaneRightWidth; |
||||||
|
HeaderSortRulePane headerSortRulePane; |
||||||
|
UICheckBox uiCheckBox; |
||||||
|
|
||||||
|
HeaderSettingPane(int headerSettingPaneWidth, int headerSettingPaneRightWidth) { |
||||||
|
this.headerSettingPaneWidth = headerSettingPaneWidth; |
||||||
|
this.headerSettingPaneRightWidth = headerSettingPaneRightWidth; |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
void initComponents() { |
||||||
|
initUILabel(); |
||||||
|
initHeaderSortRulePane(); |
||||||
|
} |
||||||
|
|
||||||
|
void initUILabel() { |
||||||
|
JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 2)); |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Setting")); |
||||||
|
UILabel emptyUILabel = new UILabel(); |
||||||
|
emptyUILabel.setPreferredSize(new Dimension(10, 10)); |
||||||
|
|
||||||
|
uiCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Sort_Allow_User_Click_Sort_Order")); |
||||||
|
uiCheckBox.setPreferredSize(new Dimension(headerSettingPaneRightWidth - 10, AbstractSortPane.PANE_COMPONENT_HEIGHT)); |
||||||
|
uiCheckBox.addChangeListener(new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
headerSortRulePane.setVisible(uiCheckBox.isSelected()); |
||||||
|
} |
||||||
|
}); |
||||||
|
jPanel.add(uiLabel); |
||||||
|
jPanel.add(emptyUILabel); |
||||||
|
jPanel.add(uiCheckBox); |
||||||
|
this.add(jPanel); |
||||||
|
} |
||||||
|
|
||||||
|
void initHeaderSortRulePane() { |
||||||
|
headerSortRulePane = new HeaderSortRulePane(); |
||||||
|
this.add(headerSortRulePane); |
||||||
|
headerSortRulePane.setVisible(false); |
||||||
|
} |
||||||
|
|
||||||
|
protected void refresh() { |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortHeader.SortItem[] sortItems) { |
||||||
|
if (sortItems == null) { |
||||||
|
uiCheckBox.setSelected(false); |
||||||
|
} else { |
||||||
|
uiCheckBox.setSelected(true); |
||||||
|
} |
||||||
|
headerSortRulePane.populateBean(sortItems); |
||||||
|
} |
||||||
|
|
||||||
|
public SortHeader.SortItem[] updateBean() { |
||||||
|
if (uiCheckBox.isSelected()) { |
||||||
|
return headerSortRulePane.updateBean(); |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,279 @@ |
|||||||
|
package com.fr.design.sort.header; |
||||||
|
|
||||||
|
import com.fr.base.svg.SVGIcon; |
||||||
|
import com.fr.base.svg.SVGTranscoder; |
||||||
|
import com.fr.design.event.UIObserver; |
||||||
|
import com.fr.design.event.UIObserverListener; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.theme.edit.ui.ColorListPane; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
import com.fr.report.core.sort.common.SortRule; |
||||||
|
import org.apache.batik.transcoder.TranscoderInput; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class HeaderSortRulePane extends JPanel { |
||||||
|
private static final String ASC_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/asc.svg"; |
||||||
|
private static final String DES_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/des.svg"; |
||||||
|
private static final String NOSORT_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/nosort.svg"; |
||||||
|
private static final double ICON_SCALE = SVGIcon.SYSTEM_SCALE * 1.25; |
||||||
|
private static final int ICON_LENGTH = (int) Math.ceil(16 * ICON_SCALE); |
||||||
|
IconButton ascIconButton; |
||||||
|
IconButton desIconButton; |
||||||
|
IconButton nosortIconButton; |
||||||
|
UICheckBox ascUICheckBox; |
||||||
|
UICheckBox desUICheckBox; |
||||||
|
UICheckBox nosortUICheckBox; |
||||||
|
static Map<String, String> originalSvgTextMap = new HashMap<>(); |
||||||
|
|
||||||
|
HeaderSortRulePane() { |
||||||
|
initComponents(); |
||||||
|
initState(true); |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); |
||||||
|
} |
||||||
|
|
||||||
|
void initComponents() { |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
initUILabel(); |
||||||
|
initSortRuleItem(); |
||||||
|
this.setPreferredSize(new Dimension(160, 160)); |
||||||
|
} |
||||||
|
|
||||||
|
void initUILabel() { |
||||||
|
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Sort_Basis"), SwingConstants.LEFT); |
||||||
|
this.add(uiLabel, BorderLayout.NORTH); |
||||||
|
} |
||||||
|
|
||||||
|
void initSortRuleItem() { |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(ASC_ICON_TEMPLATE_PATH)}, |
||||||
|
new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(DES_ICON_TEMPLATE_PATH)}, |
||||||
|
new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(NOSORT_ICON_TEMPLATE_PATH)}, |
||||||
|
}; |
||||||
|
double[] rowSize = {ICON_LENGTH + 10, ICON_LENGTH + 10, ICON_LENGTH + 10}; |
||||||
|
double[] columnSize = {80, ICON_LENGTH + 10}; |
||||||
|
JPanel sortRuleItem = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, 0); |
||||||
|
this.add(sortRuleItem, BorderLayout.CENTER); |
||||||
|
initUICheckBoxChange(ascUICheckBox, ascIconButton); |
||||||
|
initUICheckBoxChange(desUICheckBox, desIconButton); |
||||||
|
initUICheckBoxChange(nosortUICheckBox, nosortIconButton); |
||||||
|
} |
||||||
|
|
||||||
|
void initUICheckBoxChange(UICheckBox uiCheckBox, IconButton iconButton) { |
||||||
|
uiCheckBox.addChangeListener(new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
iconButton.setActiveState(uiCheckBox.isSelected()); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
void initState(boolean selected) { |
||||||
|
ascUICheckBox.setSelected(selected); |
||||||
|
desUICheckBox.setSelected(selected); |
||||||
|
nosortUICheckBox.setSelected(selected); |
||||||
|
ascIconButton.refreshIconLabelColor(new Color(33, 33, 34)); |
||||||
|
desIconButton.refreshIconLabelColor(new Color(33, 33, 34)); |
||||||
|
nosortIconButton.refreshIconLabelColor(new Color(33, 33, 34)); |
||||||
|
} |
||||||
|
|
||||||
|
class IconButton extends JPanel implements UIObserver { |
||||||
|
JLayeredPane jLayeredPane; |
||||||
|
String iconTemplatePath; |
||||||
|
UILabel iconLabel; |
||||||
|
ColorListPane.ColorButton colorButton; |
||||||
|
Color color; |
||||||
|
BufferedImage bufferedImage; |
||||||
|
UIObserverListener uiObserverListener; |
||||||
|
boolean activeState; |
||||||
|
UILabel borderUiLabel; |
||||||
|
|
||||||
|
IconButton(String iconTemplatePath) { |
||||||
|
this.iconTemplatePath = iconTemplatePath; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isActiveState() { |
||||||
|
return activeState; |
||||||
|
} |
||||||
|
|
||||||
|
public void setActiveState(boolean activeState) { |
||||||
|
if (activeState) { |
||||||
|
borderUiLabel.setBorder(BorderFactory.createLineBorder(Color.gray, 1)); |
||||||
|
colorButton.setVisible(true); |
||||||
|
} else { |
||||||
|
borderUiLabel.setBorder(null); |
||||||
|
colorButton.setVisible(false); |
||||||
|
} |
||||||
|
this.activeState = activeState; |
||||||
|
} |
||||||
|
|
||||||
|
void initComponents() { |
||||||
|
jLayeredPane = new JLayeredPane(); |
||||||
|
iconLabel = getIconLabel(iconTemplatePath); |
||||||
|
borderUiLabel = new UILabel(); |
||||||
|
borderUiLabel.setSize(ICON_LENGTH, ICON_LENGTH); |
||||||
|
borderUiLabel.setOpaque(true); |
||||||
|
borderUiLabel.setBackground(Color.WHITE); |
||||||
|
iconLabel.setSize(ICON_LENGTH, ICON_LENGTH); |
||||||
|
colorButton = new ColorListPane.ColorButton(Color.CYAN); |
||||||
|
colorButton.setSize(ICON_LENGTH, ICON_LENGTH); |
||||||
|
colorButton.addChangeListener(new ChangeListener() { |
||||||
|
@Override |
||||||
|
public void stateChanged(ChangeEvent e) { |
||||||
|
color = colorButton.getSelectObject(); |
||||||
|
refreshIconLabelColor(color); |
||||||
|
uiObserverListener.doChange(); |
||||||
|
} |
||||||
|
}); |
||||||
|
jLayeredPane.setPreferredSize(new Dimension(ICON_LENGTH, ICON_LENGTH)); |
||||||
|
|
||||||
|
jLayeredPane.add(iconLabel, JLayeredPane.POPUP_LAYER); |
||||||
|
jLayeredPane.add(borderUiLabel, JLayeredPane.MODAL_LAYER); |
||||||
|
jLayeredPane.add(colorButton, JLayeredPane.PALETTE_LAYER); |
||||||
|
this.add(jLayeredPane); |
||||||
|
} |
||||||
|
|
||||||
|
void refreshIconLabelColor(Color color) { |
||||||
|
Icon icon = getIcon(iconTemplatePath, color); |
||||||
|
refreshIconLabel(icon); |
||||||
|
} |
||||||
|
|
||||||
|
void refreshIconLabel(BufferedImage bufferedImage) { |
||||||
|
if (bufferedImage != null) { |
||||||
|
this.bufferedImage = bufferedImage; |
||||||
|
Icon icon = new SVGIcon(bufferedImage); |
||||||
|
refreshIconLabel(icon); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void refreshIconLabel(Icon icon) { |
||||||
|
if (icon != null) { |
||||||
|
iconLabel.removeAll(); |
||||||
|
iconLabel.setIcon(icon); |
||||||
|
iconLabel.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
UILabel getIconLabel(String iconPath) { |
||||||
|
return getIconLabel(iconPath, new Color(33, 33, 34)); |
||||||
|
} |
||||||
|
|
||||||
|
UILabel getIconLabel(String iconPath, Color color) { |
||||||
|
Icon svgIcon = getIcon(iconPath, color); |
||||||
|
return new UILabel(svgIcon); |
||||||
|
} |
||||||
|
|
||||||
|
Icon getIcon(String iconPath, Color color) { |
||||||
|
try { |
||||||
|
String originalSvgText = getOriginalSvgText(iconPath); |
||||||
|
String svgText = originalSvgText.replaceAll("\\{fillColor\\}", shiftColor(color)); |
||||||
|
InputStream svgInputStream = new ByteArrayInputStream(svgText.getBytes(StandardCharsets.UTF_8)); |
||||||
|
TranscoderInput input = new TranscoderInput(svgInputStream); |
||||||
|
bufferedImage = SVGTranscoder.createImage(ICON_SCALE, input).getImage(); |
||||||
|
SVGIcon svgIcon = new SVGIcon(bufferedImage); |
||||||
|
return svgIcon; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
String getOriginalSvgText(String iconPath) throws Exception { |
||||||
|
String originalSvgText = originalSvgTextMap.get(iconPath); |
||||||
|
if (originalSvgText == null) { |
||||||
|
InputStream inputStream = IOUtils.getResourceAsStream(iconPath, HeaderSortRulePane.class); |
||||||
|
originalSvgText = getSvgText(inputStream); |
||||||
|
originalSvgTextMap.put(iconPath, originalSvgText); |
||||||
|
} |
||||||
|
return originalSvgText; |
||||||
|
} |
||||||
|
|
||||||
|
String shiftColor(Color color) { |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
stringBuilder.append(shiftValue(color.getRed())); |
||||||
|
stringBuilder.append(shiftValue(color.getGreen())); |
||||||
|
stringBuilder.append(shiftValue(color.getBlue())); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
String shiftValue(int value) { |
||||||
|
String resultValue = Integer.toHexString(value); |
||||||
|
if (resultValue.length() == 1) { |
||||||
|
resultValue = "0" + resultValue; |
||||||
|
} |
||||||
|
return resultValue; |
||||||
|
} |
||||||
|
|
||||||
|
private String getSvgText(InputStream inputStream) throws Exception { |
||||||
|
StringBuffer stringBuffer = new StringBuffer(); |
||||||
|
byte[] b = new byte[1024]; |
||||||
|
for (int n; (n = inputStream.read(b)) != -1; ) { |
||||||
|
stringBuffer.append(new String(b, 0, n)); |
||||||
|
} |
||||||
|
return stringBuffer.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void registerChangeListener(UIObserverListener uiObserverListener) { |
||||||
|
this.uiObserverListener = uiObserverListener; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean shouldResponseChangeListener() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortHeader.SortItem[] sortItems) { |
||||||
|
initState(sortItems == null); |
||||||
|
if (sortItems != null) { |
||||||
|
for (SortHeader.SortItem sortItem : sortItems) { |
||||||
|
SortRule sortRule = sortItem.getSortRule(); |
||||||
|
BufferedImage bufferedImage = sortItem.getBufferedImage(); |
||||||
|
if (sortRule == SortRule.ASC) { |
||||||
|
ascIconButton.refreshIconLabel(bufferedImage); |
||||||
|
ascUICheckBox.setSelected(true); |
||||||
|
} else if (sortRule == SortRule.DES) { |
||||||
|
desIconButton.refreshIconLabel(bufferedImage); |
||||||
|
desUICheckBox.setSelected(true); |
||||||
|
} else if (sortRule == SortRule.NO_SORT) { |
||||||
|
nosortIconButton.refreshIconLabel(bufferedImage); |
||||||
|
nosortUICheckBox.setSelected(true); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public SortHeader.SortItem[] updateBean() { |
||||||
|
java.util.List<SortHeader.SortItem> items = new ArrayList<>(); |
||||||
|
if (ascUICheckBox.isSelected()) { |
||||||
|
items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.bufferedImage)); |
||||||
|
} |
||||||
|
if (desUICheckBox.isSelected()) { |
||||||
|
items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.bufferedImage)); |
||||||
|
} |
||||||
|
if (nosortUICheckBox.isSelected()) { |
||||||
|
items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.bufferedImage)); |
||||||
|
} |
||||||
|
SortHeader.SortItem[] resultItems = new SortHeader.SortItem[items.size()]; |
||||||
|
return items.toArray(resultItems); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
package com.fr.design.sort.header; |
||||||
|
|
||||||
|
import com.fr.design.sort.common.SortColumnRowPane; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.core.sort.header.SortHeader; |
||||||
|
import com.fr.stable.ColumnRow; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
public class SortHeaderPane extends JPanel { |
||||||
|
int sortHeaderPaneWidth; |
||||||
|
int sortHeaderPaneRightWidth; |
||||||
|
SortHeader sortHeader; |
||||||
|
HeaderAreaPane headerAreaPane; |
||||||
|
HeaderSettingPane headerSettingPane; |
||||||
|
TemplateCellElement cellElement; |
||||||
|
|
||||||
|
public SortHeaderPane(int sortHeaderPaneWidth, int sortHeaderPaneRightWidth) { |
||||||
|
this.sortHeaderPaneWidth = sortHeaderPaneWidth; |
||||||
|
this.sortHeaderPaneRightWidth = sortHeaderPaneRightWidth; |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
initHeaderArea(); |
||||||
|
initHeaderSetting(); |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
} |
||||||
|
|
||||||
|
void initHeaderArea() { |
||||||
|
this.headerAreaPane = new HeaderAreaPane(sortHeaderPaneWidth, sortHeaderPaneRightWidth); |
||||||
|
this.add(headerAreaPane); |
||||||
|
} |
||||||
|
|
||||||
|
void initHeaderSetting() { |
||||||
|
this.headerSettingPane = new HeaderSettingPane(sortHeaderPaneWidth, sortHeaderPaneRightWidth); |
||||||
|
this.add(headerSettingPane); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(SortHeader sortHeader, String defaultHeaderArea) { |
||||||
|
this.sortHeader = sortHeader; |
||||||
|
boolean showHeaderArea = false; |
||||||
|
SortHeader.SortItem[] sortItems = null; |
||||||
|
String headerArea = defaultHeaderArea; |
||||||
|
ColumnRow columnRow = ColumnRow.valueOf(headerArea); |
||||||
|
if (sortHeader != null) { |
||||||
|
headerArea = sortHeader.getHeaderArea(); |
||||||
|
sortItems = sortHeader.getSortItems(); |
||||||
|
if (headerArea != null) { |
||||||
|
showHeaderArea = true; |
||||||
|
columnRow = ColumnRow.valueOf(headerArea); |
||||||
|
} |
||||||
|
} |
||||||
|
headerAreaPane.populateBean(columnRow, showHeaderArea); |
||||||
|
headerSettingPane.populateBean(sortItems); |
||||||
|
} |
||||||
|
|
||||||
|
public SortHeader updateBean(TemplateCellElement cellElement) { |
||||||
|
ColumnRow columnRow = headerAreaPane.updateBean( cellElement); |
||||||
|
SortHeader.SortItem[] items = headerSettingPane.updateBean(); |
||||||
|
String headerArea = null; |
||||||
|
if (columnRow != null) { |
||||||
|
headerArea = columnRow.toString(); |
||||||
|
} |
||||||
|
SortHeader sortHeader = new SortHeader(headerArea, null, items); |
||||||
|
return sortHeader; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue