From 6ebd8cb29328622c85ac53b2962b1bfb667c4745 Mon Sep 17 00:00:00 2001 From: hzzz Date: Tue, 23 May 2017 15:47:12 +0800 Subject: [PATCH 01/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../file/newReport/NewPolyReportAction.java | 4 +++- .../file/newReport/NewWorkBookAction.java | 4 +++- .../fr/design/mainframe/ElementCasePane.java | 12 ++++++---- .../design/mainframe/FormatBrushAction.java | 2 +- .../fr/design/actions/edit/CopyAction.java | 4 +++- .../com/fr/design/actions/edit/CutAction.java | 4 +++- .../fr/design/actions/edit/PasteAction.java | 4 +++- .../gui/autocomplete/AutoCompletion.java | 5 ++-- .../design/gui/frpane/UIAdvancedTextPane.java | 8 ++++--- .../gui/icombobox/ExtendedComboBox.java | 4 +++- .../fr/design/gui/icombobox/UIComboBoxUI.java | 4 +++- .../gui/itabpane/UITabsHeaderIconPane.java | 4 +++- .../ui/rtextarea/RTADefaultInputMap.java | 24 +++++++------------ .../loghandler/DesignerLogHandler.java | 8 ++++--- .../src/com/fr/design/menu/KeySetUtils.java | 20 +++++++++------- .../designer/beans/actions/CopyAction.java | 4 +++- .../designer/beans/actions/CutAction.java | 4 +++- .../designer/beans/actions/PasteAction.java | 4 +++- .../mainframe/actions/NewFormAction.java | 4 +++- .../widget/editors/DataTableConfigPane.java | 4 +++- 20 files changed, 80 insertions(+), 51 deletions(-) diff --git a/designer/src/com/fr/design/actions/file/newReport/NewPolyReportAction.java b/designer/src/com/fr/design/actions/file/newReport/NewPolyReportAction.java index ea7785f7a..924d0c01d 100644 --- a/designer/src/com/fr/design/actions/file/newReport/NewPolyReportAction.java +++ b/designer/src/com/fr/design/actions/file/newReport/NewPolyReportAction.java @@ -11,13 +11,15 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JPolyWorkBook; import com.fr.general.Inter; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class NewPolyReportAction extends UpdateAction { public NewPolyReportAction() { this.setName(Inter.getLocText("M-New_Multi_Report")); this.setMnemonic('F'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/formExport.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, DEFAULT_MODIFIER)); } /** diff --git a/designer/src/com/fr/design/actions/file/newReport/NewWorkBookAction.java b/designer/src/com/fr/design/actions/file/newReport/NewWorkBookAction.java index 268adafbf..cda7a0aa1 100644 --- a/designer/src/com/fr/design/actions/file/newReport/NewWorkBookAction.java +++ b/designer/src/com/fr/design/actions/file/newReport/NewWorkBookAction.java @@ -12,6 +12,8 @@ import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class NewWorkBookAction extends UpdateAction { public NewWorkBookAction() { @@ -47,7 +49,7 @@ public class NewWorkBookAction extends UpdateAction { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_N, DEFAULT_MODIFIER); } }; diff --git a/designer/src/com/fr/design/mainframe/ElementCasePane.java b/designer/src/com/fr/design/mainframe/ElementCasePane.java index dcc68ab81..52bbc6393 100644 --- a/designer/src/com/fr/design/mainframe/ElementCasePane.java +++ b/designer/src/com/fr/design/mainframe/ElementCasePane.java @@ -127,6 +127,8 @@ import com.fr.stable.ColumnRow; import com.fr.stable.Constants; import com.fr.stable.unit.FU; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * This class used to edit Report. */ @@ -280,7 +282,7 @@ public abstract class ElementCasePane extends Tar } } }); - formatBrush.registerKeyboardAction(keyListener, KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); + formatBrush.registerKeyboardAction(keyListener, KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER), JComponent.WHEN_IN_FOCUSED_WINDOW); formatBrush.registerKeyboardAction(escKey, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); } @@ -855,7 +857,7 @@ public abstract class ElementCasePane extends Tar // clearReportPage old values. inputMapAncestor.clear(); actionMap.clear(); - inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK), "cut"); + inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), "cut"); actionMap.put("cut", new AbstractAction() { public void actionPerformed(ActionEvent evt) { if (cut()) { @@ -863,13 +865,13 @@ public abstract class ElementCasePane extends Tar } } }); - inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK), "copy"); + inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), "copy"); actionMap.put("copy", new AbstractAction() { public void actionPerformed(ActionEvent evt) { copy(); } }); - inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), "paste"); + inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), "paste"); actionMap.put("paste", new AbstractAction() { public void actionPerformed(ActionEvent evt) { if (paste()) { @@ -887,7 +889,7 @@ public abstract class ElementCasePane extends Tar } } }); - inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK), "delete_all"); + inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, DEFAULT_MODIFIER), "delete_all"); actionMap.put("delete_all", new AbstractAction() { public void actionPerformed(ActionEvent evt) { if (clearAll()) { diff --git a/designer/src/com/fr/design/mainframe/FormatBrushAction.java b/designer/src/com/fr/design/mainframe/FormatBrushAction.java index 296fb6d20..cf4c98448 100644 --- a/designer/src/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer/src/com/fr/design/mainframe/FormatBrushAction.java @@ -1 +1 @@ -package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; import com.fr.general.Inter; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * Author : daisy * Date: 13-8-7 * Time: 上午11:05 */ public class FormatBrushAction extends ElementCaseAction { private ElementCasePane ePane; private CellSelection oldSelection; public FormatBrushAction(ElementCasePane t) { super(t); this.setName(Inter.getLocText("M_Edit-FormatBrush")); this.setMnemonic('B'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK)); } public boolean executeActionReturnUndoRecordNeeded() { ePane = (ElementCasePane) getEditingComponent(); if (ePane != null) { Selection selection = ePane.getSelection(); if (!(selection instanceof CellSelection)) { return false; } oldSelection = ((CellSelection) selection).clone(); ePane.setFormatReferencedCell(oldSelection); int cellRectangleCount = oldSelection.getCellRectangleCount(); if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; } } //只对单个区域进行格式刷操作 ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); ePane.repaint(); return true; } return false; } /** * 判断是不是连续区域 * * @return */ private boolean isContinueArea() { int xStart = oldSelection.getCellRectangle(1).x; int xend = 0; int yStrat = oldSelection.getCellRectangle(1).y; int yend = 0; int totalNum = 0; for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { Rectangle temp = oldSelection.getCellRectangle(i); if (temp.getX() < xStart) { xStart = temp.x; } if (temp.getX() + temp.getWidth() > xend) { xend = (int) (temp.getX() + temp.getWidth()); } if (temp.getY() < yStrat) { yStrat = temp.y; } if (temp.getY() + temp.getHeight() > yend) { yend = (int) (temp.getY() + temp.getHeight()); } totalNum += (int) (temp.getWidth() * temp.getHeight()); } if ((xend - xStart) * (yend - yStrat) == totalNum) { oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); ePane.setSelection(oldSelection); ePane.setFormatReferencedCell(oldSelection); return true; } return false; } public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; } int rowSpan = referencedStyle[0].length; int columnSpan = referencedStyle.length; //开始进行格式刷样式复制 TemplateElementCase elementCase = reportPane.getEditingElementCase(); int rowNum = cs.getRowSpan(); int columnNum = cs.getColumnSpan(); //如果只点选了一个,则自动补足 if (cs.getColumnSpan() * cs.getRowSpan() == 1) { rowNum = rowSpan; columnNum = columnSpan; } for (int j = 0; j < rowNum; j++) { for (int i = 0; i < columnNum; i++) { int column = i + cs.getColumn(); int row = j + cs.getRow(); TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); } } } private Style[][] getOldStyles(CellSelection oldSelection) { Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; int cellRectangleCount = oldSelection.getCellRectangleCount(); TemplateElementCase elementCase = ePane.getEditingElementCase(); for (int rect = 0; rect < cellRectangleCount; rect++) { Rectangle cellRectangle = oldSelection.getCellRectangle(rect); for (int j = 0; j < cellRectangle.height; j++) { for (int i = 0; i < cellRectangle.width; i++) { int column = i + cellRectangle.x; int row = j + cellRectangle.y; TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } Style style = cellElement.getStyle(); if (style == null) { style = style.DEFAULT_STYLE; } referencedStyle[i][j] = style; } } } return referencedStyle; } } \ No newline at end of file +package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; import com.fr.general.Inter; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.*; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** * Author : daisy * Date: 13-8-7 * Time: 上午11:05 */ public class FormatBrushAction extends ElementCaseAction { private ElementCasePane ePane; private CellSelection oldSelection; public FormatBrushAction(ElementCasePane t) { super(t); this.setName(Inter.getLocText("M_Edit-FormatBrush")); this.setMnemonic('B'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); } public boolean executeActionReturnUndoRecordNeeded() { ePane = (ElementCasePane) getEditingComponent(); if (ePane != null) { Selection selection = ePane.getSelection(); if (!(selection instanceof CellSelection)) { return false; } oldSelection = ((CellSelection) selection).clone(); ePane.setFormatReferencedCell(oldSelection); int cellRectangleCount = oldSelection.getCellRectangleCount(); if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; } } //只对单个区域进行格式刷操作 ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); ePane.repaint(); return true; } return false; } /** * 判断是不是连续区域 * * @return */ private boolean isContinueArea() { int xStart = oldSelection.getCellRectangle(1).x; int xend = 0; int yStrat = oldSelection.getCellRectangle(1).y; int yend = 0; int totalNum = 0; for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { Rectangle temp = oldSelection.getCellRectangle(i); if (temp.getX() < xStart) { xStart = temp.x; } if (temp.getX() + temp.getWidth() > xend) { xend = (int) (temp.getX() + temp.getWidth()); } if (temp.getY() < yStrat) { yStrat = temp.y; } if (temp.getY() + temp.getHeight() > yend) { yend = (int) (temp.getY() + temp.getHeight()); } totalNum += (int) (temp.getWidth() * temp.getHeight()); } if ((xend - xStart) * (yend - yStrat) == totalNum) { oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); ePane.setSelection(oldSelection); ePane.setFormatReferencedCell(oldSelection); return true; } return false; } public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; } int rowSpan = referencedStyle[0].length; int columnSpan = referencedStyle.length; //开始进行格式刷样式复制 TemplateElementCase elementCase = reportPane.getEditingElementCase(); int rowNum = cs.getRowSpan(); int columnNum = cs.getColumnSpan(); //如果只点选了一个,则自动补足 if (cs.getColumnSpan() * cs.getRowSpan() == 1) { rowNum = rowSpan; columnNum = columnSpan; } for (int j = 0; j < rowNum; j++) { for (int i = 0; i < columnNum; i++) { int column = i + cs.getColumn(); int row = j + cs.getRow(); TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); } } } private Style[][] getOldStyles(CellSelection oldSelection) { Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; int cellRectangleCount = oldSelection.getCellRectangleCount(); TemplateElementCase elementCase = ePane.getEditingElementCase(); for (int rect = 0; rect < cellRectangleCount; rect++) { Rectangle cellRectangle = oldSelection.getCellRectangle(rect); for (int j = 0; j < cellRectangle.height; j++) { for (int i = 0; i < cellRectangle.width; i++) { int column = i + cellRectangle.x; int row = j + cellRectangle.y; TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } Style style = cellElement.getStyle(); if (style == null) { style = style.DEFAULT_STYLE; } referencedStyle[i][j] = style; } } } return referencedStyle; } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/actions/edit/CopyAction.java b/designer_base/src/com/fr/design/actions/edit/CopyAction.java index d0579a579..b3a932ba5 100644 --- a/designer_base/src/com/fr/design/actions/edit/CopyAction.java +++ b/designer_base/src/com/fr/design/actions/edit/CopyAction.java @@ -11,6 +11,8 @@ import com.fr.general.Inter; import javax.swing.*; import java.awt.event.KeyEvent; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Copy. */ @@ -21,7 +23,7 @@ public class CopyAction extends TemplateComponentAction { this.setName(Inter.getLocText("M_Edit-Copy")); this.setMnemonic('C'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)); } @Override diff --git a/designer_base/src/com/fr/design/actions/edit/CutAction.java b/designer_base/src/com/fr/design/actions/edit/CutAction.java index 735ec5bf3..b0e7847a6 100644 --- a/designer_base/src/com/fr/design/actions/edit/CutAction.java +++ b/designer_base/src/com/fr/design/actions/edit/CutAction.java @@ -12,6 +12,8 @@ import com.fr.design.actions.TemplateComponentAction; import com.fr.design.designer.TargetComponent; import com.fr.general.Inter; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Cut. */ @@ -25,7 +27,7 @@ public class CutAction extends TemplateComponentAction { this.setName(Inter.getLocText("M_Edit-Cut")); this.setMnemonic('T'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); } @Override diff --git a/designer_base/src/com/fr/design/actions/edit/PasteAction.java b/designer_base/src/com/fr/design/actions/edit/PasteAction.java index f6b71e421..4ca42c0f2 100644 --- a/designer_base/src/com/fr/design/actions/edit/PasteAction.java +++ b/designer_base/src/com/fr/design/actions/edit/PasteAction.java @@ -12,6 +12,8 @@ import com.fr.design.actions.TemplateComponentAction; import com.fr.design.designer.TargetComponent; import com.fr.general.Inter; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Paste. */ @@ -25,7 +27,7 @@ public class PasteAction extends TemplateComponentAction { this.setName(Inter.getLocText("M_Edit-Paste")); this.setMnemonic('P'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/paste.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)); } @Override diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java index 83047ad71..122beb1e6 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java @@ -20,6 +20,8 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.*; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Adds auto-completion to a text component. Provides a popup window with a @@ -308,8 +310,7 @@ public class AutoCompletion { */ public static KeyStroke getDefaultTriggerKey() { // Default to CTRL, even on Mac, since Ctrl+Space activates Spotlight - int mask = InputEvent.CTRL_MASK; - return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, mask); + return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, DEFAULT_MODIFIER); } diff --git a/designer_base/src/com/fr/design/gui/frpane/UIAdvancedTextPane.java b/designer_base/src/com/fr/design/gui/frpane/UIAdvancedTextPane.java index 0194551da..8ce8ec1a0 100644 --- a/designer_base/src/com/fr/design/gui/frpane/UIAdvancedTextPane.java +++ b/designer_base/src/com/fr/design/gui/frpane/UIAdvancedTextPane.java @@ -20,6 +20,8 @@ import com.fr.design.actions.UpdateAction; import com.fr.design.menu.KeySetUtils; import com.fr.general.Inter; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * p:这是一个增强的JTextPane,支持很多Action */ @@ -143,7 +145,7 @@ public class UIAdvancedTextPane extends UITextPane { setName(Inter.getLocText("M_Edit-Cut")); setMnemonic('T'); setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); - setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK)); + setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); } public void actionPerformed(ActionEvent evt) { @@ -162,7 +164,7 @@ public class UIAdvancedTextPane extends UITextPane { this.setName(Inter.getLocText("M_Edit-Copy")); this.setMnemonic('C'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)); } public void actionPerformed(ActionEvent evt) { @@ -181,7 +183,7 @@ public class UIAdvancedTextPane extends UITextPane { this.setName(Inter.getLocText("M_Edit-Paste")); this.setMnemonic('P'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/paste.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)); } public void actionPerformed(ActionEvent evt) { diff --git a/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java b/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java index 86a5b5cf2..47ddbdac3 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java +++ b/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java @@ -17,6 +17,8 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class ExtendedComboBox extends UIComboBox { private static final int VALUE120 = 120; @@ -79,7 +81,7 @@ public class ExtendedComboBox extends UIComboBox { // Key from the list. // ie., don't allow CTRL key deselection. e = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers() - ^ InputEvent.CTRL_MASK, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); + ^ DEFAULT_MODIFIER, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); } super.processMouseEvent(e); } diff --git a/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java b/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java index 28ae0aebf..ae1089fa9 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java +++ b/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java @@ -24,6 +24,8 @@ import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.stable.Constants; import com.fr.stable.StringUtils; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * @author zhou F * @since 2012-5-9下午4:33:07 @@ -208,7 +210,7 @@ public class UIComboBoxUI extends BasicComboBoxUI implements MouseListener { @Override public void processMouseEvent(MouseEvent e) { if (e.isControlDown()) { - e = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers() ^ InputEvent.CTRL_MASK, e.getX(), e.getY(), e.getClickCount(), + e = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers() ^ DEFAULT_MODIFIER, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); } super.processMouseEvent(e); diff --git a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java index 1ba60ed57..1ec189cc1 100644 --- a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java +++ b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java @@ -32,6 +32,8 @@ import com.fr.design.gui.core.UITabComponent; import com.fr.design.gui.ibutton.UITabButton; import com.fr.stable.StringUtils; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * 本来想弄个延迟加载的,发现在单元格属性表那边没有意义,就算了.这个面板是纯粹的,没有与模板的任何交互操作(比如说populate() update()) * @@ -125,7 +127,7 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { inputMapAncestor.clear(); actionMap.clear(); - inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_MASK), "switch"); + inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, DEFAULT_MODIFIER), "switch"); actionMap.put("switch", new AbstractAction() { /** diff --git a/designer_base/src/com/fr/design/gui/syntax/ui/rtextarea/RTADefaultInputMap.java b/designer_base/src/com/fr/design/gui/syntax/ui/rtextarea/RTADefaultInputMap.java index 5e1a7cfe7..35a1995ed 100644 --- a/designer_base/src/com/fr/design/gui/syntax/ui/rtextarea/RTADefaultInputMap.java +++ b/designer_base/src/com/fr/design/gui/syntax/ui/rtextarea/RTADefaultInputMap.java @@ -41,6 +41,14 @@ import javax.swing.text.DefaultEditorKit; public class RTADefaultInputMap extends InputMap { + /** + * Returns the default modifier key for a system. For example, on Windows + * this would be the CTRL key (InputEvent.CTRL_MASK). + * + * @return The default modifier key. + */ + public static final int DEFAULT_MODIFIER = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + /** * Constructs the default input map for an RTextArea. */ @@ -48,7 +56,7 @@ public class RTADefaultInputMap extends InputMap { super(); - int defaultModifier = getDefaultModifier(); + int defaultModifier = DEFAULT_MODIFIER; //int ctrl = InputEvent.CTRL_MASK; int alt = InputEvent.ALT_MASK; int shift = InputEvent.SHIFT_MASK; @@ -134,18 +142,4 @@ public class RTADefaultInputMap extends InputMap { */ } - - - /** - * Returns the default modifier key for a system. For example, on Windows - * this would be the CTRL key (InputEvent.CTRL_MASK). - * - * @return The default modifier key. - */ - protected static final int getDefaultModifier() { - return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - } - - - } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java index 501f957df..59afdba51 100644 --- a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java +++ b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java @@ -24,6 +24,8 @@ import java.util.Date; import java.util.logging.Handler; import java.util.logging.LogRecord; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class DesignerLogHandler { protected static final int INFO_INT = FRLogLevel.INFO.intValue(); protected static final int ERRO_INT = FRLogLevel.ERROR.intValue(); @@ -158,9 +160,9 @@ public class DesignerLogHandler { clear.setIcon(BaseUtils.readIcon("/com/fr/design/images/log/clear.png")); popup.add(clear); - selectAll.setAccelerator(KeyStroke.getKeyStroke('A', InputEvent.CTRL_MASK)); - copy.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK)); - clear.setAccelerator(KeyStroke.getKeyStroke('L', InputEvent.CTRL_MASK)); + selectAll.setAccelerator(KeyStroke.getKeyStroke('A', DEFAULT_MODIFIER)); + copy.setAccelerator(KeyStroke.getKeyStroke('C', DEFAULT_MODIFIER)); + clear.setAccelerator(KeyStroke.getKeyStroke('L', DEFAULT_MODIFIER)); jTextArea.addMouseListener(new MouseAdapter() { // check for right click diff --git a/designer_base/src/com/fr/design/menu/KeySetUtils.java b/designer_base/src/com/fr/design/menu/KeySetUtils.java index 1b62fcdc4..401da7fb9 100644 --- a/designer_base/src/com/fr/design/menu/KeySetUtils.java +++ b/designer_base/src/com/fr/design/menu/KeySetUtils.java @@ -12,6 +12,8 @@ import javax.swing.*; import java.awt.event.KeyEvent; import java.util.Locale; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Created by IntelliJ IDEA. * Author : daisy @@ -36,7 +38,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_O, DEFAULT_MODIFIER); } }; @@ -71,7 +73,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_W, DEFAULT_MODIFIER); } }; @@ -88,7 +90,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_S, DEFAULT_MODIFIER); } }; @@ -122,7 +124,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_Z, DEFAULT_MODIFIER); } }; @@ -139,7 +141,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_Y, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_Y, DEFAULT_MODIFIER); } }; @@ -156,7 +158,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_E, DEFAULT_MODIFIER); } }; @@ -353,7 +355,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_M, DEFAULT_MODIFIER); } }; @@ -370,7 +372,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_E, DEFAULT_MODIFIER); } }; @@ -387,7 +389,7 @@ public class KeySetUtils { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_E, DEFAULT_MODIFIER); } }; diff --git a/designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java b/designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java index 23686f651..d3906040d 100644 --- a/designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java +++ b/designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java @@ -8,6 +8,8 @@ import javax.swing.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class CopyAction extends FormEditAction { public CopyAction(FormDesigner t) { @@ -15,7 +17,7 @@ public class CopyAction extends FormEditAction { this.setName(Inter.getLocText("M_Edit-Copy")); this.setMnemonic('C'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)); } @Override diff --git a/designer_form/src/com/fr/design/designer/beans/actions/CutAction.java b/designer_form/src/com/fr/design/designer/beans/actions/CutAction.java index 9acb26148..1f81c1280 100644 --- a/designer_form/src/com/fr/design/designer/beans/actions/CutAction.java +++ b/designer_form/src/com/fr/design/designer/beans/actions/CutAction.java @@ -9,6 +9,8 @@ import com.fr.base.BaseUtils; import com.fr.general.Inter; import com.fr.design.mainframe.FormDesigner; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class CutAction extends FormEditAction { public CutAction(FormDesigner t) { @@ -16,7 +18,7 @@ public class CutAction extends FormEditAction { this.setName(Inter.getLocText("M_Edit-Cut")); this.setMnemonic('T'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); } @Override diff --git a/designer_form/src/com/fr/design/designer/beans/actions/PasteAction.java b/designer_form/src/com/fr/design/designer/beans/actions/PasteAction.java index 85ce1d6ed..351a809f6 100644 --- a/designer_form/src/com/fr/design/designer/beans/actions/PasteAction.java +++ b/designer_form/src/com/fr/design/designer/beans/actions/PasteAction.java @@ -9,6 +9,8 @@ import com.fr.base.BaseUtils; import com.fr.general.Inter; import com.fr.design.mainframe.FormDesigner; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class PasteAction extends FormEditAction { public PasteAction(FormDesigner t) { @@ -16,7 +18,7 @@ public class PasteAction extends FormEditAction { this.setName(Inter.getLocText("M_Edit-Paste")); this.setMnemonic('P'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/paste.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)); } @Override diff --git a/designer_form/src/com/fr/design/mainframe/actions/NewFormAction.java b/designer_form/src/com/fr/design/mainframe/actions/NewFormAction.java index 107b9da58..78b17d4b3 100644 --- a/designer_form/src/com/fr/design/mainframe/actions/NewFormAction.java +++ b/designer_form/src/com/fr/design/mainframe/actions/NewFormAction.java @@ -14,6 +14,8 @@ import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class NewFormAction extends UpdateAction { public NewFormAction() { @@ -48,7 +50,7 @@ public class NewFormAction extends UpdateAction { @Override public KeyStroke getKeyStroke() { - return KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK); + return KeyStroke.getKeyStroke(KeyEvent.VK_F, DEFAULT_MODIFIER); } }; } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java index 36c54f4ec..417d761cc 100644 --- a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java +++ b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java @@ -21,6 +21,8 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + public class DataTableConfigPane extends JComponent implements PropertyChangeListener { private DataEditingTable table; @@ -183,7 +185,7 @@ public class DataTableConfigPane extends JComponent implements PropertyChangeLis this.setName(Inter.getLocText("M_Edit-Cut")); this.setMnemonic('T'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK)); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); } @Override From 7c533795e72e2b4744c977fc1546473095562517 Mon Sep 17 00:00:00 2001 From: hzzz Date: Wed, 24 May 2017 10:50:53 +0800 Subject: [PATCH 02/20] =?UTF-8?q?=E4=BF=AElogPane=E7=9A=84=E5=BF=AB?= =?UTF-8?q?=E6=8D=B7=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RSyntaxTextAreaDefaultInputMap.java | 2 +- .../loghandler/DesignerLogHandler.java | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextAreaDefaultInputMap.java b/designer_base/src/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextAreaDefaultInputMap.java index f9171f74a..715ab47fe 100644 --- a/designer_base/src/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextAreaDefaultInputMap.java +++ b/designer_base/src/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextAreaDefaultInputMap.java @@ -34,7 +34,7 @@ public class RSyntaxTextAreaDefaultInputMap extends RTADefaultInputMap { */ public RSyntaxTextAreaDefaultInputMap() { - int defaultMod = getDefaultModifier(); + int defaultMod = DEFAULT_MODIFIER; //int ctrl = InputEvent.CTRL_MASK; int shift = InputEvent.SHIFT_MASK; //int alt = InputEvent.ALT_MASK; diff --git a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java index 59afdba51..8da862fb6 100644 --- a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java +++ b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java @@ -134,8 +134,7 @@ public class DesignerLogHandler { private UIMenuItem clear; private LogHandlerArea() { - jTextArea = new JTextPane(); - + jTextArea = initLogJTextArea(); this.setLayout(FRGUIPaneFactory.createBorderLayout()); UIScrollPane js = new UIScrollPane(jTextArea); this.add(js, BorderLayout.CENTER); @@ -190,6 +189,23 @@ public class DesignerLogHandler { }); } + private JTextPane initLogJTextArea() { + JTextPane resultPane = new JTextPane(); + InputMap inputMap = resultPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), "copy"); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, DEFAULT_MODIFIER), "clear"); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), "select-all"); + ActionMap actionMap = resultPane.getActionMap(); + actionMap.put("clear", new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + resultPane.setText(""); + caption.clearMessage(); + DesignerLogImpl.getInstance().clear(); + } + }); + return resultPane; + } + public void printStackTrace(LogRecordTimeProvider logRecordTime) { LogRecord logRecord = logRecordTime.getLogRecord(); Date date = logRecordTime.getDate(); @@ -299,6 +315,4 @@ public class DesignerLogHandler { }; } - - } \ No newline at end of file From 54c008a3b985d3184129ce87fe4ae711de713188 Mon Sep 17 00:00:00 2001 From: hzzz Date: Wed, 24 May 2017 20:04:04 +0800 Subject: [PATCH 03/20] fix --- .../src/com/fr/design/gui/ilist/UIList.java | 13 +++++++++++++ .../com/fr/design/gui/itextarea/UITextArea.java | 13 +++++++++++++ .../fr/design/gui/itextfield/UITextField.java | 17 ++++++++++++++--- .../gui/itree/checkboxtree/CheckBoxTree.java | 9 +++++++-- .../loghandler/DesignerLogHandler.java | 9 +++------ 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/ilist/UIList.java b/designer_base/src/com/fr/design/gui/ilist/UIList.java index b01f40f0b..2a31fe6c3 100644 --- a/designer_base/src/com/fr/design/gui/ilist/UIList.java +++ b/designer_base/src/com/fr/design/gui/ilist/UIList.java @@ -6,10 +6,14 @@ import com.fr.design.mainframe.JTemplate; import com.fr.stable.StringUtils; import javax.swing.*; +import javax.swing.text.DefaultEditorKit; import java.awt.*; +import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.Vector; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * Created with IntelliJ IDEA. * User: pony @@ -22,6 +26,15 @@ public class UIList extends JList{ public UIList() { super(); + InputMap inputMap = this.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + DefaultEditorKit.selectAllAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), + DefaultEditorKit.copyAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), + DefaultEditorKit.pasteAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), + DefaultEditorKit.cutAction); } public UIList(ListModel dataModel) { diff --git a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java index cf89971b3..8194b10ce 100644 --- a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java +++ b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java @@ -7,13 +7,26 @@ import com.fr.design.utils.gui.GUICoreUtils; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.text.DefaultEditorKit; import java.awt.*; +import java.awt.event.KeyEvent; + +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; public class UITextArea extends JTextArea implements UIObserver { private UIObserverListener uiObserverListener; public UITextArea(int i, int j) { super(i, j); + InputMap inputMap = this.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + DefaultEditorKit.selectAllAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), + DefaultEditorKit.copyAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), + DefaultEditorKit.pasteAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), + DefaultEditorKit.cutAction); initComponents(); } diff --git a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java index 7a451593b..ff4556acb 100644 --- a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java +++ b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java @@ -1,12 +1,12 @@ package com.fr.design.gui.itextfield; import java.awt.*; +import java.awt.event.KeyEvent; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JTextField; +import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; import com.fr.design.event.GlobalNameListener; @@ -16,6 +16,8 @@ import com.fr.design.event.UIObserverListener; import com.fr.stable.Constants; import com.fr.design.utils.gui.GUICoreUtils; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * @author Jerry */ @@ -30,6 +32,15 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs public UITextField() { super(); + InputMap inputMap = this.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + DefaultEditorKit.selectAllAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), + DefaultEditorKit.copyAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), + DefaultEditorKit.pasteAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), + DefaultEditorKit.cutAction); initListener(); } diff --git a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java index 0511504cf..c56efdfd6 100644 --- a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java +++ b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java @@ -16,10 +16,10 @@ import java.beans.PropertyChangeListener; import java.util.Hashtable; import java.util.Vector; -import javax.swing.JTree; -import javax.swing.SwingUtilities; +import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; +import javax.swing.text.DefaultEditorKit; import javax.swing.text.Position; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; @@ -29,6 +29,8 @@ import javax.swing.tree.TreePath; import com.fr.design.gui.icheckbox.UICheckBox; +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + /** * CheckBoxTree is a special JTree which uses UICheckBox as the tree renderer. * In addition to regular JTree's features, it also allows you select any number @@ -87,6 +89,9 @@ public class CheckBoxTree extends JTree { public CheckBoxTree(TreeModel newModel) { super(newModel); + InputMap inputMap = this.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + "selectAll"); init(); } diff --git a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java index 8da862fb6..0bf286e51 100644 --- a/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java +++ b/designer_base/src/com/fr/design/mainframe/loghandler/DesignerLogHandler.java @@ -13,10 +13,7 @@ import com.fr.general.LogRecordTime; import com.fr.stable.xml.LogRecordTimeProvider; import javax.swing.*; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.SimpleAttributeSet; -import javax.swing.text.StyleConstants; +import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.text.SimpleDateFormat; @@ -192,9 +189,9 @@ public class DesignerLogHandler { private JTextPane initLogJTextArea() { JTextPane resultPane = new JTextPane(); InputMap inputMap = resultPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), "copy"); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, DEFAULT_MODIFIER), "clear"); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), "select-all"); ActionMap actionMap = resultPane.getActionMap(); actionMap.put("clear", new AbstractAction() { public void actionPerformed(ActionEvent evt) { From 89564565cdd5098aa3fc242859a3baed3a9c357d Mon Sep 17 00:00:00 2001 From: hzzz Date: Wed, 24 May 2017 20:09:10 +0800 Subject: [PATCH 04/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/fr/design/gui/ilist/UIList.java | 24 ++------ .../fr/design/gui/itextarea/UITextArea.java | 8 +-- .../fr/design/gui/itextfield/UITextField.java | 8 +-- .../gui/itree/checkboxtree/CheckBoxTree.java | 60 +++++++------------ 4 files changed, 37 insertions(+), 63 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/ilist/UIList.java b/designer_base/src/com/fr/design/gui/ilist/UIList.java index 2a31fe6c3..8916cf18c 100644 --- a/designer_base/src/com/fr/design/gui/ilist/UIList.java +++ b/designer_base/src/com/fr/design/gui/ilist/UIList.java @@ -6,14 +6,10 @@ import com.fr.design.mainframe.JTemplate; import com.fr.stable.StringUtils; import javax.swing.*; -import javax.swing.text.DefaultEditorKit; import java.awt.*; -import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.Vector; -import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; - /** * Created with IntelliJ IDEA. * User: pony @@ -21,20 +17,11 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M * Time: 上午11:07 * To change this template use File | Settings | File Templates. */ -public class UIList extends JList{ +public class UIList extends JList { private Icon icon; public UIList() { super(); - InputMap inputMap = this.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), - DefaultEditorKit.selectAllAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), - DefaultEditorKit.copyAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), - DefaultEditorKit.pasteAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), - DefaultEditorKit.cutAction); } public UIList(ListModel dataModel) { @@ -59,12 +46,12 @@ public class UIList extends JList{ if (rendererComp.getPreferredSize().width > getVisibleRect().width) { String tips = (rendererComp instanceof JComponent) ? ((JComponent) rendererComp).getToolTipText() : null; if (tips == null) { - if(value instanceof JTemplate){ + if (value instanceof JTemplate) { tips = ((JTemplate) value).getEditingFILE().getName(); icon = ((JTemplate) value).getEditingFILE().getIcon(); - } else if (value instanceof ListModelElement || value instanceof TableProcedure){ - tips = ((JLabel)rendererComp).getText(); - icon = ((JLabel)rendererComp).getIcon(); + } else if (value instanceof ListModelElement || value instanceof TableProcedure) { + tips = ((JLabel) rendererComp).getText(); + icon = ((JLabel) rendererComp).getIcon(); } } return tips; @@ -84,6 +71,7 @@ public class UIList extends JList{ } return null; } + public JToolTip createToolTip() { UIToolTip tip = new UIToolTip(icon); tip.setComponent(this); diff --git a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java index 8194b10ce..03a70a6ef 100644 --- a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java +++ b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java @@ -19,13 +19,13 @@ public class UITextArea extends JTextArea implements UIObserver { public UITextArea(int i, int j) { super(i, j); InputMap inputMap = this.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), DefaultEditorKit.pasteAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), DefaultEditorKit.cutAction); initComponents(); } diff --git a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java index ff4556acb..0af105058 100644 --- a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java +++ b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java @@ -33,13 +33,13 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs public UITextField() { super(); InputMap inputMap = this.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), DefaultEditorKit.pasteAction); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), DefaultEditorKit.cutAction); initListener(); } diff --git a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java index c56efdfd6..a22264477 100644 --- a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java +++ b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java @@ -5,8 +5,14 @@ */ package com.fr.design.gui.itree.checkboxtree; -import java.awt.Component; -import java.awt.Rectangle; +import com.fr.design.gui.icheckbox.UICheckBox; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.text.Position; +import javax.swing.tree.*; +import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; @@ -16,19 +22,6 @@ import java.beans.PropertyChangeListener; import java.util.Hashtable; import java.util.Vector; -import javax.swing.*; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.text.DefaultEditorKit; -import javax.swing.text.Position; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; - -import com.fr.design.gui.icheckbox.UICheckBox; - import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** @@ -39,11 +32,11 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M * select one or several tree nodes and press SPACE key to toggle the * check box selection for all selected tree nodes. *

- * In order to retrieve which tree paths are selected, you need to call + * In order to retrieve which tree paths are selected, you need to call * {@link #getCheckBoxTreeSelectionModel()}. - * It will return the selection model that keeps track of which tree + * It will return the selection model that keeps track of which tree * paths have been checked. For example - * {@link CheckBoxTreeSelectionModel#getSelectionPaths()} + * {@link CheckBoxTreeSelectionModel#getSelectionPaths()} * will give the list of paths which have * been checked. */ @@ -90,8 +83,7 @@ public class CheckBoxTree extends JTree { public CheckBoxTree(TreeModel newModel) { super(newModel); InputMap inputMap = this.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), - "selectAll"); + inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), "selectAll"); init(); } @@ -116,7 +108,7 @@ public class CheckBoxTree extends JTree { addPropertyChangeListener(JTree.SELECTION_MODEL_PROPERTY, _modelChangeListener); updateRowMapper(); } - + /** * Inserts the mouse listener at the particular index in the listeners' chain. * @@ -127,7 +119,7 @@ public class CheckBoxTree extends JTree { private void insertMouseListener(Component component, MouseListener l, int index) { MouseListener[] listeners = component.getMouseListeners(); for (int i = 0, length = listeners.length; i < length; i++) { - component.removeMouseListener(listeners[i]); + component.removeMouseListener(listeners[i]); } // for (MouseListener listener : listeners) { // component.removeMouseListener(listener); @@ -173,7 +165,7 @@ public class CheckBoxTree extends JTree { * Gets the cell renderer with check box. * * @return CheckBoxTree's own cell renderer which has the check box. The actual cell renderer - * you set by setCellRenderer() can be accessed by using {@link #getActualCellRenderer()}. + * you set by setCellRenderer() can be accessed by using {@link #getActualCellRenderer()}. */ public TreeCellRenderer getCellRenderer() { TreeCellRenderer cellRenderer = super.getCellRenderer(); @@ -182,8 +174,7 @@ public class CheckBoxTree extends JTree { } if (_treeCellRenderer == null) { _treeCellRenderer = createCellRenderer(cellRenderer); - } - else { + } else { _treeCellRenderer.setActualTreeRenderer(cellRenderer); } return _treeCellRenderer; @@ -199,8 +190,7 @@ public class CheckBoxTree extends JTree { public TreeCellRenderer getActualCellRenderer() { if (_treeCellRenderer != null) { return _treeCellRenderer.getActualTreeRenderer(); - } - else { + } else { return super.getCellRenderer(); } } @@ -255,8 +245,7 @@ public class CheckBoxTree extends JTree { if (clicksInCheckBox(e, path)) { return path; - } - else { + } else { return null; } } @@ -264,13 +253,11 @@ public class CheckBoxTree extends JTree { protected boolean clicksInCheckBox(MouseEvent e, TreePath path) { if (!_tree.isCheckBoxVisible(path)) { return false; - } - else { + } else { Rectangle bounds = _tree.getPathBounds(path); if (_tree.getComponentOrientation().isLeftToRight()) { return e.getX() < bounds.x + _hotspot; - } - else { + } else { return e.getX() > bounds.x + bounds.width - _hotspot; } } @@ -354,8 +341,7 @@ public class CheckBoxTree extends JTree { selectionModel.removeSelectionPath(path); else selectionModel.addSelectionPath(path); - } - finally { + } finally { if (!selectionModel.isSingleEventMode()) { selectionModel.setBatchMode(false); } @@ -370,8 +356,8 @@ public class CheckBoxTree extends JTree { return; } for (int i = 0, length = treePaths.length; i < length; i++) { - TreePath tmpTreePath = treePaths[i]; - toggleSelection(tmpTreePath); + TreePath tmpTreePath = treePaths[i]; + toggleSelection(tmpTreePath); } // for (TreePath treePath : treePaths) { // toggleSelection(treePath); From aaa4c1fb0d5edc54c4680a03e1959425b6bd3919 Mon Sep 17 00:00:00 2001 From: hzzz Date: Wed, 24 May 2017 21:00:29 +0800 Subject: [PATCH 05/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- designer/src/com/fr/design/mainframe/FormatBrushAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer/src/com/fr/design/mainframe/FormatBrushAction.java b/designer/src/com/fr/design/mainframe/FormatBrushAction.java index cf4c98448..a2daa7902 100644 --- a/designer/src/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer/src/com/fr/design/mainframe/FormatBrushAction.java @@ -1 +1 @@ -package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; import com.fr.general.Inter; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.*; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** * Author : daisy * Date: 13-8-7 * Time: 上午11:05 */ public class FormatBrushAction extends ElementCaseAction { private ElementCasePane ePane; private CellSelection oldSelection; public FormatBrushAction(ElementCasePane t) { super(t); this.setName(Inter.getLocText("M_Edit-FormatBrush")); this.setMnemonic('B'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); } public boolean executeActionReturnUndoRecordNeeded() { ePane = (ElementCasePane) getEditingComponent(); if (ePane != null) { Selection selection = ePane.getSelection(); if (!(selection instanceof CellSelection)) { return false; } oldSelection = ((CellSelection) selection).clone(); ePane.setFormatReferencedCell(oldSelection); int cellRectangleCount = oldSelection.getCellRectangleCount(); if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; } } //只对单个区域进行格式刷操作 ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); ePane.repaint(); return true; } return false; } /** * 判断是不是连续区域 * * @return */ private boolean isContinueArea() { int xStart = oldSelection.getCellRectangle(1).x; int xend = 0; int yStrat = oldSelection.getCellRectangle(1).y; int yend = 0; int totalNum = 0; for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { Rectangle temp = oldSelection.getCellRectangle(i); if (temp.getX() < xStart) { xStart = temp.x; } if (temp.getX() + temp.getWidth() > xend) { xend = (int) (temp.getX() + temp.getWidth()); } if (temp.getY() < yStrat) { yStrat = temp.y; } if (temp.getY() + temp.getHeight() > yend) { yend = (int) (temp.getY() + temp.getHeight()); } totalNum += (int) (temp.getWidth() * temp.getHeight()); } if ((xend - xStart) * (yend - yStrat) == totalNum) { oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); ePane.setSelection(oldSelection); ePane.setFormatReferencedCell(oldSelection); return true; } return false; } public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; } int rowSpan = referencedStyle[0].length; int columnSpan = referencedStyle.length; //开始进行格式刷样式复制 TemplateElementCase elementCase = reportPane.getEditingElementCase(); int rowNum = cs.getRowSpan(); int columnNum = cs.getColumnSpan(); //如果只点选了一个,则自动补足 if (cs.getColumnSpan() * cs.getRowSpan() == 1) { rowNum = rowSpan; columnNum = columnSpan; } for (int j = 0; j < rowNum; j++) { for (int i = 0; i < columnNum; i++) { int column = i + cs.getColumn(); int row = j + cs.getRow(); TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); } } } private Style[][] getOldStyles(CellSelection oldSelection) { Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; int cellRectangleCount = oldSelection.getCellRectangleCount(); TemplateElementCase elementCase = ePane.getEditingElementCase(); for (int rect = 0; rect < cellRectangleCount; rect++) { Rectangle cellRectangle = oldSelection.getCellRectangle(rect); for (int j = 0; j < cellRectangle.height; j++) { for (int i = 0; i < cellRectangle.width; i++) { int column = i + cellRectangle.x; int row = j + cellRectangle.y; TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } Style style = cellElement.getStyle(); if (style == null) { style = style.DEFAULT_STYLE; } referencedStyle[i][j] = style; } } } return referencedStyle; } } \ No newline at end of file +package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; import com.fr.general.Inter; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** * Author : daisy * Date: 13-8-7 * Time: 上午11:05 */ public class FormatBrushAction extends ElementCaseAction { private ElementCasePane ePane; private CellSelection oldSelection; public FormatBrushAction(ElementCasePane t) { super(t); this.setName(Inter.getLocText("M_Edit-FormatBrush")); this.setMnemonic('B'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); } public boolean executeActionReturnUndoRecordNeeded() { ePane = (ElementCasePane) getEditingComponent(); if (ePane != null) { Selection selection = ePane.getSelection(); if (!(selection instanceof CellSelection)) { return false; } oldSelection = ((CellSelection) selection).clone(); ePane.setFormatReferencedCell(oldSelection); int cellRectangleCount = oldSelection.getCellRectangleCount(); if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; } } //只对单个区域进行格式刷操作 ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); ePane.repaint(); return true; } return false; } /** * 判断是不是连续区域 * * @return */ private boolean isContinueArea() { int xStart = oldSelection.getCellRectangle(1).x; int xend = 0; int yStrat = oldSelection.getCellRectangle(1).y; int yend = 0; int totalNum = 0; for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { Rectangle temp = oldSelection.getCellRectangle(i); if (temp.getX() < xStart) { xStart = temp.x; } if (temp.getX() + temp.getWidth() > xend) { xend = (int) (temp.getX() + temp.getWidth()); } if (temp.getY() < yStrat) { yStrat = temp.y; } if (temp.getY() + temp.getHeight() > yend) { yend = (int) (temp.getY() + temp.getHeight()); } totalNum += (int) (temp.getWidth() * temp.getHeight()); } if ((xend - xStart) * (yend - yStrat) == totalNum) { oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); ePane.setSelection(oldSelection); ePane.setFormatReferencedCell(oldSelection); return true; } return false; } public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; } int rowSpan = referencedStyle[0].length; int columnSpan = referencedStyle.length; //开始进行格式刷样式复制 TemplateElementCase elementCase = reportPane.getEditingElementCase(); int rowNum = cs.getRowSpan(); int columnNum = cs.getColumnSpan(); //如果只点选了一个,则自动补足 if (cs.getColumnSpan() * cs.getRowSpan() == 1) { rowNum = rowSpan; columnNum = columnSpan; } for (int j = 0; j < rowNum; j++) { for (int i = 0; i < columnNum; i++) { int column = i + cs.getColumn(); int row = j + cs.getRow(); TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); } } } private Style[][] getOldStyles(CellSelection oldSelection) { Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; int cellRectangleCount = oldSelection.getCellRectangleCount(); TemplateElementCase elementCase = ePane.getEditingElementCase(); for (int rect = 0; rect < cellRectangleCount; rect++) { Rectangle cellRectangle = oldSelection.getCellRectangle(rect); for (int j = 0; j < cellRectangle.height; j++) { for (int i = 0; i < cellRectangle.width; i++) { int column = i + cellRectangle.x; int row = j + cellRectangle.y; TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } Style style = cellElement.getStyle(); if (style == null) { style = style.DEFAULT_STYLE; } referencedStyle[i][j] = style; } } } return referencedStyle; } } \ No newline at end of file From fbc7daed4f64e582f912d20f1621aaab594f76aa Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 09:41:12 +0800 Subject: [PATCH 06/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/mainframe/FormatBrushAction.java | 172 +++++++++++++++++- .../fr/design/gui/itextarea/UITextArea.java | 23 ++- .../fr/design/gui/itextfield/UITextField.java | 41 +++-- .../gui/itree/checkboxtree/CheckBoxTree.java | 4 - 4 files changed, 210 insertions(+), 30 deletions(-) diff --git a/designer/src/com/fr/design/mainframe/FormatBrushAction.java b/designer/src/com/fr/design/mainframe/FormatBrushAction.java index a2daa7902..84bd160ab 100644 --- a/designer/src/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer/src/com/fr/design/mainframe/FormatBrushAction.java @@ -1 +1,171 @@ -package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; import com.fr.general.Inter; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** * Author : daisy * Date: 13-8-7 * Time: 上午11:05 */ public class FormatBrushAction extends ElementCaseAction { private ElementCasePane ePane; private CellSelection oldSelection; public FormatBrushAction(ElementCasePane t) { super(t); this.setName(Inter.getLocText("M_Edit-FormatBrush")); this.setMnemonic('B'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); } public boolean executeActionReturnUndoRecordNeeded() { ePane = (ElementCasePane) getEditingComponent(); if (ePane != null) { Selection selection = ePane.getSelection(); if (!(selection instanceof CellSelection)) { return false; } oldSelection = ((CellSelection) selection).clone(); ePane.setFormatReferencedCell(oldSelection); int cellRectangleCount = oldSelection.getCellRectangleCount(); if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; } } //只对单个区域进行格式刷操作 ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); ePane.repaint(); return true; } return false; } /** * 判断是不是连续区域 * * @return */ private boolean isContinueArea() { int xStart = oldSelection.getCellRectangle(1).x; int xend = 0; int yStrat = oldSelection.getCellRectangle(1).y; int yend = 0; int totalNum = 0; for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { Rectangle temp = oldSelection.getCellRectangle(i); if (temp.getX() < xStart) { xStart = temp.x; } if (temp.getX() + temp.getWidth() > xend) { xend = (int) (temp.getX() + temp.getWidth()); } if (temp.getY() < yStrat) { yStrat = temp.y; } if (temp.getY() + temp.getHeight() > yend) { yend = (int) (temp.getY() + temp.getHeight()); } totalNum += (int) (temp.getWidth() * temp.getHeight()); } if ((xend - xStart) * (yend - yStrat) == totalNum) { oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); ePane.setSelection(oldSelection); ePane.setFormatReferencedCell(oldSelection); return true; } return false; } public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; } int rowSpan = referencedStyle[0].length; int columnSpan = referencedStyle.length; //开始进行格式刷样式复制 TemplateElementCase elementCase = reportPane.getEditingElementCase(); int rowNum = cs.getRowSpan(); int columnNum = cs.getColumnSpan(); //如果只点选了一个,则自动补足 if (cs.getColumnSpan() * cs.getRowSpan() == 1) { rowNum = rowSpan; columnNum = columnSpan; } for (int j = 0; j < rowNum; j++) { for (int i = 0; i < columnNum; i++) { int column = i + cs.getColumn(); int row = j + cs.getRow(); TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); } } } private Style[][] getOldStyles(CellSelection oldSelection) { Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; int cellRectangleCount = oldSelection.getCellRectangleCount(); TemplateElementCase elementCase = ePane.getEditingElementCase(); for (int rect = 0; rect < cellRectangleCount; rect++) { Rectangle cellRectangle = oldSelection.getCellRectangle(rect); for (int j = 0; j < cellRectangle.height; j++) { for (int i = 0; i < cellRectangle.width; i++) { int column = i + cellRectangle.x; int row = j + cellRectangle.y; TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); if (cellElement == null) { cellElement = new DefaultTemplateCellElement(column, row); elementCase.addCellElement(cellElement); } Style style = cellElement.getStyle(); if (style == null) { style = style.DEFAULT_STYLE; } referencedStyle[i][j] = style; } } } return referencedStyle; } } \ No newline at end of file +package com.fr.design.mainframe; + +import com.fr.base.BaseUtils; +import com.fr.base.Style; +import com.fr.design.actions.ElementCaseAction; +import com.fr.general.Inter; +import com.fr.grid.selection.CellSelection; +import com.fr.grid.selection.Selection; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.TemplateCellElement; +import com.fr.report.elementcase.TemplateElementCase; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + +/** + * Author : daisy + * Date: 13-8-7 + * Time: 上午11:05 + */ +public class FormatBrushAction extends ElementCaseAction { + + private ElementCasePane ePane; + private CellSelection oldSelection; + + + public FormatBrushAction(ElementCasePane t) { + super(t); + this.setName(Inter.getLocText("M_Edit-FormatBrush")); + this.setMnemonic('B'); + this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); + } + + public boolean executeActionReturnUndoRecordNeeded() { + ePane = (ElementCasePane) getEditingComponent(); + if (ePane != null) { + Selection selection = ePane.getSelection(); + if (!(selection instanceof CellSelection)) { + return false; + } + oldSelection = ((CellSelection) selection).clone(); + ePane.setFormatReferencedCell(oldSelection); + int cellRectangleCount = oldSelection.getCellRectangleCount(); + if (cellRectangleCount > 1) { + //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 + //判断是不是连续区域 + //荣国是连续区域,那么这些长方形的长加起来应该等于 + if (!isContinueArea()) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); + ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); + ePane.getFormatBrush().setSelected(false); + return false; + } + } + //只对单个区域进行格式刷操作 + ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); + ePane.repaint(); + return true; + } + return false; + } + + + /** + * 判断是不是连续区域 + * + * @return + */ + private boolean isContinueArea() { + int xStart = oldSelection.getCellRectangle(1).x; + int xend = 0; + int yStrat = oldSelection.getCellRectangle(1).y; + int yend = 0; + int totalNum = 0; + for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { + Rectangle temp = oldSelection.getCellRectangle(i); + if (temp.getX() < xStart) { + xStart = temp.x; + } + if (temp.getX() + temp.getWidth() > xend) { + xend = (int) (temp.getX() + temp.getWidth()); + } + if (temp.getY() < yStrat) { + yStrat = temp.y; + } + if (temp.getY() + temp.getHeight() > yend) { + yend = (int) (temp.getY() + temp.getHeight()); + } + totalNum += (int) (temp.getWidth() * temp.getHeight()); + } + + if ((xend - xStart) * (yend - yStrat) == totalNum) { + oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); + ePane.setSelection(oldSelection); + ePane.setFormatReferencedCell(oldSelection); + return true; + } + return false; + } + + + public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { + //得到被参照的单元格的行列数 + if (referencedStyle == null) { + return; + } + int rowSpan = referencedStyle[0].length; + int columnSpan = referencedStyle.length; + + //开始进行格式刷样式复制 + TemplateElementCase elementCase = reportPane.getEditingElementCase(); + int rowNum = cs.getRowSpan(); + int columnNum = cs.getColumnSpan(); + + + //如果只点选了一个,则自动补足 + if (cs.getColumnSpan() * cs.getRowSpan() == 1) { + rowNum = rowSpan; + columnNum = columnSpan; + } + + for (int j = 0; j < rowNum; j++) { + for (int i = 0; i < columnNum; i++) { + int column = i + cs.getColumn(); + int row = j + cs.getRow(); + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement == null) { + cellElement = new DefaultTemplateCellElement(column, row); + elementCase.addCellElement(cellElement); + } + cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); + } + } + + + } + + + private Style[][] getOldStyles(CellSelection oldSelection) { + Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; + int cellRectangleCount = oldSelection.getCellRectangleCount(); + TemplateElementCase elementCase = ePane.getEditingElementCase(); + for (int rect = 0; rect < cellRectangleCount; rect++) { + Rectangle cellRectangle = oldSelection.getCellRectangle(rect); + for (int j = 0; j < cellRectangle.height; j++) { + for (int i = 0; i < cellRectangle.width; i++) { + int column = i + cellRectangle.x; + int row = j + cellRectangle.y; + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement == null) { + cellElement = new DefaultTemplateCellElement(column, row); + elementCase.addCellElement(cellElement); + } + Style style = cellElement.getStyle(); + if (style == null) { + style = style.DEFAULT_STYLE; + } + + referencedStyle[i][j] = style; + } + } + } + + return referencedStyle; + } + +} \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java index 03a70a6ef..6e04eacb8 100644 --- a/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java +++ b/designer_base/src/com/fr/design/gui/itextarea/UITextArea.java @@ -19,14 +19,21 @@ public class UITextArea extends JTextArea implements UIObserver { public UITextArea(int i, int j) { super(i, j); InputMap inputMap = this.getInputMap(); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), - DefaultEditorKit.selectAllAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), - DefaultEditorKit.copyAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), - DefaultEditorKit.pasteAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), - DefaultEditorKit.cutAction); + while (inputMap.getParent() != null) { + inputMap = inputMap.getParent(); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), DefaultEditorKit.pasteAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), DefaultEditorKit.cutAction); + } initComponents(); } diff --git a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java index 0af105058..4f15b1f81 100644 --- a/designer_base/src/com/fr/design/gui/itextfield/UITextField.java +++ b/designer_base/src/com/fr/design/gui/itextfield/UITextField.java @@ -1,20 +1,19 @@ package com.fr.design.gui.itextfield; -import java.awt.*; -import java.awt.event.KeyEvent; +import com.fr.design.event.GlobalNameListener; +import com.fr.design.event.GlobalNameObserver; +import com.fr.design.event.UIObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.stable.Constants; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; - -import com.fr.design.event.GlobalNameListener; -import com.fr.design.event.GlobalNameObserver; -import com.fr.design.event.UIObserver; -import com.fr.design.event.UIObserverListener; -import com.fr.stable.Constants; -import com.fr.design.utils.gui.GUICoreUtils; +import java.awt.*; +import java.awt.event.KeyEvent; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -33,14 +32,21 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs public UITextField() { super(); InputMap inputMap = this.getInputMap(); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), - DefaultEditorKit.selectAllAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), - DefaultEditorKit.copyAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), - DefaultEditorKit.pasteAction); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), - DefaultEditorKit.cutAction); + while (inputMap.getParent() != null) { + inputMap = inputMap.getParent(); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER), DefaultEditorKit.pasteAction); + } + if (inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)) == null) { + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER), DefaultEditorKit.cutAction); + } initListener(); } @@ -197,6 +203,7 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs /** * 主函数 + * * @param args 参数 */ public static void main(String... args) { diff --git a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java index a22264477..941fd962a 100644 --- a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java +++ b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java @@ -22,8 +22,6 @@ import java.beans.PropertyChangeListener; import java.util.Hashtable; import java.util.Vector; -import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; - /** * CheckBoxTree is a special JTree which uses UICheckBox as the tree renderer. * In addition to regular JTree's features, it also allows you select any number @@ -82,8 +80,6 @@ public class CheckBoxTree extends JTree { public CheckBoxTree(TreeModel newModel) { super(newModel); - InputMap inputMap = this.getInputMap(); - inputMap.getParent().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), "selectAll"); init(); } From 487002536ec56a94949f45d8b28c41920a049e63 Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 09:42:21 +0800 Subject: [PATCH 07/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/mainframe/FormatBrushAction.java | 340 +++++++++--------- 1 file changed, 170 insertions(+), 170 deletions(-) diff --git a/designer/src/com/fr/design/mainframe/FormatBrushAction.java b/designer/src/com/fr/design/mainframe/FormatBrushAction.java index 84bd160ab..ddc9e29dc 100644 --- a/designer/src/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer/src/com/fr/design/mainframe/FormatBrushAction.java @@ -1,171 +1,171 @@ -package com.fr.design.mainframe; - -import com.fr.base.BaseUtils; -import com.fr.base.Style; -import com.fr.design.actions.ElementCaseAction; -import com.fr.general.Inter; -import com.fr.grid.selection.CellSelection; -import com.fr.grid.selection.Selection; -import com.fr.report.cell.DefaultTemplateCellElement; -import com.fr.report.cell.TemplateCellElement; -import com.fr.report.elementcase.TemplateElementCase; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.KeyEvent; - -import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; - -/** - * Author : daisy - * Date: 13-8-7 - * Time: 上午11:05 - */ -public class FormatBrushAction extends ElementCaseAction { - - private ElementCasePane ePane; - private CellSelection oldSelection; - - - public FormatBrushAction(ElementCasePane t) { - super(t); - this.setName(Inter.getLocText("M_Edit-FormatBrush")); - this.setMnemonic('B'); - this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); - } - - public boolean executeActionReturnUndoRecordNeeded() { - ePane = (ElementCasePane) getEditingComponent(); - if (ePane != null) { - Selection selection = ePane.getSelection(); - if (!(selection instanceof CellSelection)) { - return false; - } - oldSelection = ((CellSelection) selection).clone(); - ePane.setFormatReferencedCell(oldSelection); - int cellRectangleCount = oldSelection.getCellRectangleCount(); - if (cellRectangleCount > 1) { - //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 - //判断是不是连续区域 - //荣国是连续区域,那么这些长方形的长加起来应该等于 - if (!isContinueArea()) { - JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); - ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); - ePane.getFormatBrush().setSelected(false); - return false; - } - } - //只对单个区域进行格式刷操作 - ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); - ePane.repaint(); - return true; - } - return false; - } - - - /** - * 判断是不是连续区域 - * - * @return - */ - private boolean isContinueArea() { - int xStart = oldSelection.getCellRectangle(1).x; - int xend = 0; - int yStrat = oldSelection.getCellRectangle(1).y; - int yend = 0; - int totalNum = 0; - for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { - Rectangle temp = oldSelection.getCellRectangle(i); - if (temp.getX() < xStart) { - xStart = temp.x; - } - if (temp.getX() + temp.getWidth() > xend) { - xend = (int) (temp.getX() + temp.getWidth()); - } - if (temp.getY() < yStrat) { - yStrat = temp.y; - } - if (temp.getY() + temp.getHeight() > yend) { - yend = (int) (temp.getY() + temp.getHeight()); - } - totalNum += (int) (temp.getWidth() * temp.getHeight()); - } - - if ((xend - xStart) * (yend - yStrat) == totalNum) { - oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); - ePane.setSelection(oldSelection); - ePane.setFormatReferencedCell(oldSelection); - return true; - } - return false; - } - - - public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { - //得到被参照的单元格的行列数 - if (referencedStyle == null) { - return; - } - int rowSpan = referencedStyle[0].length; - int columnSpan = referencedStyle.length; - - //开始进行格式刷样式复制 - TemplateElementCase elementCase = reportPane.getEditingElementCase(); - int rowNum = cs.getRowSpan(); - int columnNum = cs.getColumnSpan(); - - - //如果只点选了一个,则自动补足 - if (cs.getColumnSpan() * cs.getRowSpan() == 1) { - rowNum = rowSpan; - columnNum = columnSpan; - } - - for (int j = 0; j < rowNum; j++) { - for (int i = 0; i < columnNum; i++) { - int column = i + cs.getColumn(); - int row = j + cs.getRow(); - TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); - if (cellElement == null) { - cellElement = new DefaultTemplateCellElement(column, row); - elementCase.addCellElement(cellElement); - } - cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); - } - } - - - } - - - private Style[][] getOldStyles(CellSelection oldSelection) { - Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; - int cellRectangleCount = oldSelection.getCellRectangleCount(); - TemplateElementCase elementCase = ePane.getEditingElementCase(); - for (int rect = 0; rect < cellRectangleCount; rect++) { - Rectangle cellRectangle = oldSelection.getCellRectangle(rect); - for (int j = 0; j < cellRectangle.height; j++) { - for (int i = 0; i < cellRectangle.width; i++) { - int column = i + cellRectangle.x; - int row = j + cellRectangle.y; - TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); - if (cellElement == null) { - cellElement = new DefaultTemplateCellElement(column, row); - elementCase.addCellElement(cellElement); - } - Style style = cellElement.getStyle(); - if (style == null) { - style = style.DEFAULT_STYLE; - } - - referencedStyle[i][j] = style; - } - } - } - - return referencedStyle; - } - +package com.fr.design.mainframe; + +import com.fr.base.BaseUtils; +import com.fr.base.Style; +import com.fr.design.actions.ElementCaseAction; +import com.fr.general.Inter; +import com.fr.grid.selection.CellSelection; +import com.fr.grid.selection.Selection; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.TemplateCellElement; +import com.fr.report.elementcase.TemplateElementCase; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; + +/** + * Author : daisy + * Date: 13-8-7 + * Time: 上午11:05 + */ +public class FormatBrushAction extends ElementCaseAction { + + private ElementCasePane ePane; + private CellSelection oldSelection; + + + public FormatBrushAction(ElementCasePane t) { + super(t); + this.setName(Inter.getLocText("M_Edit-FormatBrush")); + this.setMnemonic('B'); + this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/formatBrush.png")); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, DEFAULT_MODIFIER)); + } + + public boolean executeActionReturnUndoRecordNeeded() { + ePane = (ElementCasePane) getEditingComponent(); + if (ePane != null) { + Selection selection = ePane.getSelection(); + if (!(selection instanceof CellSelection)) { + return false; + } + oldSelection = ((CellSelection) selection).clone(); + ePane.setFormatReferencedCell(oldSelection); + int cellRectangleCount = oldSelection.getCellRectangleCount(); + if (cellRectangleCount > 1) { + //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 + //判断是不是连续区域 + //荣国是连续区域,那么这些长方形的长加起来应该等于 + if (!isContinueArea()) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); + ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); + ePane.getFormatBrush().setSelected(false); + return false; + } + } + //只对单个区域进行格式刷操作 + ((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(false); + ePane.repaint(); + return true; + } + return false; + } + + + /** + * 判断是不是连续区域 + * + * @return + */ + private boolean isContinueArea() { + int xStart = oldSelection.getCellRectangle(1).x; + int xend = 0; + int yStrat = oldSelection.getCellRectangle(1).y; + int yend = 0; + int totalNum = 0; + for (int i = 0; i < oldSelection.getCellRectangleCount(); i++) { + Rectangle temp = oldSelection.getCellRectangle(i); + if (temp.getX() < xStart) { + xStart = temp.x; + } + if (temp.getX() + temp.getWidth() > xend) { + xend = (int) (temp.getX() + temp.getWidth()); + } + if (temp.getY() < yStrat) { + yStrat = temp.y; + } + if (temp.getY() + temp.getHeight() > yend) { + yend = (int) (temp.getY() + temp.getHeight()); + } + totalNum += (int) (temp.getWidth() * temp.getHeight()); + } + + if ((xend - xStart) * (yend - yStrat) == totalNum) { + oldSelection = new CellSelection(xStart, yStrat, (xend - xStart), (yend - yStrat)); + ePane.setSelection(oldSelection); + ePane.setFormatReferencedCell(oldSelection); + return true; + } + return false; + } + + + public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { + //得到被参照的单元格的行列数 + if (referencedStyle == null) { + return; + } + int rowSpan = referencedStyle[0].length; + int columnSpan = referencedStyle.length; + + //开始进行格式刷样式复制 + TemplateElementCase elementCase = reportPane.getEditingElementCase(); + int rowNum = cs.getRowSpan(); + int columnNum = cs.getColumnSpan(); + + + //如果只点选了一个,则自动补足 + if (cs.getColumnSpan() * cs.getRowSpan() == 1) { + rowNum = rowSpan; + columnNum = columnSpan; + } + + for (int j = 0; j < rowNum; j++) { + for (int i = 0; i < columnNum; i++) { + int column = i + cs.getColumn(); + int row = j + cs.getRow(); + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement == null) { + cellElement = new DefaultTemplateCellElement(column, row); + elementCase.addCellElement(cellElement); + } + cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); + } + } + + + } + + + private Style[][] getOldStyles(CellSelection oldSelection) { + Style[][] referencedStyle = new Style[oldSelection.getColumnSpan()][oldSelection.getRowSpan()]; + int cellRectangleCount = oldSelection.getCellRectangleCount(); + TemplateElementCase elementCase = ePane.getEditingElementCase(); + for (int rect = 0; rect < cellRectangleCount; rect++) { + Rectangle cellRectangle = oldSelection.getCellRectangle(rect); + for (int j = 0; j < cellRectangle.height; j++) { + for (int i = 0; i < cellRectangle.width; i++) { + int column = i + cellRectangle.x; + int row = j + cellRectangle.y; + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement == null) { + cellElement = new DefaultTemplateCellElement(column, row); + elementCase.addCellElement(cellElement); + } + Style style = cellElement.getStyle(); + if (style == null) { + style = style.DEFAULT_STYLE; + } + + referencedStyle[i][j] = style; + } + } + } + + return referencedStyle; + } + } \ No newline at end of file From e26becc6847f20291aabcb06f537ec7fb203837c Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 13:52:51 +0800 Subject: [PATCH 08/20] PMD --- .../design/mainframe/FormatBrushAction.java | 2 +- .../autocomplete/AutoCompletePopupWindow.java | 16 +- .../gui/autocomplete/AutoCompletion.java | 2590 ++++++++--------- .../ParameterizedCompletionContext.java | 4 +- .../gui/itabpane/UITabsHeaderIconPane.java | 10 +- .../gui/itree/checkboxtree/CheckBoxTree.java | 6 +- .../com/fr/design/locale/designer.properties | 2 +- .../design/locale/designer_en_US.properties | 2 +- .../design/locale/designer_ja_JP.properties | 2 +- .../design/locale/designer_ko_KR.properties | 2 +- .../design/locale/designer_zh_CN.properties | 2 +- .../design/locale/designer_zh_TW.properties | 2 +- .../widget/editors/DataTableConfigPane.java | 475 +-- 13 files changed, 1552 insertions(+), 1563 deletions(-) diff --git a/designer/src/com/fr/design/mainframe/FormatBrushAction.java b/designer/src/com/fr/design/mainframe/FormatBrushAction.java index ddc9e29dc..f77bda9eb 100644 --- a/designer/src/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer/src/com/fr/design/mainframe/FormatBrushAction.java @@ -50,7 +50,7 @@ public class FormatBrushAction extends ElementCaseAction { //判断是不是连续区域 //荣国是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { - JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("Can_not_use_FormatBursh")); + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("FR-Designer_Can_not_use_FormatBursh")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); ePane.getFormatBrush().setSelected(false); return false; diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java index c5efadc5c..40b3d7ca2 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java @@ -179,7 +179,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, } else { doAutocomplete(); } - } else if (AutoCompletion.getDebug()) { + } else if (AutoCompletion.isDebug()) { Thread.dumpStack(); } } @@ -300,7 +300,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, */ private void installKeyBindings() { - if (AutoCompletion.getDebug()) { + if (AutoCompletion.isDebug()) { System.out.println("PopupWindow: Installing keybindings"); } @@ -313,7 +313,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ActionMap am = comp.getActionMap(); replaceAction(im, am, KeyEvent.VK_ESCAPE, escapeKap, oldEscape); - if (AutoCompletion.getDebug() && oldEscape.action == escapeKap.action) { + if (AutoCompletion.isDebug() && oldEscape.action == escapeKap.action) { Thread.dumpStack(); } replaceAction(im, am, KeyEvent.VK_UP, upKap, oldUp); @@ -371,7 +371,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, */ private void positionDescWindow() { - boolean showDescWindow = descWindow != null && ac.getShowDescWindow(); + boolean showDescWindow = descWindow != null && ac.isShowDescWindow(); if (!showDescWindow) { return; } @@ -604,7 +604,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, Rectangle screenBounds = Util.getScreenBoundsForPoint(r.x, r.y); //Dimension screenSize = getToolkit().getScreenSize(); - boolean showDescWindow = descWindow != null && ac.getShowDescWindow(); + boolean showDescWindow = descWindow != null && ac.isShowDescWindow(); int totalH = getHeight(); if (showDescWindow) { totalH = Math.max(totalH, descWindow.getHeight()); @@ -655,7 +655,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, installKeyBindings(); lastLine = ac.getLineOfCaret(); selectFirstItem(); - if (descWindow == null && ac.getShowDescWindow()) { + if (descWindow == null && ac.isShowDescWindow()) { descWindow = createDescriptionWindow(); positionDescWindow(); } @@ -693,7 +693,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, // 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.getShowDescWindow()); + descWindow.setVisible(visible && ac.isShowDescWindow()); } } @@ -708,7 +708,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, */ private void uninstallKeyBindings() { - if (AutoCompletion.getDebug()) { + if (AutoCompletion.isDebug()) { System.out.println("PopupWindow: Removing keybindings"); } diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java index 122beb1e6..d5447880b 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java @@ -8,17 +8,17 @@ */ package com.fr.design.gui.autocomplete; -import java.awt.*; -import java.awt.event.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.List; import javax.swing.*; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.*; +import java.awt.*; +import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -26,20 +26,20 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M /** * Adds auto-completion to a text component. Provides a popup window with a * list of auto-complete choices on a given keystroke, such as Crtrl+Space.

- * + *

* Depending on the {@link CompletionProvider} installed, the following * auto-completion features may be enabled: - * + *

*

    - *
  • An auto-complete choices list made visible via e.g. Ctrl+Space
  • - *
  • A "description" window displayed alongside the choices list that - * provides documentation on the currently selected completion choice - * (as seen in Eclipse and NetBeans).
  • - *
  • Parameter assistance. If this is enabled, if the user enters a - * "parameterized" completion, such as a method or a function, then - * they will receive a tool tip describing the arguments they have to - * enter to the completion. Also, the arguments can be navigated via - * tab and shift+tab (a la Eclipse and NetBeans).
  • + *
  • An auto-complete choices list made visible via e.g. Ctrl+Space
  • + *
  • A "description" window displayed alongside the choices list that + * provides documentation on the currently selected completion choice + * (as seen in Eclipse and NetBeans).
  • + *
  • Parameter assistance. If this is enabled, if the user enters a + * "parameterized" completion, such as a method or a function, then + * they will receive a tool tip describing the arguments they have to + * enter to the completion. Also, the arguments can be navigated via + * tab and shift+tab (a la Eclipse and NetBeans).
  • *
* * @author Robert Futrell @@ -53,1293 +53,1277 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M */ public class AutoCompletion { - /** - * The text component we're providing completion for. - */ - private JTextComponent textComponent; - - /** - * The parent window of {@link #textComponent}. - */ - private Window parentWindow; - - /** - * The popup window containing completion choices. - */ - private AutoCompletePopupWindow popupWindow; - - /** - * The preferred size of the completion choices window. This field exists - * because the user will likely set the preferred size of the window - * before it is actually created. - */ - private Dimension preferredChoicesWindowSize; - - /** - * 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; - - /** - * Manages any parameterized completions that are inserted. - */ - private ParameterizedCompletionContext pcc; - - /** - * Provides the completion options relevant to the current caret position. - */ - private CompletionProvider provider; - - /** - * The renderer to use for the completion choices. If this is - * null, then a default renderer is used. - */ - private ListCellRenderer renderer; - - /** - * The handler to use when an external URL is clicked in the help - * documentation. - */ - private ExternalURLHandler externalURLHandler; - - /** - * An optional redirector that converts URL's to some other location before - * being handed over to externalURLHandler. - */ - private static LinkRedirector linkRedirector; - - /** - * Whether the description window should be displayed along with the - * completion choice window. - */ - private boolean showDescWindow; - - /** - * Whether auto-complete is enabled. - */ - private boolean autoCompleteEnabled; - - /** - * Whether the auto-activation of auto-complete (after a delay, after the - * user types an appropriate character) is enabled. - */ - private boolean autoActivationEnabled; - - /** - * Whether or not, when there is only a single auto-complete option - * that matches the text at the current text position, that text should - * be auto-inserted, instead of the completion window displaying. - */ - private boolean autoCompleteSingleChoices; - - /** - * Whether parameter assistance is enabled. - */ - private boolean parameterAssistanceEnabled; - - /** - * A renderer used for {@link Completion}s in the optional parameter - * choices popup window (displayed when a {@link ParameterizedCompletion} - * is code-completed). If this isn't set, a default renderer is used. - */ - private ListCellRenderer paramChoicesRenderer; - - /** - * The keystroke that triggers the completion window. - */ - private KeyStroke trigger; - - /** - * The previous key in the text component's InputMap for the - * trigger key. - */ - private Object oldTriggerKey; - - /** - * The action previously assigned to {@link #trigger}, so we can reset it - * if the user disables auto-completion. - */ - private Action oldTriggerAction; - - /** - * The previous key in the text component's InputMap for the - * parameter completion trigger key. - */ - private Object oldParenKey; - - /** - * The action previously assigned to the parameter completion key, so we - * can reset it when we uninstall. - */ - private Action oldParenAction; - - /** - * Listens for events in the parent window that affect the visibility of - * the popup windows. - */ - private ParentWindowListener parentWindowListener; - - /** - * Listens for events from the text component that affect the visibility - * of the popup windows. - */ - private TextComponentListener textComponentListener; - - /** - * Listens for events in the text component that cause the popup windows - * to automatically activate. - */ - private AutoActivationListener autoActivationListener; - - /** - * Listens for LAF changes so the auto-complete windows automatically - * update themselves accordingly. - */ - private LookAndFeelChangeListener lafListener; - - /** - * The key used in the input map for the AutoComplete action. - */ - private static final String PARAM_TRIGGER_KEY = "AutoComplete"; - - /** - * Key used in the input map for the parameter completion action. - */ - private static final String PARAM_COMPLETE_KEY = "AutoCompletion.FunctionStart"; - - /** - * Stores how to render auto-completion-specific highlights in text - * components. - */ - private static final AutoCompletionStyleContext styleContext = - new AutoCompletionStyleContext(); - - /** - * Whether debug messages should be printed to stdout as AutoCompletion - * runs. - */ - private static final boolean DEBUG = initDebug(); - - - /** - * Constructor. - * - * @param provider The completion provider. This cannot be - * null. - */ - public AutoCompletion(CompletionProvider provider) { - - setChoicesWindowSize(350, 200); - setDescriptionWindowSize(350, 250); - - setCompletionProvider(provider); - setTriggerKey(getDefaultTriggerKey()); - setAutoCompleteEnabled(true); - setAutoCompleteSingleChoices(true); - setAutoActivationEnabled(false); - setShowDescWindow(false); - parentWindowListener = new ParentWindowListener(); - textComponentListener = new TextComponentListener(); - autoActivationListener = new AutoActivationListener(); - lafListener = new LookAndFeelChangeListener(); - - } - - - /** - * Displays the popup window. Hosting applications can call this method - * to programmatically begin an auto-completion operation. - */ - public void doCompletion() { - refreshPopupWindow(); - } - - - /** - * Returns the delay between when the user types a character and when the - * code completion popup should automatically appear (if applicable). - * - * @return The delay, in milliseconds. - * @see #setAutoActivationDelay(int) - */ - public int getAutoActivationDelay() { - return autoActivationListener.timer.getDelay(); - } - - - /** - * Returns whether, if a single auto-complete choice is available, it - * should be automatically inserted, without displaying the popup menu. - * - * @return Whether to auto-complete single choices. - * @see #setAutoCompleteSingleChoices(boolean) - */ - public boolean getAutoCompleteSingleChoices() { - return autoCompleteSingleChoices; - } - - - /** - * Returns the completion provider. - * - * @return The completion provider. - */ - public CompletionProvider getCompletionProvider() { - return provider; - } - - - /** - * Returns whether debug is enabled for AutoCompletion. - * - * @return Whether debug is enabled. - */ - static boolean getDebug() { - return DEBUG; - } - - - /** - * Returns the default auto-complete "trigger key" for this OS. For - * Windows, for example, it is Ctrl+Space. - * - * @return The default auto-complete trigger key. - */ - public static KeyStroke getDefaultTriggerKey() { - // Default to CTRL, even on Mac, since Ctrl+Space activates Spotlight - return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, DEFAULT_MODIFIER); - } - - - /** - * Returns the handler to use when an external URL is clicked in the - * description window. - * - * @return The handler. - * @see #setExternalURLHandler(ExternalURLHandler) - * @see #getLinkRedirector() - */ - public ExternalURLHandler getExternalURLHandler() { - return externalURLHandler; - } - - - int getLineOfCaret() { - Document doc = textComponent.getDocument(); - Element root = doc.getDefaultRootElement(); - return root.getElementIndex(textComponent.getCaretPosition()); - } - - - /** - * Returns the link redirector, if any. - * - * @return The link redirector, or null if none. - * @see #setLinkRedirector(LinkRedirector) - */ - public static LinkRedirector getLinkRedirector() { - return linkRedirector; - } - - - /** - * 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() { - return renderer; - } - - - /** - * Returns the renderer to use for {@link Completion}s in the optional - * parameter choices popup window (displayed when a - * {@link ParameterizedCompletion} is code-completed). If this returns - * null, a default renderer is used. - * - * @return The renderer to use. - * @see #setParamChoicesRenderer(ListCellRenderer) - * @see #isParameterAssistanceEnabled() - */ - public ListCellRenderer getParamChoicesRenderer() { - return paramChoicesRenderer; - } - - - /** - * Returns the text to replace with in the document. This is a - * "last-chance" hook for subclasses to make special modifications to the - * completion text inserted. The default implementation simply returns - * c.getReplacementText(). You usually will not need to modify - * this method. - * - * @param c The completion being inserted. - * @param doc The document being modified. - * @param start The start of the text being replaced. - * @param len The length of the text being replaced. - * @return The text to replace with. - */ - protected String getReplacementText(Completion c, Document doc, int start, - int len) { - return c.getReplacementText(); - } - - - /** - * Returns whether the "description window" should be shown alongside - * the completion window. - * - * @return Whether the description window should be shown. - * @see #setShowDescWindow(boolean) - */ - public boolean getShowDescWindow() { - return showDescWindow; - } - - - /** - * Returns the style context describing how auto-completion related - * highlights in the editor are rendered. - * - * @return The style context. - */ - public static AutoCompletionStyleContext getStyleContext() { - return styleContext; - } - - - /** - * Returns the text component for which auto-completion is enabled. - * - * @return The text component, or null if this - * {@link AutoCompletion} is not installed on any text component. - * @see #install(JTextComponent) - */ - public JTextComponent getTextComponent() { - return textComponent; - } - - - /** - * Returns the orientation of the text component we're installed to. - * - * @return The orientation of the text component, or null if - * we are not installed on one. - */ - ComponentOrientation getTextComponentOrientation() { - return textComponent==null ? null : - textComponent.getComponentOrientation(); - } - - - /** - * Returns the "trigger key" used for auto-complete. - * - * @return The trigger key. - * @see #setTriggerKey(KeyStroke) - */ - public KeyStroke getTriggerKey() { - return trigger; - } - - - /** - * Hides any child windows being displayed by the auto-completion system. - * - * @return Whether any windows were visible. - */ - public boolean hideChildWindows() { - //return hidePopupWindow() || hideToolTipWindow(); - boolean res = hidePopupWindow(); - res |= hideParameterCompletionPopups(); - return res; - } - - - /** - * Hides and disposes of any parameter completion-related popups. - * - * @return Whether any such windows were visible (and thus hidden). - */ - private boolean hideParameterCompletionPopups() { - if (pcc!=null) { - pcc.deactivate(); - pcc = null; - return true; - } - return false; - } - - - /** - * Hides the popup window, if it is visible. - * - * @return Whether the popup window was visible. - */ - private boolean hidePopupWindow() { - if (popupWindow!=null) { - if (popupWindow.isVisible()) { - popupWindow.setVisible(false); - return true; - } - } - return false; - } - - - /** - * Determines whether debug should be enabled for the AutoCompletion - * library. This method checks a system property, but takes care of - * {@link SecurityException}s in case we're in an applet or WebStart. - * - * @return Whether debug should be enabled. - */ - private static final boolean initDebug() { - boolean debug = false; - try { - debug = Boolean.getBoolean("AutoCompletion.debug"); - } catch (SecurityException se) { // We're in an applet or WebStart. - debug = false; - } - return debug; - } - - - /** - * Inserts a completion. Any time a code completion event occurs, the - * actual text insertion happens through this method. - * - * @param c A completion to insert. This cannot be null. - */ - protected final void insertCompletion(Completion c) { - insertCompletion(c, false); - } - - - /** - * Inserts a completion. Any time a code completion event occurs, the - * actual text insertion happens through this method. - * - * @param c A completion to insert. This cannot be null. - * @param typedParamListStartChar Whether the parameterized completion - * start character was typed (typically '('). - */ - protected void insertCompletion(Completion c, - boolean typedParamListStartChar) { - - JTextComponent textComp = getTextComponent(); - String alreadyEntered = c.getAlreadyEntered(textComp); - hidePopupWindow(); - Caret caret = textComp.getCaret(); - - int dot = caret.getDot(); - int len = alreadyEntered.length(); - int start = dot-len; - String replacement = getReplacementText(c, textComp.getDocument(), - start, len); - - caret.setDot(start); - caret.moveDot(dot); - textComp.replaceSelection(replacement); - - if (isParameterAssistanceEnabled() && - (c instanceof ParameterizedCompletion)) { - ParameterizedCompletion pc = (ParameterizedCompletion)c; - startParameterizedCompletionAssistance(pc, typedParamListStartChar); - } - - } - - - /** - * Installs this auto-completion on a text component. If this - * {@link AutoCompletion} is already installed on another text component, - * it is uninstalled first. - * - * @param c The text component. - * @see #uninstall() - */ - public void install(JTextComponent c) { - - if (textComponent!=null) { - uninstall(); - } - - this.textComponent = c; - installTriggerKey(getTriggerKey()); - - // Install the function completion key, if there is one. - // NOTE: We cannot do this if the start char is ' ' (e.g. just a space - // between the function name and parameters) because it overrides - // RSTA's special space action. It seems KeyStorke.getKeyStroke(' ') - // hoses ctrl+space, shift+space, etc., even though I think it - // shouldn't... - char start = provider.getParameterListStart(); - if (start!=0 && start!=' ') { - InputMap im = c.getInputMap(); - ActionMap am = c.getActionMap(); - KeyStroke ks = KeyStroke.getKeyStroke(start); - oldParenKey = im.get(ks); - im.put(ks, PARAM_COMPLETE_KEY); - oldParenAction = am.get(PARAM_COMPLETE_KEY); - am.put(PARAM_COMPLETE_KEY, - new ParameterizedCompletionStartAction(start)); - } - - textComponentListener.addTo(this.textComponent); - // In case textComponent is already in a window... - textComponentListener.hierarchyChanged(null); - - if (isAutoActivationEnabled()) { - autoActivationListener.addTo(this.textComponent); - } - - UIManager.addPropertyChangeListener(lafListener); - updateUI(); // In case there have been changes since we uninstalled - - } - - - /** - * Installs a "trigger key" action onto the current text component. - * - * @param ks The keystroke that should trigger the action. - * @see #uninstallTriggerKey() - */ - private void installTriggerKey(KeyStroke ks) { - InputMap im = textComponent.getInputMap(); - oldTriggerKey = im.get(ks); - im.put(ks, PARAM_TRIGGER_KEY); - ActionMap am = textComponent.getActionMap(); - oldTriggerAction = am.get(PARAM_TRIGGER_KEY); - am.put(PARAM_TRIGGER_KEY, new AutoCompleteAction()); - } - - - /** - * Returns whether auto-activation is enabled (that is, whether the - * completion popup will automatically appear after a delay when the user - * types an appropriate character). Note that this parameter will be - * ignored if auto-completion is disabled. - * - * @return Whether auto-activation is enabled. - * @see #setAutoActivationEnabled(boolean) - * @see #getAutoActivationDelay() - * @see #isAutoCompleteEnabled() - */ - public boolean isAutoActivationEnabled() { - return autoActivationEnabled; - } - - - /** - * Returns whether auto-completion is enabled. - * - * @return Whether auto-completion is enabled. - * @see #setAutoCompleteEnabled(boolean) - */ - public boolean isAutoCompleteEnabled() { - return autoCompleteEnabled; - } - - - /** - * Returns whether parameter assistance is enabled. - * - * @return Whether parameter assistance is enabled. - * @see #setParameterAssistanceEnabled(boolean) - */ - public boolean isParameterAssistanceEnabled() { - return parameterAssistanceEnabled; - } - - - /** - * Returns whether the completion popup window is visible. - * - * @return Whether the completion popup window is visible. - */ - public boolean isPopupVisible() { - return popupWindow!=null && popupWindow.isVisible(); - } - - - /** - * Refreshes the popup window. First, this method gets the possible - * completions for the current caret position. If there are none, and the - * popup is visible, it is hidden. If there are some completions and the - * popup is hidden, it is made visible and made to display the completions. - * If there are some completions and the popup is visible, its list is - * updated to the current set of completions. - * - * @return The current line number of the caret. - */ - protected int refreshPopupWindow() { - - // A return value of null => don't suggest completions - String text = provider.getAlreadyEnteredText(textComponent); - if (text==null && !isPopupVisible()) { - return getLineOfCaret(); - } - - // If the popup is currently visible, and they type a space (or any - // character that resets the completion list to "all completions"), - // the popup window should be hidden instead of being reset to show - // everything. - int textLen = text==null ? 0 : text.length(); - if (textLen==0) { - if (isPopupVisible()) { - hidePopupWindow(); - return getLineOfCaret(); - } - } - - final List completions = provider. - getCompletions(textComponent); - int count = completions.size(); - - if (count>1 || (count==1 && (isPopupVisible() || textLen==0)) || - (count==1 && !getAutoCompleteSingleChoices())) { - - if (popupWindow==null) { - popupWindow = new AutoCompletePopupWindow(parentWindow, this); - // Completion is usually done for code, which is always done - // LTR, so make completion stuff RTL only if text component is - // also RTL. - popupWindow.applyComponentOrientation( - getTextComponentOrientation()); - if (renderer!=null) { - popupWindow.setListCellRenderer(renderer); - } - if (preferredChoicesWindowSize!=null) { - popupWindow.setSize(preferredChoicesWindowSize); - } - if (preferredDescWindowSize!=null) { - popupWindow.setDescriptionWindowSize( - preferredDescWindowSize); - } - } - - popupWindow.setCompletions(completions); - - if (!popupWindow.isVisible()) { - Rectangle r = null; - try { - r = textComponent.modelToView(textComponent. - getCaretPosition()); - } catch (BadLocationException ble) { - - return -1; - } - Point p = new Point(r.x, r.y); - SwingUtilities.convertPointToScreen(p, textComponent); - r.x = p.x; - r.y = p.y; - popupWindow.setLocationRelativeTo(r); - popupWindow.setVisible(true); - } - - } - - else if (count==1) { // !isPopupVisible && autoCompleteSingleChoices - SwingUtilities.invokeLater(new Runnable() { - public void run() { - insertCompletion(completions.get(0)); - } - }); - } - - else { - hidePopupWindow(); - } - - return getLineOfCaret(); - - } - - - /** - * Sets the delay between when the user types a character and when the - * code completion popup should automatically appear (if applicable). - * - * @param ms The delay, in milliseconds. This should be greater than zero. - * @see #getAutoActivationDelay() - */ - public void setAutoActivationDelay(int ms) { - ms = Math.max(0, ms); - autoActivationListener.timer.stop(); - autoActivationListener.timer.setInitialDelay(ms); - } - - - /** - * Toggles whether auto-activation is enabled. Note that auto-activation - * also depends on auto-completion itself being enabled. - * - * @param enabled Whether auto-activation is enabled. - * @see #isAutoActivationEnabled() - * @see #setAutoActivationDelay(int) - */ - public void setAutoActivationEnabled(boolean enabled) { - if (enabled!=autoActivationEnabled) { - autoActivationEnabled = enabled; - if (textComponent!=null) { - if (autoActivationEnabled) { - autoActivationListener.addTo(textComponent); - } - else { - autoActivationListener.removeFrom(textComponent); - } - } - } - } - - - /** - * Sets whether auto-completion is enabled. - * - * @param enabled Whether auto-completion is enabled. - * @see #isAutoCompleteEnabled() - */ - public void setAutoCompleteEnabled(boolean enabled) { - if (enabled!=autoCompleteEnabled) { - autoCompleteEnabled = enabled; - hidePopupWindow(); - } - } - - - /** - * Sets whether, if a single auto-complete choice is available, it should - * be automatically inserted, without displaying the popup menu. - * - * @param autoComplete Whether to auto-complete single choices. - * @see #getAutoCompleteSingleChoices() - */ - public void setAutoCompleteSingleChoices(boolean autoComplete) { - autoCompleteSingleChoices = autoComplete; - } - - - /** - * Sets the completion provider being used. - * - * @param provider The new completion provider. This cannot be - * null. - * @throws IllegalArgumentException If provider is - * null. - */ - public void setCompletionProvider(CompletionProvider provider) { - if (provider==null) { - throw new IllegalArgumentException("provider cannot be null"); - } - this.provider = provider; - hidePopupWindow(); // In case new choices should be displayed. - } - - - /** - * Sets the size of the completion choices window. - * - * @param w The new width. - * @param h The new height. - * @see #setDescriptionWindowSize(int, int) - */ - public void setChoicesWindowSize(int w, int h) { - preferredChoicesWindowSize = new Dimension(w, h); - if (popupWindow!=null) { - popupWindow.setSize(preferredChoicesWindowSize); - } - } - - - /** - * Sets the size of the description window. - * - * @param w The new width. - * @param h The new height. - * @see #setChoicesWindowSize(int, int) - */ - public void setDescriptionWindowSize(int w, int h) { - preferredDescWindowSize = new Dimension(w, h); - if (popupWindow!=null) { - popupWindow.setDescriptionWindowSize(preferredDescWindowSize); - } - } - - - /** - * Sets the handler to use when an external URL is clicked in the - * description window. This handler can perform some action, such as - * open the URL in a web browser. The default implementation will open - * the URL in a browser, but only if running in Java 6. If you want - * browser support for Java 5 and below, or otherwise want to respond to - * hyperlink clicks, you will have to install your own handler to do so. - * - * @param handler The new handler. - * @see #getExternalURLHandler() - */ - public void setExternalURLHandler(ExternalURLHandler handler) { - this.externalURLHandler = handler; - } - - - /** - * Sets the redirector for external URL's found in code completion - * documentation. When a non-local link in completion popups is clicked, - * this redirector is given the chance to modify the URL fetched and - * displayed. - * - * @param linkRedirector The link redirector, or null for - * none. - * @see #getLinkRedirector() - */ - public static void setLinkRedirector(LinkRedirector linkRedirector) { - AutoCompletion.linkRedirector = linkRedirector; - } - - - /** - * 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 null, - * a default renderer is used. - * @see #getListCellRenderer() - */ - public void setListCellRenderer(ListCellRenderer renderer) { - this.renderer = renderer; - if (popupWindow!=null) { - popupWindow.setListCellRenderer(renderer); - hidePopupWindow(); - } - } - - - /** - * Sets the renderer to use for {@link Completion}s in the optional - * parameter choices popup window (displayed when a - * {@link ParameterizedCompletion} is code-completed). If this isn't set, - * a default renderer is used. - * - * @param r The renderer to use. - * @see #getParamChoicesRenderer() - * @see #setParameterAssistanceEnabled(boolean) - */ - public void setParamChoicesRenderer(ListCellRenderer r) { - paramChoicesRenderer = r; - } - - - /** - * Sets whether parameter assistance is enabled. If parameter assistance - * is enabled, and a "parameterized" completion (such as a function or - * method) is inserted, the user will get "assistance" in inserting the - * parameters in the form of a popup window with documentation and easy - * tabbing through the arguments (as seen in Eclipse and NetBeans). - * - * @param enabled Whether parameter assistance should be enabled. - * @see #isParameterAssistanceEnabled() - */ - public void setParameterAssistanceEnabled(boolean enabled) { - parameterAssistanceEnabled = enabled; - } - - - /** - * Sets whether the "description window" should be shown beside the - * completion window. - * - * @param show Whether to show the description window. - * @see #getShowDescWindow() - */ - public void setShowDescWindow(boolean show) { - hidePopupWindow(); // Needed to force it to take effect - showDescWindow = show; - } - - - /** - * Sets the keystroke that should be used to trigger the auto-complete - * popup window. - * - * @param ks The keystroke. - * @throws IllegalArgumentException If ks is null. - * @see #getTriggerKey() - */ - public void setTriggerKey(KeyStroke ks) { - if (ks==null) { - throw new IllegalArgumentException("trigger key cannot be null"); - } - if (!ks.equals(trigger)) { - if (textComponent!=null) { - // Put old trigger action back. - uninstallTriggerKey(); - // Grab current action for new trigger and replace it. - installTriggerKey(ks); - } - trigger = ks; - } - } - - - /** - * Displays a "tool tip" detailing the inputs to the function just entered. - * - * @param pc The completion. - * @param typedParamListStartChar Whether the parameterized completion list - * starting character was typed. - */ - private void startParameterizedCompletionAssistance( - ParameterizedCompletion pc, boolean typedParamListStartChar) { - - // Get rid of the previous tool tip window, if there is one. - hideParameterCompletionPopups(); - - // Don't bother with a tool tip if there are no parameters, but if - // they typed e.g. the opening '(', make them overtype the ')'. - if (pc.getParamCount()==0 && !(pc instanceof TemplateCompletion)) { - CompletionProvider p = pc.getProvider(); - char end = p.getParameterListEnd(); // Might be '\0' - String text = end=='\0' ? "" : Character.toString(end); - if (typedParamListStartChar) { - String template = "${}" + text + "${cursor}"; - textComponent.replaceSelection(Character.toString(p.getParameterListStart())); - TemplateCompletion tc = new TemplateCompletion(p, null, null, template); - pc = tc; - } - else { - text = p.getParameterListStart() + text; - textComponent.replaceSelection(text); - return; - } - } - - pcc = new ParameterizedCompletionContext(parentWindow, this, pc); - pcc.activate(); - - } - - - /** - * Uninstalls this auto-completion from its text component. If it is not - * installed on any text component, nothing happens. - * - * @see #install(JTextComponent) - */ - public void uninstall() { - - if (textComponent!=null) { - - hidePopupWindow(); // Unregisters listeners, actions, etc. - - uninstallTriggerKey(); - - // Uninstall the function completion key. - char start = provider.getParameterListStart(); - if (start!=0) { - KeyStroke ks = KeyStroke.getKeyStroke(start); - InputMap im = textComponent.getInputMap(); - im.put(ks, oldParenKey); - ActionMap am = textComponent.getActionMap(); - am.put(PARAM_COMPLETE_KEY, oldParenAction); - } - - textComponentListener.removeFrom(textComponent); - if (parentWindow!=null) { - parentWindowListener.removeFrom(parentWindow); - } - - if (isAutoActivationEnabled()) { - autoActivationListener.removeFrom(textComponent); - } - - UIManager.removePropertyChangeListener(lafListener); - - textComponent = null; - popupWindow = null; - - } - - } - - - /** - * Replaces the "trigger key" action with the one that was there - * before auto-completion was installed. - * - * @see #installTriggerKey(KeyStroke) - */ - private void uninstallTriggerKey() { - InputMap im = textComponent.getInputMap(); - im.put(trigger, oldTriggerKey); - ActionMap am = textComponent.getActionMap(); - am.put(PARAM_TRIGGER_KEY, oldTriggerAction); - } - - - /** - * Updates the LookAndFeel of the popup window. Applications can call - * this method as appropriate if they support changing the LookAndFeel - * at runtime. - */ - private void updateUI() { - if (popupWindow!=null) { - popupWindow.updateUI(); - } - if (pcc!=null) { - pcc.updateUI(); - } - // Will practically always be a JComponent (a JLabel) - if (paramChoicesRenderer instanceof JComponent) { - ((JComponent)paramChoicesRenderer).updateUI(); - } - } - - - /** - * Listens for events in the text component to auto-activate the code - * completion popup. - */ - private class AutoActivationListener extends FocusAdapter - implements DocumentListener, CaretListener, ActionListener { - - private Timer timer; - private boolean justInserted; - - public AutoActivationListener() { - timer = new Timer(200, this); - timer.setRepeats(false); - } - - public void actionPerformed(ActionEvent e) { - doCompletion(); - } - - public void addTo(JTextComponent tc) { - tc.addFocusListener(this); - tc.getDocument().addDocumentListener(this); - tc.addCaretListener(this); - } - - public void caretUpdate(CaretEvent e) { - if (justInserted) { - justInserted = false; - } - else { - timer.stop(); - } - } - - public void changedUpdate(DocumentEvent e) { - // Ignore - } - - @Override - public void focusLost(FocusEvent e) { - timer.stop(); - //hideChildWindows(); Other listener will do this - } - - public void insertUpdate(DocumentEvent e) { - justInserted = false; - if (isAutoCompleteEnabled() && isAutoActivationEnabled() && - e.getLength()==1) { - if (provider.isAutoActivateOkay(textComponent)) { - timer.restart(); - justInserted = true; - } - else { - timer.stop(); - } - } - else { - timer.stop(); - } - } - - public void removeFrom(JTextComponent tc) { - tc.removeFocusListener(this); - tc.getDocument().removeDocumentListener(this); - tc.removeCaretListener(this); - timer.stop(); - justInserted = false; - } - - public void removeUpdate(DocumentEvent e) { - timer.stop(); - } - - } - - - /** - * The Action that displays the popup window if - * auto-completion is enabled. - */ - private class AutoCompleteAction extends AbstractAction { - - public void actionPerformed(ActionEvent e) { - if (isAutoCompleteEnabled()) { - refreshPopupWindow(); - } - else if (oldTriggerAction!=null) { - oldTriggerAction.actionPerformed(e); - } - } - - } - - - /** - * Listens for LookAndFeel changes and updates the various popup windows - * involved in auto-completion accordingly. - */ - private class LookAndFeelChangeListener implements PropertyChangeListener { - - public void propertyChange(PropertyChangeEvent e) { - String name = e.getPropertyName(); - if ("lookAndFeel".equals(name)) { - updateUI(); - } - } - - } - - - /** - * Action that starts a parameterized completion, e.g. after '(' is - * typed. - */ - private class ParameterizedCompletionStartAction extends AbstractAction { - - private String start; - - public ParameterizedCompletionStartAction(char ch) { - this.start = Character.toString(ch); - } - - public void actionPerformed(ActionEvent e) { - - // Prevents keystrokes from messing up - boolean wasVisible = hidePopupWindow(); - - // Only proceed if they were selecting a completion - if (!wasVisible || !isParameterAssistanceEnabled()) { - textComponent.replaceSelection(start); - return; - } - - Completion c = popupWindow.getSelection(); - if (c instanceof ParameterizedCompletion) { // Should always be true - // Fixes capitalization of the entered text. - insertCompletion(c, true); - } - - } - - } - - - /** - * Listens for events in the parent window of the text component with - * auto-completion enabled. - */ - private class ParentWindowListener extends ComponentAdapter - implements WindowFocusListener { - - public void addTo(Window w) { - w.addComponentListener(this); - w.addWindowFocusListener(this); - } - - @Override - public void componentHidden(ComponentEvent e) { - hideChildWindows(); - } - - @Override - public void componentMoved(ComponentEvent e) { - hideChildWindows(); - } - - @Override - public void componentResized(ComponentEvent e) { - hideChildWindows(); - } - - public void removeFrom(Window w) { - w.removeComponentListener(this); - w.removeWindowFocusListener(this); - } - - public void windowGainedFocus(WindowEvent e) { - } - - public void windowLostFocus(WindowEvent e) { - hideChildWindows(); - } - - } - - - /** - * Listens for events from the text component we're installed on. - */ - private class TextComponentListener extends FocusAdapter - implements HierarchyListener { - - void addTo(JTextComponent tc) { - tc.addFocusListener(this); - tc.addHierarchyListener(this); - } - - /** - * Hide the auto-completion windows when the text component loses - * focus. - */ - @Override - public void focusLost(FocusEvent e) { - hideChildWindows(); - } - - /** - * Called when the component hierarchy for our text component changes. - * When the text component is added to a new {@link Window}, this - * method registers listeners on that Window. - * - * @param e The event. - */ - public void hierarchyChanged(HierarchyEvent e) { - - // NOTE: e many be null as we call this method at other times. - //System.out.println("Hierarchy changed! " + e); - - Window oldParentWindow = parentWindow; - parentWindow = SwingUtilities.getWindowAncestor(textComponent); - if (parentWindow!=oldParentWindow) { - if (oldParentWindow!=null) { - parentWindowListener.removeFrom(oldParentWindow); - } - if (parentWindow!=null) { - parentWindowListener.addTo(parentWindow); - } - } - - } - - public void removeFrom(JTextComponent tc) { - tc.removeFocusListener(this); - tc.removeHierarchyListener(this); - } - - } + /** + * The text component we're providing completion for. + */ + private JTextComponent textComponent; + + /** + * The parent window of {@link #textComponent}. + */ + private Window parentWindow; + + /** + * The popup window containing completion choices. + */ + private AutoCompletePopupWindow popupWindow; + + /** + * The preferred size of the completion choices window. This field exists + * because the user will likely set the preferred size of the window + * before it is actually created. + */ + private Dimension preferredChoicesWindowSize; + + /** + * 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; + + /** + * Manages any parameterized completions that are inserted. + */ + private ParameterizedCompletionContext pcc; + + /** + * Provides the completion options relevant to the current caret position. + */ + private CompletionProvider provider; + + /** + * The renderer to use for the completion choices. If this is + * null, then a default renderer is used. + */ + private ListCellRenderer renderer; + + /** + * The handler to use when an external URL is clicked in the help + * documentation. + */ + private ExternalURLHandler externalURLHandler; + + /** + * An optional redirector that converts URL's to some other location before + * being handed over to externalURLHandler. + */ + private static LinkRedirector linkRedirector; + + /** + * Whether the description window should be displayed along with the + * completion choice window. + */ + private boolean showDescWindow; + + /** + * Whether auto-complete is enabled. + */ + private boolean autoCompleteEnabled; + + /** + * Whether the auto-activation of auto-complete (after a delay, after the + * user types an appropriate character) is enabled. + */ + private boolean autoActivationEnabled; + + /** + * Whether or not, when there is only a single auto-complete option + * that matches the text at the current text position, that text should + * be auto-inserted, instead of the completion window displaying. + */ + private boolean autoCompleteSingleChoices; + + /** + * Whether parameter assistance is enabled. + */ + private boolean parameterAssistanceEnabled; + + /** + * A renderer used for {@link Completion}s in the optional parameter + * choices popup window (displayed when a {@link ParameterizedCompletion} + * is code-completed). If this isn't set, a default renderer is used. + */ + private ListCellRenderer paramChoicesRenderer; + + /** + * The keystroke that triggers the completion window. + */ + private KeyStroke trigger; + + /** + * The previous key in the text component's InputMap for the + * trigger key. + */ + private Object oldTriggerKey; + + /** + * The action previously assigned to {@link #trigger}, so we can reset it + * if the user disables auto-completion. + */ + private Action oldTriggerAction; + + /** + * The previous key in the text component's InputMap for the + * parameter completion trigger key. + */ + private Object oldParenKey; + + /** + * The action previously assigned to the parameter completion key, so we + * can reset it when we uninstall. + */ + private Action oldParenAction; + + /** + * Listens for events in the parent window that affect the visibility of + * the popup windows. + */ + private ParentWindowListener parentWindowListener; + + /** + * Listens for events from the text component that affect the visibility + * of the popup windows. + */ + private TextComponentListener textComponentListener; + + /** + * Listens for events in the text component that cause the popup windows + * to automatically activate. + */ + private AutoActivationListener autoActivationListener; + + /** + * Listens for LAF changes so the auto-complete windows automatically + * update themselves accordingly. + */ + private LookAndFeelChangeListener lafListener; + + /** + * The key used in the input map for the AutoComplete action. + */ + private static final String PARAM_TRIGGER_KEY = "AutoComplete"; + + /** + * Key used in the input map for the parameter completion action. + */ + private static final String PARAM_COMPLETE_KEY = "AutoCompletion.FunctionStart"; + + /** + * Stores how to render auto-completion-specific highlights in text + * components. + */ + private static final AutoCompletionStyleContext STYLE_CONTEXT = + new AutoCompletionStyleContext(); + + /** + * Whether debug messages should be printed to stdout as AutoCompletion + * runs. + */ + private static final boolean DEBUG = initDebug(); + + + /** + * Constructor. + * + * @param provider The completion provider. This cannot be + * null. + */ + public AutoCompletion(CompletionProvider provider) { + + setChoicesWindowSize(350, 200); + setDescriptionWindowSize(350, 250); + + setCompletionProvider(provider); + setTriggerKey(getDefaultTriggerKey()); + setAutoCompleteEnabled(true); + setAutoCompleteSingleChoices(true); + setAutoActivationEnabled(false); + setShowDescWindow(false); + parentWindowListener = new ParentWindowListener(); + textComponentListener = new TextComponentListener(); + autoActivationListener = new AutoActivationListener(); + lafListener = new LookAndFeelChangeListener(); + + } + + + /** + * Displays the popup window. Hosting applications can call this method + * to programmatically begin an auto-completion operation. + */ + public void doCompletion() { + refreshPopupWindow(); + } + + + /** + * Returns the delay between when the user types a character and when the + * code completion popup should automatically appear (if applicable). + * + * @return The delay, in milliseconds. + * @see #setAutoActivationDelay(int) + */ + public int getAutoActivationDelay() { + return autoActivationListener.timer.getDelay(); + } + + + /** + * Returns whether, if a single auto-complete choice is available, it + * should be automatically inserted, without displaying the popup menu. + * + * @return Whether to auto-complete single choices. + * @see #setAutoCompleteSingleChoices(boolean) + */ + public boolean getAutoCompleteSingleChoices() { + return autoCompleteSingleChoices; + } + + + /** + * Returns the completion provider. + * + * @return The completion provider. + */ + public CompletionProvider getCompletionProvider() { + return provider; + } + + + /** + * Returns whether debug is enabled for AutoCompletion. + * + * @return Whether debug is enabled. + */ + static boolean isDebug() { + return DEBUG; + } + + + /** + * Returns the default auto-complete "trigger key" for this OS. For + * Windows, for example, it is Ctrl+Space. + * + * @return The default auto-complete trigger key. + */ + public static KeyStroke getDefaultTriggerKey() { + // Default to CTRL, even on Mac, since Ctrl+Space activates Spotlight + return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, DEFAULT_MODIFIER); + } + + + /** + * Returns the handler to use when an external URL is clicked in the + * description window. + * + * @return The handler. + * @see #setExternalURLHandler(ExternalURLHandler) + * @see #getLinkRedirector() + */ + public ExternalURLHandler getExternalURLHandler() { + return externalURLHandler; + } + + + int getLineOfCaret() { + Document doc = textComponent.getDocument(); + Element root = doc.getDefaultRootElement(); + return root.getElementIndex(textComponent.getCaretPosition()); + } + + + /** + * Returns the link redirector, if any. + * + * @return The link redirector, or null if none. + * @see #setLinkRedirector(LinkRedirector) + */ + public static LinkRedirector getLinkRedirector() { + return linkRedirector; + } + + + /** + * 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() { + return renderer; + } + + + /** + * Returns the renderer to use for {@link Completion}s in the optional + * parameter choices popup window (displayed when a + * {@link ParameterizedCompletion} is code-completed). If this returns + * null, a default renderer is used. + * + * @return The renderer to use. + * @see #setParamChoicesRenderer(ListCellRenderer) + * @see #isParameterAssistanceEnabled() + */ + public ListCellRenderer getParamChoicesRenderer() { + return paramChoicesRenderer; + } + + + /** + * Returns the text to replace with in the document. This is a + * "last-chance" hook for subclasses to make special modifications to the + * completion text inserted. The default implementation simply returns + * c.getReplacementText(). You usually will not need to modify + * this method. + * + * @param c The completion being inserted. + * @param doc The document being modified. + * @param start The start of the text being replaced. + * @param len The length of the text being replaced. + * @return The text to replace with. + */ + protected String getReplacementText(Completion c, Document doc, int start, + int len) { + return c.getReplacementText(); + } + + + /** + * Returns whether the "description window" should be shown alongside + * the completion window. + * + * @return Whether the description window should be shown. + * @see #setShowDescWindow(boolean) + */ + public boolean isShowDescWindow() { + return showDescWindow; + } + + + /** + * Returns the style context describing how auto-completion related + * highlights in the editor are rendered. + * + * @return The style context. + */ + public static AutoCompletionStyleContext getStyleContext() { + return STYLE_CONTEXT; + } + + + /** + * Returns the text component for which auto-completion is enabled. + * + * @return The text component, or null if this + * {@link AutoCompletion} is not installed on any text component. + * @see #install(JTextComponent) + */ + public JTextComponent getTextComponent() { + return textComponent; + } + + + /** + * Returns the orientation of the text component we're installed to. + * + * @return The orientation of the text component, or null if + * we are not installed on one. + */ + ComponentOrientation getTextComponentOrientation() { + return textComponent == null ? null : + textComponent.getComponentOrientation(); + } + + + /** + * Returns the "trigger key" used for auto-complete. + * + * @return The trigger key. + * @see #setTriggerKey(KeyStroke) + */ + public KeyStroke getTriggerKey() { + return trigger; + } + + + /** + * Hides any child windows being displayed by the auto-completion system. + * + * @return Whether any windows were visible. + */ + public boolean hideChildWindows() { + //return hidePopupWindow() || hideToolTipWindow(); + boolean res = hidePopupWindow(); + res |= hideParameterCompletionPopups(); + return res; + } + + + /** + * Hides and disposes of any parameter completion-related popups. + * + * @return Whether any such windows were visible (and thus hidden). + */ + private boolean hideParameterCompletionPopups() { + if (pcc != null) { + pcc.deactivate(); + pcc = null; + return true; + } + return false; + } + + + /** + * Hides the popup window, if it is visible. + * + * @return Whether the popup window was visible. + */ + private boolean hidePopupWindow() { + if (popupWindow != null) { + if (popupWindow.isVisible()) { + popupWindow.setVisible(false); + return true; + } + } + return false; + } + + + /** + * Determines whether debug should be enabled for the AutoCompletion + * library. This method checks a system property, but takes care of + * {@link SecurityException}s in case we're in an applet or WebStart. + * + * @return Whether debug should be enabled. + */ + private static final boolean initDebug() { + boolean debug = false; + try { + debug = Boolean.getBoolean("AutoCompletion.debug"); + } catch (SecurityException se) { // We're in an applet or WebStart. + debug = false; + } + return debug; + } + + + /** + * Inserts a completion. Any time a code completion event occurs, the + * actual text insertion happens through this method. + * + * @param c A completion to insert. This cannot be null. + */ + protected final void insertCompletion(Completion c) { + insertCompletion(c, false); + } + + + /** + * Inserts a completion. Any time a code completion event occurs, the + * actual text insertion happens through this method. + * + * @param c A completion to insert. This cannot be null. + * @param typedParamListStartChar Whether the parameterized completion + * start character was typed (typically '('). + */ + protected void insertCompletion(Completion c, + boolean typedParamListStartChar) { + + JTextComponent textComp = getTextComponent(); + String alreadyEntered = c.getAlreadyEntered(textComp); + hidePopupWindow(); + Caret caret = textComp.getCaret(); + + int dot = caret.getDot(); + int len = alreadyEntered.length(); + int start = dot - len; + String replacement = getReplacementText(c, textComp.getDocument(), + start, len); + + caret.setDot(start); + caret.moveDot(dot); + textComp.replaceSelection(replacement); + + if (isParameterAssistanceEnabled() && + (c instanceof ParameterizedCompletion)) { + ParameterizedCompletion pc = (ParameterizedCompletion) c; + startParameterizedCompletionAssistance(pc, typedParamListStartChar); + } + + } + + + /** + * Installs this auto-completion on a text component. If this + * {@link AutoCompletion} is already installed on another text component, + * it is uninstalled first. + * + * @param c The text component. + * @see #uninstall() + */ + public void install(JTextComponent c) { + + if (textComponent != null) { + uninstall(); + } + + this.textComponent = c; + installTriggerKey(getTriggerKey()); + + // Install the function completion key, if there is one. + // NOTE: We cannot do this if the start char is ' ' (e.g. just a space + // between the function name and parameters) because it overrides + // RSTA's special space action. It seems KeyStorke.getKeyStroke(' ') + // hoses ctrl+space, shift+space, etc., even though I think it + // shouldn't... + char start = provider.getParameterListStart(); + if (start != 0 && start != ' ') { + InputMap im = c.getInputMap(); + ActionMap am = c.getActionMap(); + KeyStroke ks = KeyStroke.getKeyStroke(start); + oldParenKey = im.get(ks); + im.put(ks, PARAM_COMPLETE_KEY); + oldParenAction = am.get(PARAM_COMPLETE_KEY); + am.put(PARAM_COMPLETE_KEY, + new ParameterizedCompletionStartAction(start)); + } + + textComponentListener.addTo(this.textComponent); + // In case textComponent is already in a window... + textComponentListener.hierarchyChanged(null); + + if (isAutoActivationEnabled()) { + autoActivationListener.addTo(this.textComponent); + } + + UIManager.addPropertyChangeListener(lafListener); + updateUI(); // In case there have been changes since we uninstalled + + } + + + /** + * Installs a "trigger key" action onto the current text component. + * + * @param ks The keystroke that should trigger the action. + * @see #uninstallTriggerKey() + */ + private void installTriggerKey(KeyStroke ks) { + InputMap im = textComponent.getInputMap(); + oldTriggerKey = im.get(ks); + im.put(ks, PARAM_TRIGGER_KEY); + ActionMap am = textComponent.getActionMap(); + oldTriggerAction = am.get(PARAM_TRIGGER_KEY); + am.put(PARAM_TRIGGER_KEY, new AutoCompleteAction()); + } + + + /** + * Returns whether auto-activation is enabled (that is, whether the + * completion popup will automatically appear after a delay when the user + * types an appropriate character). Note that this parameter will be + * ignored if auto-completion is disabled. + * + * @return Whether auto-activation is enabled. + * @see #setAutoActivationEnabled(boolean) + * @see #getAutoActivationDelay() + * @see #isAutoCompleteEnabled() + */ + public boolean isAutoActivationEnabled() { + return autoActivationEnabled; + } + + + /** + * Returns whether auto-completion is enabled. + * + * @return Whether auto-completion is enabled. + * @see #setAutoCompleteEnabled(boolean) + */ + public boolean isAutoCompleteEnabled() { + return autoCompleteEnabled; + } + + + /** + * Returns whether parameter assistance is enabled. + * + * @return Whether parameter assistance is enabled. + * @see #setParameterAssistanceEnabled(boolean) + */ + public boolean isParameterAssistanceEnabled() { + return parameterAssistanceEnabled; + } + + + /** + * Returns whether the completion popup window is visible. + * + * @return Whether the completion popup window is visible. + */ + public boolean isPopupVisible() { + return popupWindow != null && popupWindow.isVisible(); + } + + + /** + * Refreshes the popup window. First, this method gets the possible + * completions for the current caret position. If there are none, and the + * popup is visible, it is hidden. If there are some completions and the + * popup is hidden, it is made visible and made to display the completions. + * If there are some completions and the popup is visible, its list is + * updated to the current set of completions. + * + * @return The current line number of the caret. + */ + protected int refreshPopupWindow() { + // A return value of null => don't suggest completions + String text = provider.getAlreadyEnteredText(textComponent); + if (text == null && !isPopupVisible()) { + return getLineOfCaret(); + } + // If the popup is currently visible, and they type a space (or any + // character that resets the completion list to "all completions"), + // the popup window should be hidden instead of being reset to show + // everything. + int textLen = text == null ? 0 : text.length(); + if (textLen == 0 && isPopupVisible()) { + hidePopupWindow(); + return getLineOfCaret(); + } + final List completions = provider.getCompletions(textComponent); + int count = completions.size(); + if (needSetPopupWindow(count, textLen)) { + if (popupWindow == null) { + popupWindow = createAutoCompletePopupWindow(); + } + popupWindow.setCompletions(completions); + if (!popupWindow.isVisible()) { + Rectangle r = null; + try { + r = textComponent.modelToView(textComponent.getCaretPosition()); + } catch (BadLocationException ble) { + return -1; + } + Point p = new Point(r.x, r.y); + SwingUtilities.convertPointToScreen(p, textComponent); + r.x = p.x; + r.y = p.y; + popupWindow.setLocationRelativeTo(r); + popupWindow.setVisible(true); + } + } else if (count == 1) { // !isPopupVisible && autoCompleteSingleChoices + SwingUtilities.invokeLater(new Runnable() { + public void run() { + insertCompletion(completions.get(0)); + } + }); + } else { + hidePopupWindow(); + } + return getLineOfCaret(); + } + + private boolean needSetPopupWindow(int count, int textLen) { + return (count == 1 && (isPopupVisible() || textLen == 0)) + || (count == 1 && !getAutoCompleteSingleChoices()) + || count > 1; + } + + private AutoCompletePopupWindow createAutoCompletePopupWindow() { + AutoCompletePopupWindow popupWindow = new AutoCompletePopupWindow(parentWindow, this); + // Completion is usually done for code, which is always done + // LTR, so make completion stuff RTL only if text component is + // also RTL. + popupWindow.applyComponentOrientation( + getTextComponentOrientation()); + if (renderer != null) { + popupWindow.setListCellRenderer(renderer); + } + if (preferredChoicesWindowSize != null) { + popupWindow.setSize(preferredChoicesWindowSize); + } + if (preferredDescWindowSize != null) { + popupWindow.setDescriptionWindowSize( + preferredDescWindowSize); + } + return popupWindow; + } + + /** + * Sets the delay between when the user types a character and when the + * code completion popup should automatically appear (if applicable). + * + * @param ms The delay, in milliseconds. This should be greater than zero. + * @see #getAutoActivationDelay() + */ + public void setAutoActivationDelay(int ms) { + ms = Math.max(0, ms); + autoActivationListener.timer.stop(); + autoActivationListener.timer.setInitialDelay(ms); + } + + + /** + * Toggles whether auto-activation is enabled. Note that auto-activation + * also depends on auto-completion itself being enabled. + * + * @param enabled Whether auto-activation is enabled. + * @see #isAutoActivationEnabled() + * @see #setAutoActivationDelay(int) + */ + public void setAutoActivationEnabled(boolean enabled) { + if (enabled != autoActivationEnabled) { + autoActivationEnabled = enabled; + if (textComponent != null) { + if (autoActivationEnabled) { + autoActivationListener.addTo(textComponent); + } else { + autoActivationListener.removeFrom(textComponent); + } + } + } + } + + + /** + * Sets whether auto-completion is enabled. + * + * @param enabled Whether auto-completion is enabled. + * @see #isAutoCompleteEnabled() + */ + public void setAutoCompleteEnabled(boolean enabled) { + if (enabled != autoCompleteEnabled) { + autoCompleteEnabled = enabled; + hidePopupWindow(); + } + } + + + /** + * Sets whether, if a single auto-complete choice is available, it should + * be automatically inserted, without displaying the popup menu. + * + * @param autoComplete Whether to auto-complete single choices. + * @see #getAutoCompleteSingleChoices() + */ + public void setAutoCompleteSingleChoices(boolean autoComplete) { + autoCompleteSingleChoices = autoComplete; + } + + + /** + * Sets the completion provider being used. + * + * @param provider The new completion provider. This cannot be + * null. + * @throws IllegalArgumentException If provider is + * null. + */ + public void setCompletionProvider(CompletionProvider provider) { + if (provider == null) { + throw new IllegalArgumentException("provider cannot be null"); + } + this.provider = provider; + hidePopupWindow(); // In case new choices should be displayed. + } + + + /** + * Sets the size of the completion choices window. + * + * @param w The new width. + * @param h The new height. + * @see #setDescriptionWindowSize(int, int) + */ + public void setChoicesWindowSize(int w, int h) { + preferredChoicesWindowSize = new Dimension(w, h); + if (popupWindow != null) { + popupWindow.setSize(preferredChoicesWindowSize); + } + } + + + /** + * Sets the size of the description window. + * + * @param w The new width. + * @param h The new height. + * @see #setChoicesWindowSize(int, int) + */ + public void setDescriptionWindowSize(int w, int h) { + preferredDescWindowSize = new Dimension(w, h); + if (popupWindow != null) { + popupWindow.setDescriptionWindowSize(preferredDescWindowSize); + } + } + + + /** + * Sets the handler to use when an external URL is clicked in the + * description window. This handler can perform some action, such as + * open the URL in a web browser. The default implementation will open + * the URL in a browser, but only if running in Java 6. If you want + * browser support for Java 5 and below, or otherwise want to respond to + * hyperlink clicks, you will have to install your own handler to do so. + * + * @param handler The new handler. + * @see #getExternalURLHandler() + */ + public void setExternalURLHandler(ExternalURLHandler handler) { + this.externalURLHandler = handler; + } + + + /** + * Sets the redirector for external URL's found in code completion + * documentation. When a non-local link in completion popups is clicked, + * this redirector is given the chance to modify the URL fetched and + * displayed. + * + * @param linkRedirector The link redirector, or null for + * none. + * @see #getLinkRedirector() + */ + public static void setLinkRedirector(LinkRedirector linkRedirector) { + AutoCompletion.linkRedirector = linkRedirector; + } + + + /** + * 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 null, + * a default renderer is used. + * @see #getListCellRenderer() + */ + public void setListCellRenderer(ListCellRenderer renderer) { + this.renderer = renderer; + if (popupWindow != null) { + popupWindow.setListCellRenderer(renderer); + hidePopupWindow(); + } + } + + + /** + * Sets the renderer to use for {@link Completion}s in the optional + * parameter choices popup window (displayed when a + * {@link ParameterizedCompletion} is code-completed). If this isn't set, + * a default renderer is used. + * + * @param r The renderer to use. + * @see #getParamChoicesRenderer() + * @see #setParameterAssistanceEnabled(boolean) + */ + public void setParamChoicesRenderer(ListCellRenderer r) { + paramChoicesRenderer = r; + } + + + /** + * Sets whether parameter assistance is enabled. If parameter assistance + * is enabled, and a "parameterized" completion (such as a function or + * method) is inserted, the user will get "assistance" in inserting the + * parameters in the form of a popup window with documentation and easy + * tabbing through the arguments (as seen in Eclipse and NetBeans). + * + * @param enabled Whether parameter assistance should be enabled. + * @see #isParameterAssistanceEnabled() + */ + public void setParameterAssistanceEnabled(boolean enabled) { + parameterAssistanceEnabled = enabled; + } + + + /** + * Sets whether the "description window" should be shown beside the + * completion window. + * + * @param show Whether to show the description window. + * @see #isShowDescWindow() + */ + public void setShowDescWindow(boolean show) { + hidePopupWindow(); // Needed to force it to take effect + showDescWindow = show; + } + + + /** + * Sets the keystroke that should be used to trigger the auto-complete + * popup window. + * + * @param ks The keystroke. + * @throws IllegalArgumentException If ks is null. + * @see #getTriggerKey() + */ + public void setTriggerKey(KeyStroke ks) { + if (ks == null) { + throw new IllegalArgumentException("trigger key cannot be null"); + } + if (!ks.equals(trigger)) { + if (textComponent != null) { + // Put old trigger action back. + uninstallTriggerKey(); + // Grab current action for new trigger and replace it. + installTriggerKey(ks); + } + trigger = ks; + } + } + + + /** + * Displays a "tool tip" detailing the inputs to the function just entered. + * + * @param pc The completion. + * @param typedParamListStartChar Whether the parameterized completion list + * starting character was typed. + */ + private void startParameterizedCompletionAssistance( + ParameterizedCompletion pc, boolean typedParamListStartChar) { + + // Get rid of the previous tool tip window, if there is one. + hideParameterCompletionPopups(); + + // Don't bother with a tool tip if there are no parameters, but if + // they typed e.g. the opening '(', make them overtype the ')'. + if (pc.getParamCount() == 0 && !(pc instanceof TemplateCompletion)) { + CompletionProvider p = pc.getProvider(); + char end = p.getParameterListEnd(); // Might be '\0' + String text = end == '\0' ? "" : Character.toString(end); + if (typedParamListStartChar) { + String template = "${}" + text + "${cursor}"; + textComponent.replaceSelection(Character.toString(p.getParameterListStart())); + TemplateCompletion tc = new TemplateCompletion(p, null, null, template); + pc = tc; + } else { + text = p.getParameterListStart() + text; + textComponent.replaceSelection(text); + return; + } + } + + pcc = new ParameterizedCompletionContext(parentWindow, this, pc); + pcc.activate(); + + } + + + /** + * Uninstalls this auto-completion from its text component. If it is not + * installed on any text component, nothing happens. + * + * @see #install(JTextComponent) + */ + public void uninstall() { + + if (textComponent != null) { + + hidePopupWindow(); // Unregisters listeners, actions, etc. + + uninstallTriggerKey(); + + // Uninstall the function completion key. + char start = provider.getParameterListStart(); + if (start != 0) { + KeyStroke ks = KeyStroke.getKeyStroke(start); + InputMap im = textComponent.getInputMap(); + im.put(ks, oldParenKey); + ActionMap am = textComponent.getActionMap(); + am.put(PARAM_COMPLETE_KEY, oldParenAction); + } + + textComponentListener.removeFrom(textComponent); + if (parentWindow != null) { + parentWindowListener.removeFrom(parentWindow); + } + + if (isAutoActivationEnabled()) { + autoActivationListener.removeFrom(textComponent); + } + + UIManager.removePropertyChangeListener(lafListener); + + textComponent = null; + popupWindow = null; + + } + + } + + + /** + * Replaces the "trigger key" action with the one that was there + * before auto-completion was installed. + * + * @see #installTriggerKey(KeyStroke) + */ + private void uninstallTriggerKey() { + InputMap im = textComponent.getInputMap(); + im.put(trigger, oldTriggerKey); + ActionMap am = textComponent.getActionMap(); + am.put(PARAM_TRIGGER_KEY, oldTriggerAction); + } + + + /** + * Updates the LookAndFeel of the popup window. Applications can call + * this method as appropriate if they support changing the LookAndFeel + * at runtime. + */ + private void updateUI() { + if (popupWindow != null) { + popupWindow.updateUI(); + } + if (pcc != null) { + pcc.updateUI(); + } + // Will practically always be a JComponent (a JLabel) + if (paramChoicesRenderer instanceof JComponent) { + ((JComponent) paramChoicesRenderer).updateUI(); + } + } + + + /** + * Listens for events in the text component to auto-activate the code + * completion popup. + */ + private class AutoActivationListener extends FocusAdapter + implements DocumentListener, CaretListener, ActionListener { + + private Timer timer; + private boolean justInserted; + + public AutoActivationListener() { + timer = new Timer(200, this); + timer.setRepeats(false); + } + + public void actionPerformed(ActionEvent e) { + doCompletion(); + } + + public void addTo(JTextComponent tc) { + tc.addFocusListener(this); + tc.getDocument().addDocumentListener(this); + tc.addCaretListener(this); + } + + public void caretUpdate(CaretEvent e) { + if (justInserted) { + justInserted = false; + } else { + timer.stop(); + } + } + + public void changedUpdate(DocumentEvent e) { + // Ignore + } + + @Override + public void focusLost(FocusEvent e) { + timer.stop(); + //hideChildWindows(); Other listener will do this + } + + public void insertUpdate(DocumentEvent e) { + justInserted = false; + if (isAutoCompleteEnabled() && isAutoActivationEnabled() && + e.getLength() == 1) { + if (provider.isAutoActivateOkay(textComponent)) { + timer.restart(); + justInserted = true; + } else { + timer.stop(); + } + } else { + timer.stop(); + } + } + + public void removeFrom(JTextComponent tc) { + tc.removeFocusListener(this); + tc.getDocument().removeDocumentListener(this); + tc.removeCaretListener(this); + timer.stop(); + justInserted = false; + } + + public void removeUpdate(DocumentEvent e) { + timer.stop(); + } + + } + + + /** + * The Action that displays the popup window if + * auto-completion is enabled. + */ + private class AutoCompleteAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + if (isAutoCompleteEnabled()) { + refreshPopupWindow(); + } else if (oldTriggerAction != null) { + oldTriggerAction.actionPerformed(e); + } + } + + } + + + /** + * Listens for LookAndFeel changes and updates the various popup windows + * involved in auto-completion accordingly. + */ + private class LookAndFeelChangeListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + String name = e.getPropertyName(); + if ("lookAndFeel".equals(name)) { + updateUI(); + } + } + + } + + + /** + * Action that starts a parameterized completion, e.g. after '(' is + * typed. + */ + private class ParameterizedCompletionStartAction extends AbstractAction { + + private String start; + + public ParameterizedCompletionStartAction(char ch) { + this.start = Character.toString(ch); + } + + public void actionPerformed(ActionEvent e) { + + // Prevents keystrokes from messing up + boolean wasVisible = hidePopupWindow(); + + // Only proceed if they were selecting a completion + if (!wasVisible || !isParameterAssistanceEnabled()) { + textComponent.replaceSelection(start); + return; + } + + Completion c = popupWindow.getSelection(); + if (c instanceof ParameterizedCompletion) { // Should always be true + // Fixes capitalization of the entered text. + insertCompletion(c, true); + } + + } + + } + + + /** + * Listens for events in the parent window of the text component with + * auto-completion enabled. + */ + private class ParentWindowListener extends ComponentAdapter + implements WindowFocusListener { + + public void addTo(Window w) { + w.addComponentListener(this); + w.addWindowFocusListener(this); + } + + @Override + public void componentHidden(ComponentEvent e) { + hideChildWindows(); + } + + @Override + public void componentMoved(ComponentEvent e) { + hideChildWindows(); + } + + @Override + public void componentResized(ComponentEvent e) { + hideChildWindows(); + } + + public void removeFrom(Window w) { + w.removeComponentListener(this); + w.removeWindowFocusListener(this); + } + + public void windowGainedFocus(WindowEvent e) { + } + + public void windowLostFocus(WindowEvent e) { + hideChildWindows(); + } + + } + + + /** + * Listens for events from the text component we're installed on. + */ + private class TextComponentListener extends FocusAdapter + implements HierarchyListener { + + void addTo(JTextComponent tc) { + tc.addFocusListener(this); + tc.addHierarchyListener(this); + } + + /** + * Hide the auto-completion windows when the text component loses + * focus. + */ + @Override + public void focusLost(FocusEvent e) { + hideChildWindows(); + } + + /** + * Called when the component hierarchy for our text component changes. + * When the text component is added to a new {@link Window}, this + * method registers listeners on that Window. + * + * @param e The event. + */ + public void hierarchyChanged(HierarchyEvent e) { + + // NOTE: e many be null as we call this method at other times. + //System.out.println("Hierarchy changed! " + e); + + Window oldParentWindow = parentWindow; + parentWindow = SwingUtilities.getWindowAncestor(textComponent); + if (parentWindow != oldParentWindow) { + if (oldParentWindow != null) { + parentWindowListener.removeFrom(oldParentWindow); + } + if (parentWindow != null) { + parentWindowListener.addTo(parentWindow); + } + } + + } + + public void removeFrom(JTextComponent tc) { + tc.removeFocusListener(this); + tc.removeHierarchyListener(this); + } + + } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java b/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java index 62c68dc98..966035b89 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java @@ -439,7 +439,7 @@ class ParameterizedCompletionContext { */ private void installKeyBindings() { - if (AutoCompletion.getDebug()) { + if (AutoCompletion.isDebug()) { System.out.println("CompletionContext: Installing keybindings"); } @@ -733,7 +733,7 @@ class ParameterizedCompletionContext { */ private void uninstallKeyBindings() { - if (AutoCompletion.getDebug()) { + if (AutoCompletion.isDebug()) { System.out.println("CompletionContext Uninstalling keybindings"); } diff --git a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java index 1ec189cc1..ba7752352 100644 --- a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java +++ b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java @@ -160,12 +160,14 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { public void run() { int height = centerPane.getHeight(); int width = centerPane.getWidth(); + int step = 30; + int x = 0; int y = -height; - for (int i = 0; i <= height; i += 30) { + for (int i = 0; i <= height; i += step) { // 设置面板位置 - currentPanel.setBounds(0, i, width, height); - panel.setBounds(0, y, width, height); - y += 30; + currentPanel.setBounds(x, i, width, height); + panel.setBounds(x, y, width, height); + y += step; try { Thread.sleep(3); } catch (InterruptedException e) { diff --git a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java index 941fd962a..b81ea7c38 100644 --- a/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java +++ b/designer_base/src/com/fr/design/gui/itree/checkboxtree/CheckBoxTree.java @@ -236,8 +236,9 @@ public class CheckBoxTree extends JTree { } TreePath path = _tree.getPathForLocation(e.getX(), e.getY()); - if (path == null) + if (path == null) { return null; + } if (clicksInCheckBox(e, path)) { return path; @@ -308,8 +309,9 @@ public class CheckBoxTree extends JTree { return; } - if (e.getModifiers() == 0 && e.getKeyChar() == KeyEvent.VK_SPACE) + if (e.getModifiers() == 0 && e.getKeyChar() == KeyEvent.VK_SPACE) { toggleSelections(); + } } public void keyTyped(KeyEvent e) { diff --git a/designer_base/src/com/fr/design/locale/designer.properties b/designer_base/src/com/fr/design/locale/designer.properties index 9b75c6f47..9d6332e6a 100644 --- a/designer_base/src/com/fr/design/locale/designer.properties +++ b/designer_base/src/com/fr/design/locale/designer.properties @@ -1137,7 +1137,7 @@ FRFont-bold=bold FR-Designer_Set_Submit_Condition= Form-Change_Widget_Name=Change Widget Name ReportColumns-Report_Columns=Report Columns -Can_not_use_FormatBursh= +FR-Designer_Can_not_use_FormatBursh= CellElement-Property_Table=CellElement Property Table Dictionary-Dynamic_SQL=Dynamic SQL FR-Designer_Form-CheckBoxGroup=CheckBoxGroup diff --git a/designer_base/src/com/fr/design/locale/designer_en_US.properties b/designer_base/src/com/fr/design/locale/designer_en_US.properties index 8636f53ce..e8f9e376c 100644 --- a/designer_base/src/com/fr/design/locale/designer_en_US.properties +++ b/designer_base/src/com/fr/design/locale/designer_en_US.properties @@ -1138,7 +1138,7 @@ FRFont-bold=Bold FR-Designer_Set_Submit_Condition=Submit Condition Form-Change_Widget_Name=Change Control Name ReportColumns-Report_Columns=Multi-columns/lines display -Can_not_use_FormatBursh=Can't use format painter in multiple selections +FR-Designer_Can_not_use_FormatBursh=Can't use format painter in multiple selections CellElement-Property_Table=Cell Attribute Table Dictionary-Dynamic_SQL=Dynamic SQL FR-Designer_Form-CheckBoxGroup=CheckBoxGroup diff --git a/designer_base/src/com/fr/design/locale/designer_ja_JP.properties b/designer_base/src/com/fr/design/locale/designer_ja_JP.properties index d5d9dac39..9cb8cd654 100644 --- a/designer_base/src/com/fr/design/locale/designer_ja_JP.properties +++ b/designer_base/src/com/fr/design/locale/designer_ja_JP.properties @@ -1133,7 +1133,7 @@ FRFont-bold=\u592A\u5B57 FR-Designer_Set_Submit_Condition=\u63D0\u51FA\u6761\u4EF6\u3092\u8A2D\u5B9A Form-Change_Widget_Name=\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u540D\u5909\u66F4 ReportColumns-Report_Columns=\u5E33\u7968\u30B3\u30E9\u30E0 -Can_not_use_FormatBursh=\u8907\u6570\u9078\u629E\u3057\u305F\u30A8\u30EA\u30A2\u3067\u306F\u66F8\u5F0F\u30D6\u30E9\u30B7\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\! +FR-Designer_Can_not_use_FormatBursh=\u8907\u6570\u9078\u629E\u3057\u305F\u30A8\u30EA\u30A2\u3067\u306F\u66F8\u5F0F\u30D6\u30E9\u30B7\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\! CellElement-Property_Table=\u30BB\u30EB\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u00B7\u30B7\u30FC\u30C8 Dictionary-Dynamic_SQL=\u52D5\u614BSQL FR-Designer_Form-CheckBoxGroup=\u30D5\u30EC\u30FC\u30E0\u30BB\u30C3\u30C8\u3092\u8907\u6570\u9078\u629E diff --git a/designer_base/src/com/fr/design/locale/designer_ko_KR.properties b/designer_base/src/com/fr/design/locale/designer_ko_KR.properties index 39ebe76b6..93a796d79 100644 --- a/designer_base/src/com/fr/design/locale/designer_ko_KR.properties +++ b/designer_base/src/com/fr/design/locale/designer_ko_KR.properties @@ -1134,7 +1134,7 @@ FRFont-bold=\uAD75\uAC8C FR-Designer_Set_Submit_Condition=\uC81C\uCD9C\uC870\uAC74\uC124\uC815 Form-Change_Widget_Name=\uC18C\uD504\uD2B8\uC6E8\uC5B4\uC81C\uC5B4\uC774\uB984\uBCC0\uACBD ReportColumns-Report_Columns=\uBB38\uC11C\uC140\uB098\uB204\uAE30 -Can_not_use_FormatBursh=\uC911\uBCF5\uC120\uD0DD\uB41C\uC601\uC5ED\uC5D0\uC11C\uC2DD\uC744\uC774\uC6A9\uD558\uC5EC\uC778\uC1C4\uD560\uC218\uC5C6\uC2B5\uB2C8\uB2E4.\! +FR-Designer_Can_not_use_FormatBursh=\uC911\uBCF5\uC120\uD0DD\uB41C\uC601\uC5ED\uC5D0\uC11C\uC2DD\uC744\uC774\uC6A9\uD558\uC5EC\uC778\uC1C4\uD560\uC218\uC5C6\uC2B5\uB2C8\uB2E4.\! CellElement-Property_Table=\uC140\uC18D\uC131\uD45C Dictionary-Dynamic_SQL=\uB3D9\uC801 SQL FR-Designer_Form-CheckBoxGroup=\uCCB4\uD06C\uBC15\uC2A4\uADF8\uB8F9 diff --git a/designer_base/src/com/fr/design/locale/designer_zh_CN.properties b/designer_base/src/com/fr/design/locale/designer_zh_CN.properties index 62caf9aeb..1fe8ac3c1 100644 --- a/designer_base/src/com/fr/design/locale/designer_zh_CN.properties +++ b/designer_base/src/com/fr/design/locale/designer_zh_CN.properties @@ -1133,7 +1133,7 @@ FRFont-bold=\u52A0\u7C97 FR-Designer_Set_Submit_Condition=\u8BBE\u7F6E\u63D0\u4EA4\u6761\u4EF6 Form-Change_Widget_Name=\u66F4\u6539\u63A7\u4EF6\u540D ReportColumns-Report_Columns=\u62A5\u8868\u5206\u680F -Can_not_use_FormatBursh=\u4E0D\u80FD\u5BF9\u591A\u91CD\u9009\u5B9A\u533A\u57DF\u4F7F\u7528\u683C\u5F0F\u5237\! +FR-Designer_Can_not_use_FormatBursh=\u4E0D\u80FD\u5BF9\u591A\u91CD\u9009\u5B9A\u533A\u57DF\u4F7F\u7528\u683C\u5F0F\u5237\! CellElement-Property_Table=\u5355\u5143\u683C\u5C5E\u6027\u8868 Dictionary-Dynamic_SQL=\u52A8\u6001SQL FR-Designer_Form-CheckBoxGroup=\u590D\u9009\u6846\u7EC4 diff --git a/designer_base/src/com/fr/design/locale/designer_zh_TW.properties b/designer_base/src/com/fr/design/locale/designer_zh_TW.properties index 867b50f70..08a75d41e 100644 --- a/designer_base/src/com/fr/design/locale/designer_zh_TW.properties +++ b/designer_base/src/com/fr/design/locale/designer_zh_TW.properties @@ -1133,7 +1133,7 @@ FRFont-bold=\u7C97\u9AD4 FR-Designer_Set_Submit_Condition=\u8A2D\u5B9A\u63D0\u4EA4\u689D\u4EF6 Form-Change_Widget_Name=\u66F4\u6539\u63A7\u5236\u9805\u540D ReportColumns-Report_Columns=\u5831\u8868\u5206\u6B04 -Can_not_use_FormatBursh=\u7121\u6CD5\u4F7F\u7528\u8907\u88FD\u683C\u5F0F +FR-Designer_Can_not_use_FormatBursh=\u7121\u6CD5\u4F7F\u7528\u8907\u88FD\u683C\u5F0F CellElement-Property_Table=\u5132\u5B58\u683C\u5C6C\u6027\u8868 Dictionary-Dynamic_SQL=\u52D5\u614BSQL FR-Designer_Form-CheckBoxGroup=\u5FA9\u9078\u6846\u7D44 diff --git a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java index 417d761cc..a45d9fa25 100644 --- a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java +++ b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java @@ -25,248 +25,249 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M public class DataTableConfigPane extends JComponent implements PropertyChangeListener { - private DataEditingTable table; - - public DataTableConfigPane() { - table = new DataEditingTable(); - JScrollPane scrollPane = new JScrollPane(table); - this.setLayout(new DataTableLayout()); - this.add(scrollPane, BorderLayout.CENTER); - } - - public void populate(DataTableConfig config) { - table.populate(config); - } - - public DataTableConfig update() { - return table.update(); - } - - class DataTableLayout extends BorderLayout { - public void layoutContainer(Container target) { - super.layoutContainer(target); - table.doLayout(); - } - } - - class DataEditingTable extends JTable { - - private DataTableConfig config; - private BeanTableModel model; - private TableColumnModelListener modeListener; - - public DataEditingTable() { - this.setBorder(BorderFactory.createLineBorder(new Color(210, 210, 210), 1)); - this.setColumnSelectionAllowed(true); - this.setRowSelectionAllowed(true); - MouseAdapterListener l = new MouseAdapterListener(this); - this.addMouseListener(l); - this.addMouseMotionListener(l); - model = new BeanTableModel(); - modeListener = new TableColumnModelListener() { - - @Override - public void columnAdded(TableColumnModelEvent e) { - - } - - @Override - public void columnMarginChanged(ChangeEvent e) { - DataTableConfigPane.this.propertyChange(); - } - - @Override - public void columnMoved(TableColumnModelEvent e) { - DataTableConfigPane.this.propertyChange(); - } - - @Override - public void columnRemoved(TableColumnModelEvent e) { - - } - - @Override - public void columnSelectionChanged(ListSelectionEvent e) { - - } - - }; - } - - public TableCellRenderer getCellRenderer(int row, int column) { - TableCellRenderer renderer = super.getCellRenderer(row, column); - if (renderer instanceof UILabel) { - ((UILabel) renderer).setHorizontalAlignment(UILabel.CENTER); - } - return renderer; - } - - public void populate(DataTableConfig config) { - this.getTableHeader().getColumnModel().removeColumnModelListener(modeListener); - if (config == null) { - config = DataTableConfig.DEFAULT_TABLE_DATA_CONFIG; - } - this.config = config; - - model = new BeanTableModel(); - this.setModel(model); - this.setRowHeight(0, config.getRowHeight()); - for (int i = 0; i < config.getColumnCount(); i++) { - this.getColumn(this.getColumnName(i)).setPreferredWidth(config.getColumnWidth(i)); - } - this.getTableHeader().getColumnModel().addColumnModelListener(modeListener); - this.doLayout(); - this.repaint(); - } - - public DataTableConfig update() { - config.setRowHeight(this.getRowHeight(0)); - model = new BeanTableModel(); - String[] columns = new String[this.getColumnCount()]; - for (int i = 0; i < this.getColumnCount(); i++) { - config.setColumnWidth(i, this.getColumn(this.getColumnName(i)).getWidth()); - columns[i] = this.getColumnName(i); - } - - config.setColumns(columns); - return config; - } - - public class BeanTableModel extends AbstractTableModel { - - @Override - public int getColumnCount() { - return config.getColumnCount(); - } - - @Override - public int getRowCount() { - return 1; - } - - @Override - public String getColumnName(int column) { - return config.getColumnName(column); - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - return config.getTableDataName() + "." + config.getColumnName(columnIndex); - } - - } - - class MouseAdapterListener extends MouseAdapter { - private JTable table; - int oldY = 0; - int newY = 0; - int row = 0; - int oldHeight = 0; - boolean drag = false; - int increase = 0; - JPopupMenu popupMenu; - - public MouseAdapterListener(JTable table) { - this.table = table; - popupMenu = new JPopupMenu(); - - popupMenu.add(new CutAction()); - popupMenu.add(new CutAction()); - popupMenu.add(new CutAction()); - popupMenu.add(new CutAction()); - } - - class CutAction extends UpdateAction { - - /** - * Constructor - */ - public CutAction() { - this.setName(Inter.getLocText("M_Edit-Cut")); - this.setMnemonic('T'); - this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); - this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); - } - - @Override - public void actionPerformed(ActionEvent e) { - int row = table.getSelectedRow(); - int column = table.getSelectedColumn(); - table.getColumnModel().removeColumn(table.getColumn(table.getColumnName(column))); - DataTableConfigPane.this.propertyChange(); - } - } - - public void mouseMoved(MouseEvent e) { - int onRow = table.rowAtPoint(e.getPoint()); - - int height = 0; - for (int i = 0; i <= onRow; i++) { - height = height + table.getRowHeight(i); - } - - if (height - e.getY() < 3) { - drag = true; - table.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR)); - } else { - drag = false; - table.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } - - } - - private void trigger_popup(MouseEvent e) { - - popupMenu.show(table, e.getX(), e.getY()); - } - - public void mouseDragged(MouseEvent e) { - if (drag) { - int value = oldHeight + e.getY() - oldY; - if (value < 30) - table.setRowHeight(row, 30); - else - table.setRowHeight(row, oldHeight + e.getY() - oldY); - DataTableConfigPane.this.propertyChange(); - } - } - - public void mousePressed(MouseEvent e) { - oldY = e.getY(); - row = table.rowAtPoint(e.getPoint()); - oldHeight = table.getRowHeight(row); - if (e.getButton() == MouseEvent.BUTTON3) { - trigger_popup(e); - } - } - - public void mouseReleased(MouseEvent e) { - newY = e.getY(); - table.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } - } - } - - private ArrayList changetList = new ArrayList(); - - public void addpropertyChangeListener(PropertyChangeListener l) { - changetList.add(l); - } - - @Override - public void propertyChange() { - for (PropertyChangeListener l : changetList) { - l.propertyChange(); - } - } + private DataEditingTable table; + + public DataTableConfigPane() { + table = new DataEditingTable(); + JScrollPane scrollPane = new JScrollPane(table); + this.setLayout(new DataTableLayout()); + this.add(scrollPane, BorderLayout.CENTER); + } + + public void populate(DataTableConfig config) { + table.populate(config); + } + + public DataTableConfig update() { + return table.update(); + } + + class DataTableLayout extends BorderLayout { + public void layoutContainer(Container target) { + super.layoutContainer(target); + table.doLayout(); + } + } + + class DataEditingTable extends JTable { + + private DataTableConfig config; + private BeanTableModel model; + private TableColumnModelListener modeListener; + + public DataEditingTable() { + this.setBorder(BorderFactory.createLineBorder(new Color(210, 210, 210), 1)); + this.setColumnSelectionAllowed(true); + this.setRowSelectionAllowed(true); + MouseAdapterListener l = new MouseAdapterListener(this); + this.addMouseListener(l); + this.addMouseMotionListener(l); + model = new BeanTableModel(); + modeListener = new TableColumnModelListener() { + + @Override + public void columnAdded(TableColumnModelEvent e) { + + } + + @Override + public void columnMarginChanged(ChangeEvent e) { + DataTableConfigPane.this.propertyChange(); + } + + @Override + public void columnMoved(TableColumnModelEvent e) { + DataTableConfigPane.this.propertyChange(); + } + + @Override + public void columnRemoved(TableColumnModelEvent e) { + + } + + @Override + public void columnSelectionChanged(ListSelectionEvent e) { + + } + + }; + } + + public TableCellRenderer getCellRenderer(int row, int column) { + TableCellRenderer renderer = super.getCellRenderer(row, column); + if (renderer instanceof UILabel) { + ((UILabel) renderer).setHorizontalAlignment(UILabel.CENTER); + } + return renderer; + } + + public void populate(DataTableConfig config) { + this.getTableHeader().getColumnModel().removeColumnModelListener(modeListener); + if (config == null) { + config = DataTableConfig.DEFAULT_TABLE_DATA_CONFIG; + } + this.config = config; + + model = new BeanTableModel(); + this.setModel(model); + this.setRowHeight(0, config.getRowHeight()); + for (int i = 0; i < config.getColumnCount(); i++) { + this.getColumn(this.getColumnName(i)).setPreferredWidth(config.getColumnWidth(i)); + } + this.getTableHeader().getColumnModel().addColumnModelListener(modeListener); + this.doLayout(); + this.repaint(); + } + + public DataTableConfig update() { + config.setRowHeight(this.getRowHeight(0)); + model = new BeanTableModel(); + String[] columns = new String[this.getColumnCount()]; + for (int i = 0; i < this.getColumnCount(); i++) { + config.setColumnWidth(i, this.getColumn(this.getColumnName(i)).getWidth()); + columns[i] = this.getColumnName(i); + } + + config.setColumns(columns); + return config; + } + + public class BeanTableModel extends AbstractTableModel { + + @Override + public int getColumnCount() { + return config.getColumnCount(); + } + + @Override + public int getRowCount() { + return 1; + } + + @Override + public String getColumnName(int column) { + return config.getColumnName(column); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return config.getTableDataName() + "." + config.getColumnName(columnIndex); + } + + } + + class MouseAdapterListener extends MouseAdapter { + private JTable table; + int oldY = 0; + int newY = 0; + int row = 0; + int oldHeight = 0; + boolean drag = false; + int increase = 0; + JPopupMenu popupMenu; + + public MouseAdapterListener(JTable table) { + this.table = table; + popupMenu = new JPopupMenu(); + + popupMenu.add(new CutAction()); + popupMenu.add(new CutAction()); + popupMenu.add(new CutAction()); + popupMenu.add(new CutAction()); + } + + class CutAction extends UpdateAction { + + /** + * Constructor + */ + public CutAction() { + this.setName(Inter.getLocText("M_Edit-Cut")); + this.setMnemonic('T'); + this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/cut.png")); + this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); + } + + @Override + public void actionPerformed(ActionEvent e) { + int row = table.getSelectedRow(); + int column = table.getSelectedColumn(); + table.getColumnModel().removeColumn(table.getColumn(table.getColumnName(column))); + DataTableConfigPane.this.propertyChange(); + } + } + + public void mouseMoved(MouseEvent e) { + int onRow = table.rowAtPoint(e.getPoint()); + + int height = 0; + for (int i = 0; i <= onRow; i++) { + height = height + table.getRowHeight(i); + } + + if (height - e.getY() < 3) { + drag = true; + table.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR)); + } else { + drag = false; + table.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + + } + + private void trigger_popup(MouseEvent e) { + + popupMenu.show(table, e.getX(), e.getY()); + } + + public void mouseDragged(MouseEvent e) { + if (drag) { + int value = oldHeight + e.getY() - oldY; + if (value < 30) { + table.setRowHeight(row, 30); + } else { + table.setRowHeight(row, oldHeight + e.getY() - oldY); + } + DataTableConfigPane.this.propertyChange(); + } + } + + public void mousePressed(MouseEvent e) { + oldY = e.getY(); + row = table.rowAtPoint(e.getPoint()); + oldHeight = table.getRowHeight(row); + if (e.getButton() == MouseEvent.BUTTON3) { + trigger_popup(e); + } + } + + public void mouseReleased(MouseEvent e) { + newY = e.getY(); + table.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + } + } + + private ArrayList changetList = new ArrayList(); + + public void addpropertyChangeListener(PropertyChangeListener l) { + changetList.add(l); + } + + @Override + public void propertyChange() { + for (PropertyChangeListener l : changetList) { + l.propertyChange(); + } + } @Override public void propertyChange(Object mark) { } - @Override - public void propertyChange(Object[] marks) { + @Override + public void propertyChange(Object[] marks) { - } + } } \ No newline at end of file From 16925fe0ae01aacfe41a36ba3a51a6ead48fdb75 Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 14:38:04 +0800 Subject: [PATCH 09/20] PMD --- .../autocomplete/AutoCompletePopupWindow.java | 14 ++-- .../gui/autocomplete/AutoCompletion.java | 6 +- .../ParameterizedCompletionContext.java | 71 ++++++++----------- .../gui/itabpane/UITabsHeaderIconPane.java | 15 ++-- 4 files changed, 48 insertions(+), 58 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java index 40b3d7ca2..4dced3a83 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java @@ -10,6 +10,7 @@ package com.fr.design.gui.autocomplete; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.PopupWindowDecorator; +import com.fr.general.FRLogger; import javax.swing.*; import javax.swing.event.CaretEvent; @@ -301,7 +302,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, private void installKeyBindings() { if (AutoCompletion.isDebug()) { - System.out.println("PopupWindow: Installing keybindings"); + FRLogger.getLogger().debug("PopupWindow: Installing keybindings"); } if (escapeKap == null) { // Lazily create actions. @@ -386,15 +387,16 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, // Try to position to the right first (LTR) int x; + int dis = 5; if (ac.getTextComponentOrientation().isLeftToRight()) { - x = getX() + getWidth() + 5; + x = getX() + getWidth() + dis; if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit - x = getX() - 5 - descWindow.getWidth(); + x = getX() - dis - descWindow.getWidth(); } } else { // RTL - x = getX() - 5 - descWindow.getWidth(); + x = getX() - dis - descWindow.getWidth(); if (x < screenBounds.x) { // Doesn't fit - x = getX() + getWidth() + 5; + x = getX() + getWidth() + dis; } } @@ -709,7 +711,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, private void uninstallKeyBindings() { if (AutoCompletion.isDebug()) { - System.out.println("PopupWindow: Removing keybindings"); + FRLogger.getLogger().debug("PopupWindow: Removing keybindings"); } JTextComponent comp = ac.getTextComponent(); diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java index d5447880b..fb5f2b763 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletion.java @@ -277,7 +277,7 @@ public class AutoCompletion { * @return Whether to auto-complete single choices. * @see #setAutoCompleteSingleChoices(boolean) */ - public boolean getAutoCompleteSingleChoices() { + public boolean isAutoCompleteSingleChoices() { return autoCompleteSingleChoices; } @@ -730,7 +730,7 @@ public class AutoCompletion { private boolean needSetPopupWindow(int count, int textLen) { return (count == 1 && (isPopupVisible() || textLen == 0)) - || (count == 1 && !getAutoCompleteSingleChoices()) + || (count == 1 && !isAutoCompleteSingleChoices()) || count > 1; } @@ -809,7 +809,7 @@ public class AutoCompletion { * be automatically inserted, without displaying the popup menu. * * @param autoComplete Whether to auto-complete single choices. - * @see #getAutoCompleteSingleChoices() + * @see #isAutoCompleteSingleChoices() */ public void setAutoCompleteSingleChoices(boolean autoComplete) { autoCompleteSingleChoices = autoComplete; diff --git a/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java b/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java index 966035b89..11bab3a7e 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java @@ -14,6 +14,7 @@ import com.fr.design.gui.autocomplete.ParameterizedCompletionInsertionInfo.Repla import com.fr.design.gui.syntax.ui.rsyntaxtextarea.DocumentRange; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea; import com.fr.design.gui.syntax.ui.rtextarea.ChangeableHighlightPainter; +import com.fr.general.FRLogger; import javax.swing.*; import javax.swing.event.CaretEvent; @@ -254,7 +255,7 @@ class ParameterizedCompletionContext { * * @param offs The offset into the document. * @return The text of the parameter containing the offset, or - * null if the offset is not in a parameter. + * null if the offset is not in a parameter. */ public String getArgumentText(int offs) { List paramHighlights = getParameterHighlights(); @@ -284,7 +285,7 @@ class ParameterizedCompletionContext { * Returns the highlight of the current parameter. * * @return The current parameter's highlight, or null if - * the caret is not in a parameter's bounds. + * the caret is not in a parameter's bounds. * @see #getCurrentParameterStartOffset() */ private Highlight getCurrentParameterHighlight() { @@ -332,7 +333,7 @@ class ParameterizedCompletionContext { * Returns the starting offset of the current parameter. * * @return The current parameter's starting offset, or -1 if - * the caret is not in a parameter's bounds. + * the caret is not in a parameter's bounds. * @see #getCurrentParameterHighlight() */ private int getCurrentParameterStartOffset() { @@ -407,7 +408,7 @@ class ParameterizedCompletionContext { * Inserts the choice selected in the parameter choices window. * * @return Whether the choice was inserted. This will be false - * if the window is not visible, or no choice is selected. + * if the window is not visible, or no choice is selected. */ boolean insertSelectedChoice() { if (paramChoicesWindow != null && paramChoicesWindow.isVisible()) { @@ -438,11 +439,9 @@ class ParameterizedCompletionContext { * @see #uninstallKeyBindings() */ private void installKeyBindings() { - if (AutoCompletion.isDebug()) { - System.out.println("CompletionContext: Installing keybindings"); + FRLogger.getLogger().debug("CompletionContext: Installing keybindings"); } - JTextComponent tc = ac.getTextComponent(); InputMap im = tc.getInputMap(); ActionMap am = tc.getActionMap(); @@ -489,7 +488,6 @@ class ParameterizedCompletionContext { im.put(ks, IM_KEY_CLOSING); oldClosingAction = am.get(IM_KEY_CLOSING); am.put(IM_KEY_CLOSING, new ClosingAction()); - } @@ -513,12 +511,7 @@ class ParameterizedCompletionContext { List highlights = getParameterHighlights(); for (int i = 0; i < highlights.size(); i++) { Highlight hl = highlights.get(i); - // Check "< dot", not "<= dot" as OutlineHighlightPainter paints - // starting at one char AFTER the highlight starts, to work around - // Java issue. Thanks to Matthew Adereth! - if (currentNext == null || currentNext.getStartOffset() dot && - hl.getStartOffset() <= currentNext.getStartOffset())) { + if (needUpdate(currentNext, hl, dot)) { currentNext = hl; pos = i; } @@ -538,6 +531,15 @@ class ParameterizedCompletionContext { } + private boolean needUpdate(Highlight currentNext, Highlight hl, int dot) { + // Check "< dot", not "<= dot" as OutlineHighlightPainter paints + // starting at one char AFTER the highlight starts, to work around + // Java issue. Thanks to Matthew Adereth! + return currentNext == null || currentNext.getStartOffset() dot && + hl.getStartOffset() <= currentNext.getStartOffset()); + } + /** * Moves to and selects the previous parameter. @@ -562,10 +564,7 @@ class ParameterizedCompletionContext { for (int i = 0; i < highlights.size(); i++) { Highlight h = highlights.get(i); - if (currentPrev == null || currentPrev.getStartOffset() >= dot || - (h.getStartOffset() < selStart && - (h.getStartOffset() > currentPrev.getStartOffset() || - pos == lastSelectedParam))) { + if (pos == lastSelectedParam || needUpdate(currentPrev, dot, h, selStart)) { currentPrev = h; pos = i; } @@ -593,6 +592,12 @@ class ParameterizedCompletionContext { } + private boolean needUpdate(Highlight currentPrev, int dot, Highlight h, int selStart) { + return currentPrev == null + || currentPrev.getStartOffset() >= dot + || (currentPrev.getStartOffset() < h.getStartOffset() && h.getStartOffset() < selStart); + } + private void possiblyUpdateParamCopies(Document doc) { @@ -616,7 +621,7 @@ class ParameterizedCompletionContext { try { replacement = doc.getText(start, len); } catch (BadLocationException ble) { - // Never happens + // Never happens } // Replace any param copies tracking this parameter with the @@ -718,7 +723,7 @@ class ParameterizedCompletionContext { return h; } catch (BadLocationException ble) { - // Never happens + // Never happens } return null; @@ -734,7 +739,7 @@ class ParameterizedCompletionContext { private void uninstallKeyBindings() { if (AutoCompletion.isDebug()) { - System.out.println("CompletionContext Uninstalling keybindings"); + FRLogger.getLogger().debug("CompletionContext Uninstalling keybindings"); } JTextComponent tc = ac.getTextComponent(); @@ -1037,7 +1042,6 @@ class ParameterizedCompletionContext { * @see #uninstall() */ public void install(JTextComponent tc) { - boolean replaceTabs = false; if (tc instanceof RSyntaxTextArea) { RSyntaxTextArea textArea = (RSyntaxTextArea) tc; @@ -1047,14 +1051,10 @@ class ParameterizedCompletionContext { } Highlighter h = tc.getHighlighter(); - try { - // Insert the parameter text - ParameterizedCompletionInsertionInfo info = - pc.getInsertionInfo(tc, replaceTabs); + ParameterizedCompletionInsertionInfo info = pc.getInsertionInfo(tc, replaceTabs); tc.replaceSelection(info.getTextToInsert()); - // Add highlights around the parameters. final int replacementCount = info.getReplacementCount(); for (int i = 0; i < replacementCount; i++) { @@ -1067,40 +1067,31 @@ class ParameterizedCompletionContext { for (int i = 0; i < info.getReplacementCopyCount(); i++) { ReplacementCopy rc = info.getReplacementCopy(i); paramCopyInfos.add(new ParamCopyInfo(rc.getId(), - (Highlight) h.addHighlight(rc.getStart(), rc.getEnd(), - paramCopyP))); + (Highlight) h.addHighlight(rc.getStart(), rc.getEnd(), paramCopyP))); } - // Go back and start at the first parameter. tc.setCaretPosition(info.getSelectionStart()); if (info.hasSelection()) { tc.moveCaretPosition(info.getSelectionEnd()); } - minPos = info.getMinOffset(); maxPos = info.getMaxOffset(); try { - defaultEndOffs = tc.getDocument().createPosition( - info.getDefaultEndOffs()); + defaultEndOffs = tc.getDocument().createPosition(info.getDefaultEndOffs()); } catch (BadLocationException ble) { - // Never happens + // Never happens } - // Listen for document events AFTER we insert tc.getDocument().addDocumentListener(this); - } catch (BadLocationException ble) { - // Never happens + // Never happens } - // Add listeners to the text component, AFTER text insertion. tc.addCaretListener(this); tc.addFocusListener(this); installKeyBindings(); - } - public void removeUpdate(DocumentEvent e) { handleDocumentEvent(e); } diff --git a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java index ba7752352..8bb2f7b05 100644 --- a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java +++ b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java @@ -10,6 +10,7 @@ import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.swing.AbstractAction; @@ -145,9 +146,7 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { private void show(final JPanel panel) { int count = centerPane.getComponentCount();// 获取centerPanel中控件数 List list = new ArrayList();// - for (Component comp : centerPane.getComponents()) { - list.add(comp); - } + list.addAll(Arrays.asList(centerPane.getComponents())); if (count > 0) {// 如果centerPanel中控件数大于0就执行效果 for (int i = 0; i < count; i++) { Component comp = centerPane.getComponent(i);// 获得该位置的控件 @@ -160,14 +159,12 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { public void run() { int height = centerPane.getHeight(); int width = centerPane.getWidth(); - int step = 30; - int x = 0; int y = -height; - for (int i = 0; i <= height; i += step) { + for (int i = 0; i <= height; i += 30) { // 设置面板位置 - currentPanel.setBounds(x, i, width, height); - panel.setBounds(x, y, width, height); - y += step; + currentPanel.setBounds(0, i, width, height); + panel.setBounds(0, y, width, height); + y += 30; try { Thread.sleep(3); } catch (InterruptedException e) { From e959791ed3f17ae10d31edce3707d697cacf5b7d Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 14:43:48 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E5=B1=80=E9=83=A8=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E4=B8=8D=E8=A1=8C..=E8=BF=98=E6=98=AF=E6=94=B9=E5=9B=9E?= =?UTF-8?q?=E5=8E=BB=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/gui/autocomplete/AutoCompletePopupWindow.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java index 4dced3a83..ec303ee44 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java @@ -387,16 +387,15 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, // Try to position to the right first (LTR) int x; - int dis = 5; if (ac.getTextComponentOrientation().isLeftToRight()) { - x = getX() + getWidth() + dis; + x = getX() + getWidth() + 5; if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit - x = getX() - dis - descWindow.getWidth(); + x = getX() - 5 - descWindow.getWidth(); } } else { // RTL - x = getX() - dis - descWindow.getWidth(); + x = getX() - 5 - descWindow.getWidth(); if (x < screenBounds.x) { // Doesn't fit - x = getX() + getWidth() + dis; + x = getX() + getWidth() + 5; } } From c6d1d6d9eedc600c78d03416a6132531444d8164 Mon Sep 17 00:00:00 2001 From: hzzz Date: Thu, 25 May 2017 14:53:59 +0800 Subject: [PATCH 11/20] PMD --- .../autocomplete/AutoCompletePopupWindow.java | 9 ++-- .../gui/itabpane/UITabsHeaderIconPane.java | 44 ++++++------------- .../widget/editors/DataTableConfigPane.java | 8 ++-- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java index ec303ee44..22bb4edf7 100644 --- a/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java +++ b/designer_base/src/com/fr/design/gui/autocomplete/AutoCompletePopupWindow.java @@ -41,6 +41,7 @@ import java.util.List; class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSelectionListener, MouseListener { + private final static int DIS = 5; /** * The parent AutoCompletion instance. */ @@ -388,14 +389,14 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, // Try to position to the right first (LTR) int x; if (ac.getTextComponentOrientation().isLeftToRight()) { - x = getX() + getWidth() + 5; + x = getX() + getWidth() + DIS; if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit - x = getX() - 5 - descWindow.getWidth(); + x = getX() - DIS - descWindow.getWidth(); } } else { // RTL - x = getX() - 5 - descWindow.getWidth(); + x = getX() - DIS - descWindow.getWidth(); if (x < screenBounds.x) { // Doesn't fit - x = getX() + getWidth() + 5; + x = getX() + getWidth() + DIS; } } diff --git a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java index 8bb2f7b05..84f0cd35f 100644 --- a/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java +++ b/designer_base/src/com/fr/design/gui/itabpane/UITabsHeaderIconPane.java @@ -1,38 +1,22 @@ package com.fr.design.gui.itabpane; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.GradientPaint; -import java.awt.Graphics2D; -import java.awt.GridLayout; +import com.fr.base.BaseUtils; +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.core.UITabComponent; +import com.fr.design.gui.ibutton.UITabButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.stable.StringUtils; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.InputMap; -import javax.swing.JComponent; - -import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ilable.UILabel; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.SwingConstants; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import com.fr.base.BaseUtils; -import com.fr.design.gui.core.UITabComponent; -import com.fr.design.gui.ibutton.UITabButton; -import com.fr.stable.StringUtils; - import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; /** @@ -43,6 +27,7 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M */ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { private static final long serialVersionUID = 1L; + private static final int DIS = 30; private UILabel nameLabel; @@ -160,11 +145,11 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { int height = centerPane.getHeight(); int width = centerPane.getWidth(); int y = -height; - for (int i = 0; i <= height; i += 30) { + for (int i = 0; i <= height; i += DIS) { // 设置面板位置 currentPanel.setBounds(0, i, width, height); panel.setBounds(0, y, width, height); - y += 30; + y += DIS; try { Thread.sleep(3); } catch (InterruptedException e) { @@ -174,7 +159,6 @@ public class UITabsHeaderIconPane extends JPanel implements UITabComponent { centerPane.remove(currentPanel);// 移除当前面板 } panel.setBounds(0, 0, width, height); - } }.start(); break; diff --git a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java index a45d9fa25..00d70bd1e 100644 --- a/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java +++ b/designer_form/src/com/fr/design/mainframe/widget/editors/DataTableConfigPane.java @@ -157,6 +157,8 @@ public class DataTableConfigPane extends JComponent implements PropertyChangeLis } class MouseAdapterListener extends MouseAdapter { + private final static int DIS = 30; + private final static int SMALL_DIS = 3; private JTable table; int oldY = 0; int newY = 0; @@ -205,7 +207,7 @@ public class DataTableConfigPane extends JComponent implements PropertyChangeLis height = height + table.getRowHeight(i); } - if (height - e.getY() < 3) { + if (height - e.getY() < SMALL_DIS) { drag = true; table.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR)); } else { @@ -223,8 +225,8 @@ public class DataTableConfigPane extends JComponent implements PropertyChangeLis public void mouseDragged(MouseEvent e) { if (drag) { int value = oldHeight + e.getY() - oldY; - if (value < 30) { - table.setRowHeight(row, 30); + if (value < DIS) { + table.setRowHeight(row, DIS); } else { table.setRowHeight(row, oldHeight + e.getY() - oldY); } From 1f5114ede1d693529a6f0a2ad9cc8dd4b44d5d43 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 09:31:27 +0800 Subject: [PATCH 12/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- designer/src/com/fr/grid/GridKeyListener.java | 397 +++++++++--------- 1 file changed, 200 insertions(+), 197 deletions(-) diff --git a/designer/src/com/fr/grid/GridKeyListener.java b/designer/src/com/fr/grid/GridKeyListener.java index cf2258a4f..6c82a9dcd 100644 --- a/designer/src/com/fr/grid/GridKeyListener.java +++ b/designer/src/com/fr/grid/GridKeyListener.java @@ -1,212 +1,215 @@ package com.fr.grid; -import java.awt.Toolkit; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; - import com.fr.design.mainframe.ElementCasePane; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; import com.fr.report.elementcase.ElementCase; +import com.fr.stable.OperatingSystem; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; /** - * * @editor zhou * @since 2012-3-23上午10:55:36 */ public class GridKeyListener implements KeyListener { - private Grid grid; - // Keypressed last time - private long keyPressedLastTime = 0; - private boolean isKeyPressedContentChanged = false; - - public GridKeyListener(Grid grid) { - this.grid = grid; - } - - public void keyPressed(KeyEvent evt) { - if (!grid.isEnabled() || evt.isConsumed()) {// 如果用户在自己的KyeListener里面consume了.就不执行下面的代码了. - return; - } - KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); - if (newEvt == null) { - return; - } - long systemCurrentTime = System.currentTimeMillis(); - int code = evt.getKeyCode(); - boolean isNeedRepaint = false; - ElementCasePane reportPane = grid.getElementCasePane(); - ElementCase report = reportPane.getEditingElementCase(); - if (reportPane.getSelection() instanceof FloatSelection) { - if (systemCurrentTime - keyPressedLastTime <= 2) { - return; - } else { - keyPressedLastTime = systemCurrentTime; - } - dealWithFloatSelection(reportPane, code); - - } else { - if (systemCurrentTime - keyPressedLastTime <= 32) { - return; - } else { - keyPressedLastTime = systemCurrentTime; - } - dealWithCellSelection(evt, code); - - } - - switch (code) { - case KeyEvent.VK_PAGE_UP: {// page up - reportPane.getVerticalScrollBar().setValue(Math.max(0, grid.getVerticalValue() - grid.getVerticalExtent())); - isNeedRepaint = true; - break; - } - case KeyEvent.VK_PAGE_DOWN: {// page down - reportPane.getVerticalScrollBar().setValue(grid.getVerticalValue() + grid.getVerticalExtent()); - isNeedRepaint = true; - break; - } - // Richie:Ctrl + A全选单元格 - case KeyEvent.VK_A: - if (code == KeyEvent.VK_A && evt.isControlDown()) { - reportPane.setSelection(new CellSelection(0, 0, report.getColumnCount(), report.getRowCount())); - isNeedRepaint = true; - } - isNeedRepaint = true; - break; - } - - if (isNeedRepaint) { - reportPane.repaint(); - } - } - - /** - * 单选中悬浮元素时,只处理4个方向键 - * - * @param reportPane - * @param code - */ - private void dealWithFloatSelection(ElementCasePane reportPane, int code) { - boolean isContentChanged = false; - FloatSelection floatselection = (FloatSelection)reportPane.getSelection(); - - switch (code) { - case KeyEvent.VK_LEFT: {// left - floatselection.moveLeft(reportPane); - isContentChanged = true; - break; - } - case KeyEvent.VK_RIGHT: {// right - floatselection.moveRight(reportPane); - isContentChanged = true; - break; - } - case KeyEvent.VK_UP: {// up - floatselection.moveUp(reportPane); - isContentChanged = true; - break; - } - case KeyEvent.VK_DOWN: {// down - floatselection.moveDown(reportPane); - isContentChanged = true; - break; - } - } - - if (isContentChanged) { - grid.getElementCasePane().repaint(); - this.isKeyPressedContentChanged = true; - } - } - - private void dealWithCellSelection(KeyEvent evt, int code) { - switch (code) { - case KeyEvent.VK_ESCAPE: { - if (grid.isCellEditing()) { - grid.cancelEditing(); - } - break; - } - case KeyEvent.VK_F2: { - if (!grid.isCellEditing()) { - grid.startEditing(); - } - - break; - } - } - - // 支持小键盘 - if (IS_NUM_PAD_KEY(code)) { - keyTyped(evt); - } - } - - public void keyReleased(KeyEvent evt) { - if (!grid.isEnabled() || evt.isConsumed()) { - return; - } - KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); - if (newEvt == null) { - return; - } - - if (this.isKeyPressedContentChanged) { - grid.getElementCasePane().fireTargetModified(); - - this.isKeyPressedContentChanged = false; - } - } - - public void keyTyped(KeyEvent evt) { - if (!grid.isEnabled() || evt.isConsumed()) { - return; - } - KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); - if (newEvt == null || evt.isControlDown()) {// uneditable. - return; - } - char ch = evt.getKeyChar(); - if (ch == KeyEvent.VK_TAB) {// 禁止Tab键. - return; - } - int code = evt.getKeyCode(); - if (Character.isDefined(ch)) {// VK_SUBTRACT小键盘的减号 - Selection s = grid.getElementCasePane().getSelection(); - if (s instanceof CellSelection) { - if (!grid.getElementCasePane().isSelectedOneCell()) { - Toolkit.getDefaultToolkit().beep(); - return; - } - if (!grid.isCellEditing()) { - grid.startEditing(true); - } - - if (grid.getCellEditor() != null && grid.editorComponent != null) { - if (IS_NUM_PAD_KEY(code)) { - // 103 - 55 = 48, 小键盘和大键盘数字的差值 48 - KeyEvent ke = new KeyEvent(grid, KeyEvent.KEY_PRESSED, 0, 0, code - 48, ch); - grid.editorComponent.dispatchEvent(ke); - ke.consume(); - } else { - if (!evt.isConsumed()) { - grid.editorComponent.dispatchEvent(evt); - } - } - } - } - } - } - /** - * 小键盘 - * @param code - * @return - */ - private static boolean IS_NUM_PAD_KEY(int code){ - return code == KeyEvent.VK_NUMPAD0 || code == KeyEvent.VK_NUMPAD1 + private Grid grid; + // Keypressed last time + private long keyPressedLastTime = 0; + private boolean isKeyPressedContentChanged = false; + + public GridKeyListener(Grid grid) { + this.grid = grid; + } + + public void keyPressed(KeyEvent evt) { + if (!grid.isEnabled() || evt.isConsumed()) {// 如果用户在自己的KyeListener里面consume了.就不执行下面的代码了. + return; + } + KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); + if (newEvt == null) { + return; + } + long systemCurrentTime = System.currentTimeMillis(); + int code = evt.getKeyCode(); + boolean isNeedRepaint = false; + ElementCasePane reportPane = grid.getElementCasePane(); + ElementCase report = reportPane.getEditingElementCase(); + if (reportPane.getSelection() instanceof FloatSelection) { + if (systemCurrentTime - keyPressedLastTime <= 2) { + return; + } else { + keyPressedLastTime = systemCurrentTime; + } + dealWithFloatSelection(reportPane, code); + + } else { + if (systemCurrentTime - keyPressedLastTime <= 32) { + return; + } else { + keyPressedLastTime = systemCurrentTime; + } + dealWithCellSelection(evt, code); + + } + + switch (code) { + case KeyEvent.VK_PAGE_UP: {// page up + reportPane.getVerticalScrollBar().setValue(Math.max(0, grid.getVerticalValue() - grid.getVerticalExtent())); + isNeedRepaint = true; + break; + } + case KeyEvent.VK_PAGE_DOWN: {// page down + reportPane.getVerticalScrollBar().setValue(grid.getVerticalValue() + grid.getVerticalExtent()); + isNeedRepaint = true; + break; + } + // Richie:Ctrl + A全选单元格 + case KeyEvent.VK_A: + if ((OperatingSystem.isWindows() && evt.isControlDown()) + || OperatingSystem.isMacOS() && evt.isMetaDown()) { + reportPane.setSelection(new CellSelection(0, 0, report.getColumnCount(), report.getRowCount())); + isNeedRepaint = true; + } + isNeedRepaint = true; + break; + } + + if (isNeedRepaint) { + reportPane.repaint(); + } + } + + /** + * 单选中悬浮元素时,只处理4个方向键 + * + * @param reportPane + * @param code + */ + private void dealWithFloatSelection(ElementCasePane reportPane, int code) { + boolean isContentChanged = false; + FloatSelection floatselection = (FloatSelection) reportPane.getSelection(); + + switch (code) { + case KeyEvent.VK_LEFT: {// left + floatselection.moveLeft(reportPane); + isContentChanged = true; + break; + } + case KeyEvent.VK_RIGHT: {// right + floatselection.moveRight(reportPane); + isContentChanged = true; + break; + } + case KeyEvent.VK_UP: {// up + floatselection.moveUp(reportPane); + isContentChanged = true; + break; + } + case KeyEvent.VK_DOWN: {// down + floatselection.moveDown(reportPane); + isContentChanged = true; + break; + } + } + + if (isContentChanged) { + grid.getElementCasePane().repaint(); + this.isKeyPressedContentChanged = true; + } + } + + private void dealWithCellSelection(KeyEvent evt, int code) { + switch (code) { + case KeyEvent.VK_ESCAPE: { + if (grid.isCellEditing()) { + grid.cancelEditing(); + } + break; + } + case KeyEvent.VK_F2: { + if (!grid.isCellEditing()) { + grid.startEditing(); + } + + break; + } + } + + // 支持小键盘 + if (IS_NUM_PAD_KEY(code)) { + keyTyped(evt); + } + } + + public void keyReleased(KeyEvent evt) { + if (!grid.isEnabled() || evt.isConsumed()) { + return; + } + KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); + if (newEvt == null) { + return; + } + + if (this.isKeyPressedContentChanged) { + grid.getElementCasePane().fireTargetModified(); + + this.isKeyPressedContentChanged = false; + } + } + + public void keyTyped(KeyEvent evt) { + if (!grid.isEnabled() || evt.isConsumed()) { + return; + } + KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); + if (newEvt == null || evt.isControlDown()) {// uneditable. + return; + } + char ch = evt.getKeyChar(); + if (ch == KeyEvent.VK_TAB) {// 禁止Tab键. + return; + } + int code = evt.getKeyCode(); + if (Character.isDefined(ch)) {// VK_SUBTRACT小键盘的减号 + Selection s = grid.getElementCasePane().getSelection(); + if (s instanceof CellSelection) { + if (!grid.getElementCasePane().isSelectedOneCell()) { + Toolkit.getDefaultToolkit().beep(); + return; + } + if (!grid.isCellEditing()) { + grid.startEditing(true); + } + + if (grid.getCellEditor() != null && grid.editorComponent != null) { + if (IS_NUM_PAD_KEY(code)) { + // 103 - 55 = 48, 小键盘和大键盘数字的差值 48 + KeyEvent ke = new KeyEvent(grid, KeyEvent.KEY_PRESSED, 0, 0, code - 48, ch); + grid.editorComponent.dispatchEvent(ke); + ke.consume(); + } else { + if (!evt.isConsumed()) { + grid.editorComponent.dispatchEvent(evt); + } + } + } + } + } + } + + /** + * 小键盘 + * + * @param code + * @return + */ + private static boolean IS_NUM_PAD_KEY(int code) { + return code == KeyEvent.VK_NUMPAD0 || code == KeyEvent.VK_NUMPAD1 || code == KeyEvent.VK_NUMPAD2 || code == KeyEvent.VK_NUMPAD3 || code == KeyEvent.VK_NUMPAD4 @@ -215,10 +218,10 @@ public class GridKeyListener implements KeyListener { || code == KeyEvent.VK_NUMPAD7 || code == KeyEvent.VK_NUMPAD8 || code == KeyEvent.VK_NUMPAD9 - || code == KeyEvent.VK_MULTIPLY + || code == KeyEvent.VK_MULTIPLY || code == KeyEvent.VK_ADD || code == KeyEvent.VK_SUBTRACT || code == KeyEvent.VK_DECIMAL || code == KeyEvent.VK_DIVIDE; - } + } } \ No newline at end of file From d257489ee45f057161b837deba99a408f4159852 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 09:33:02 +0800 Subject: [PATCH 13/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- designer_base/src/com/fr/design/actions/help/AboutPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer_base/src/com/fr/design/actions/help/AboutPane.java b/designer_base/src/com/fr/design/actions/help/AboutPane.java index 9c8953597..1155f4e92 100644 --- a/designer_base/src/com/fr/design/actions/help/AboutPane.java +++ b/designer_base/src/com/fr/design/actions/help/AboutPane.java @@ -47,7 +47,7 @@ public class AboutPane extends JPanel { BoxCenterAlignmentCopyablePane buildCopyPane = new BoxCenterAlignmentCopyablePane( getBuildTitle(), - GeneralUtils.readBuildNO(), + GeneralUtils.readFullBuildNO(), new String[]{ Inter.getLocText("FR-Designer-Basic_Copy_Build_NO"), Inter.getLocText("FR-Designer-Basic_Copy_Build_NO_OK") From 3f29a1be5aa602c1b369a84be1fac7af05cec03a Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 09:34:42 +0800 Subject: [PATCH 14/20] PMD --- designer/src/com/fr/grid/GridKeyListener.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/designer/src/com/fr/grid/GridKeyListener.java b/designer/src/com/fr/grid/GridKeyListener.java index 6c82a9dcd..a7d6eb354 100644 --- a/designer/src/com/fr/grid/GridKeyListener.java +++ b/designer/src/com/fr/grid/GridKeyListener.java @@ -70,8 +70,9 @@ public class GridKeyListener implements KeyListener { } // Richie:Ctrl + A全选单元格 case KeyEvent.VK_A: - if ((OperatingSystem.isWindows() && evt.isControlDown()) - || OperatingSystem.isMacOS() && evt.isMetaDown()) { + boolean macOS = OperatingSystem.isMacOS() && evt.isMetaDown(); + boolean windows = OperatingSystem.isWindows() && evt.isControlDown(); + if (macOS || windows) { reportPane.setSelection(new CellSelection(0, 0, report.getColumnCount(), report.getRowCount())); isNeedRepaint = true; } From 9c6a862e4337919dfc5abb76275ac7f0513e040a Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 09:37:07 +0800 Subject: [PATCH 15/20] PMD --- designer/src/com/fr/grid/GridKeyListener.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/designer/src/com/fr/grid/GridKeyListener.java b/designer/src/com/fr/grid/GridKeyListener.java index a7d6eb354..8e3148bf5 100644 --- a/designer/src/com/fr/grid/GridKeyListener.java +++ b/designer/src/com/fr/grid/GridKeyListener.java @@ -16,7 +16,7 @@ import java.awt.event.KeyListener; * @since 2012-3-23上午10:55:36 */ public class GridKeyListener implements KeyListener { - + private static final int DIFF = 48; // 103 - 55 = 48, 小键盘和大键盘数字的差值 48 private Grid grid; // Keypressed last time private long keyPressedLastTime = 0; @@ -189,8 +189,7 @@ public class GridKeyListener implements KeyListener { if (grid.getCellEditor() != null && grid.editorComponent != null) { if (IS_NUM_PAD_KEY(code)) { - // 103 - 55 = 48, 小键盘和大键盘数字的差值 48 - KeyEvent ke = new KeyEvent(grid, KeyEvent.KEY_PRESSED, 0, 0, code - 48, ch); + KeyEvent ke = new KeyEvent(grid, KeyEvent.KEY_PRESSED, 0, 0, code - DIFF, ch); grid.editorComponent.dispatchEvent(ke); ke.consume(); } else { From 84f091a2f46203d0e5fe2a40448d6e0f45018b88 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 09:53:18 +0800 Subject: [PATCH 16/20] =?UTF-8?q?REPORT-2773=20mac=E4=B8=AD=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E5=BF=AB=E6=8D=B7=E9=94=AE=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/AuthorityToolBarPane.java | 366 +++- designer/src/com/fr/grid/GridKeyListener.java | 5 +- .../src/com/fr/grid/GridMouseAdapter.java | 1605 ++++++++--------- .../common/inputevent/InputEventBaseOnOS.java | 21 + .../gui/icombobox/ExtendedComboBox.java | 4 +- .../fr/design/gui/icombobox/UIComboBoxUI.java | 3 +- .../com/fr/design/gui/ilist/CheckBoxList.java | 3 +- .../com/fr/design/gui/itable/TableSorter.java | 4 +- .../UserObjectRefreshJTree.java | 3 +- .../fr/design/roleAuthority/UIRoleTreeUI.java | 3 +- .../designer/beans/models/SelectionModel.java | 5 +- 11 files changed, 1205 insertions(+), 817 deletions(-) create mode 100644 designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java diff --git a/designer/src/com/fr/design/mainframe/AuthorityToolBarPane.java b/designer/src/com/fr/design/mainframe/AuthorityToolBarPane.java index 80f40cadf..fcb6988b9 100644 --- a/designer/src/com/fr/design/mainframe/AuthorityToolBarPane.java +++ b/designer/src/com/fr/design/mainframe/AuthorityToolBarPane.java @@ -1 +1,365 @@ -package com.fr.design.mainframe; import com.fr.base.ConfigManager; import com.fr.base.ConfigManagerProvider; import com.fr.base.FRContext; import com.fr.design.beans.BasicBeanPane; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.mainframe.toolbar.AuthorityEditToolBarComponent; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.roleAuthority.RolesAlreadyEditedPane; import com.fr.design.webattr.ReportWebWidgetConstants; import com.fr.design.webattr.ToolBarButton; import com.fr.design.webattr.ToolBarPane; import com.fr.form.ui.Button; import com.fr.form.ui.ToolBar; import com.fr.form.ui.Widget; import com.fr.general.ComparatorUtils; import com.fr.general.Inter; import com.fr.main.TemplateWorkBook; import com.fr.report.web.Location; import com.fr.report.web.ToolBarManager; import com.fr.report.web.WebContent; import com.fr.stable.ArrayUtils; import com.fr.web.attr.ReportWebAttr; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.List; /** * Author : daisy * Date: 13-9-9 * Time: 下午4:58 */ public class AuthorityToolBarPane extends BasicBeanPane implements AuthorityEditToolBarComponent { private static final int SMALL_GAP = 13; private static final int GAP = 25; private static final int PRE_GAP = 9; private static final int COMBOX_WIDTH = 144; private static final String[] CHOOSEITEM = new String[]{Inter.getLocText("M-Page_Preview"), Inter.getLocText(new String[]{"Face_Write", "PageSetup-Page"}), Inter.getLocText("M-Data_Analysis")}; private UIComboBox choseComboBox; private ToolBarPane toolBarPane; private AuthorityEditToolBarPane authorityEditToolBarPane = null; private int selectedIndex = -1; private UILabel title = null; private MouseListener mouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (!toolBarPane.isEnabled()) { return; } java.util.List buttonlists = toolBarPane.getToolBarButtons(); int oldIndex = selectedIndex; selectedIndex = pressButtonIndex(e, buttonlists); //实现shift多选 if (e.isShiftDown()) { if (oldIndex == -1) { removeSelection(); ((ToolBarButton) e.getSource()).setSelected(true); } else { int max = oldIndex >= selectedIndex ? oldIndex : selectedIndex; int min = oldIndex <= selectedIndex ? oldIndex : selectedIndex; for (int i = min; i <= max; i++) { buttonlists.get(i).setSelected(true); } } } else if (!e.isControlDown()) { //实现单选 removeSelection(); if (selectedIndex != -1) { ((ToolBarButton) e.getSource()).setSelected(true); } } authorityEditToolBarPane.populate(); EastRegionContainerPane.getInstance().replaceUpPane(authorityEditToolBarPane); } }; private int pressButtonIndex(MouseEvent e, java.util.List buttonlists) { if (!(e.getSource() instanceof ToolBarButton)) { return -1; } ToolBarButton button = (ToolBarButton) e.getSource(); for (int i = 0; i < buttonlists.size(); i++) { if (ComparatorUtils.equals(button, buttonlists.get(i))) { return i; } } return -1; } /** * 去掉选择 */ public void removeSelection() { for (ToolBarButton button : toolBarPane.getToolBarButtons()) { button.setSelected(false); } } private ItemListener itemListener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.DESELECTED) { selectedIndex = -1; populateToolBarPane(); authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); authorityEditToolBarPane.setAuthorityToolBarPane(AuthorityToolBarPane.this); EastRegionContainerPane.getInstance().replaceUpPane(authorityEditToolBarPane); EastRegionContainerPane.getInstance().replaceDownPane(RolesAlreadyEditedPane.getInstance()); } } }; public AuthorityToolBarPane() { this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 3)); this.setBorder(BorderFactory.createEmptyBorder(0, PRE_GAP, 0, 0)); title = new UILabel(Inter.getLocText(new String[]{"ReportServerP-Toolbar", "Choose_Role"})); title.setHorizontalAlignment(SwingConstants.CENTER); this.add(title, 0); choseComboBox = new UIComboBox(CHOOSEITEM) { public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.width = COMBOX_WIDTH; return dim; } }; choseComboBox.addItemListener(itemListener); //默认选择第一个 choseComboBox.setSelectedIndex(0); this.add(createGapPanel(SMALL_GAP)); this.add(choseComboBox); toolBarPane = new ToolBarPane(); toolBarPane.setBorder(null); toolBarPane.removeDefaultMouseListener(); this.add(createGapPanel(GAP)); this.add(toolBarPane); populateDefaultToolBarWidgets(); populateBean(getReportWebAttr()); toolBarPane.addAuthorityListener(mouseListener); authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); authorityEditToolBarPane.setAuthorityToolBarPane(this); checkToolBarPaneEnable(); } private JPanel createGapPanel(final int gap) { return new JPanel() { public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.width = gap; return dim; } }; } private void populateToolBarPane() { toolBarPane.removeAll(); populateDefaultToolBarWidgets(); populateBean(getReportWebAttr()); toolBarPane.addAuthorityListener(mouseListener); toolBarPane.repaint(); authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); checkToolBarPaneEnable(); } /** * 使用普通用户远程设计时,如果工具栏使用的是“采用服务器设置”,则工具栏按钮为灰不可用 */ private void checkToolBarPaneEnable() { List toolBarButtons = toolBarPane.getToolBarButtons(); boolean isnotEnable = ComparatorUtils.equals(title.getText(), Inter.getLocText(new String[]{"Server", "ReportServerP-Toolbar", "Choose_Role"})) && !FRContext.getCurrentEnv().isRoot(); for (ToolBarButton button : toolBarButtons) { button.setEnabled(!isnotEnable); } toolBarPane.setEnabled(!isnotEnable); } /** * 更新权限工具栏面板 */ public void populateAuthority() { toolBarPane.repaint(); } private ReportWebAttr getReportWebAttr() { JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (!editingTemplate.isJWorkBook()) { return null; } JWorkBook editingWorkBook = (JWorkBook) editingTemplate; TemplateWorkBook wbTpl = editingWorkBook.getTarget(); return wbTpl.getReportWebAttr(); } //将该报表的设置过权限的属性记录一下 public void setAuthorityWebAttr(Widget widget, boolean isSelected, String selectedRole) { JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (!editingTemplate.isJWorkBook()) { return; } JWorkBook editingWorkBook = (JWorkBook) editingTemplate; TemplateWorkBook wbTpl = editingWorkBook.getTarget(); ReportWebAttr rw = wbTpl.getReportWebAttr(); ConfigManagerProvider cm = ConfigManager.getProviderInstance(); ReportWebAttr webAttr = ((ReportWebAttr) cm.getGlobalAttribute(ReportWebAttr.class)); //wbTpl.clear先清空 //再将所有的保存进去 //看是存在服务器还存在模板里面 if (choseComboBox.getSelectedIndex() == 0) { //分页 if (rw == null || rw.getWebPage() == null) { dealWithWebContent(webAttr.getWebPage(), widget, isSelected, selectedRole); } } else if (choseComboBox.getSelectedIndex() == 1) { //填报 if (rw == null || rw.getWebPage() == null) { dealWithWebContent(webAttr.getWebWrite(), widget, isSelected, selectedRole); } } else { //view if (rw == null || rw.getWebPage() == null) { dealWithWebContent(webAttr.getWebView(), widget, isSelected, selectedRole); } } } private void dealWithWebContent(WebContent wc, Widget widget, boolean isSelected, String selectedRole) { ToolBarManager[] managers = wc.getToolBarManagers(); if (managers == null) { return; } for (int i = 0; i < managers.length; i++) { ToolBar tb = managers[i].getToolBar(); for (int j = 0; j < tb.getWidgetSize(); j++) { if (widget instanceof Button && tb.getWidget(j) instanceof Button) { if (ComparatorUtils.equals(((Button) widget).getIconName(), ((Button) tb.getWidget(j)).getIconName())) { if (!isSelected) { tb.getWidget(j).getWidgetPrivilegeControl().addInvisibleRole(selectedRole); } else { tb.getWidget(j).getWidgetPrivilegeControl().removeInvisibleRole(selectedRole); } } } } } wc.setToolBarManagers(managers); } public void populateBean(ReportWebAttr reportWebAttr) { this.remove(title); // 如果是空值就说明采用服务器配置了 if (reportWebAttr == null || this.getWebContent(reportWebAttr) == null) { title = new UILabel(Inter.getLocText(new String[]{"Server", "ReportServerP-Toolbar", "Choose_Role"})); populateServerSettings(); this.add(title, 0); return; } // 模板设置 T webContent = this.getWebContent(reportWebAttr); title = new UILabel(Inter.getLocText(new String[]{"the_template", "ReportServerP-Toolbar", "Choose_Role"})); this.add(title, 0); populate(webContent.getToolBarManagers()); } public ReportWebAttr updateBean() { return null; } public void populate(ToolBarManager[] toolBarManager) { if (ArrayUtils.isEmpty(toolBarManager)) { return; } if (toolBarManager.length == 0) { return; } for (int i = 0; i < toolBarManager.length; i++) { toolBarPane.populateBean(toolBarManager[i].getToolBar()); } } public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.height = ToolBarMenuDock.PANLE_HEIGNT; return dim; } public void populateBean(ToolBarManager[] toolBarManager) { if (ArrayUtils.isEmpty(toolBarManager)) { return; } for (int i = 0; i < toolBarManager.length; i++) { Location location = toolBarManager[i].getToolBarLocation(); if (location instanceof Location.Embed) { toolBarPane.populateBean(toolBarManager[i].getToolBar()); } } } private void populateServerSettings() { ConfigManagerProvider cm = ConfigManager.getProviderInstance(); ReportWebAttr webAttr = ((ReportWebAttr) cm.getGlobalAttribute(ReportWebAttr.class)); if (this.getWebContent(webAttr) != null) { populate(this.getWebContent(webAttr).getToolBarManagers()); } } protected String title4PopupWindow() { return null; } private T getWebContent(ReportWebAttr reportWebAttr) { if (choseComboBox.getSelectedIndex() == 0) { return reportWebAttr == null ? null : (T) reportWebAttr.getWebPage(); } else if (choseComboBox.getSelectedIndex() == 1) { return reportWebAttr == null ? null : (T) reportWebAttr.getWebWrite(); } else { return reportWebAttr == null ? null : (T) reportWebAttr.getWebView(); } } private void populateDefaultToolBarWidgets() { if (choseComboBox.getSelectedIndex() == 0) { ReportWebWidgetConstants.getPageToolBarInstance(); } else if (choseComboBox.getSelectedIndex() == 1) { ReportWebWidgetConstants.getWriteToolBarInstance(); } else { ReportWebWidgetConstants.getViewToolBarInstance(); } } private ToolBarManager getDefaultToolBarManager() { if (choseComboBox.getSelectedIndex() == 0) { return ToolBarManager.createDefaultToolBar(); } else if (choseComboBox.getSelectedIndex() == 1) { return ToolBarManager.createDefaultWriteToolBar(); } else { return ToolBarManager.createDefaultViewToolBar(); } } } \ No newline at end of file +package com.fr.design.mainframe; + +import com.fr.base.ConfigManager; +import com.fr.base.ConfigManagerProvider; +import com.fr.base.FRContext; +import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.toolbar.AuthorityEditToolBarComponent; +import com.fr.design.mainframe.toolbar.ToolBarMenuDock; +import com.fr.design.roleAuthority.RolesAlreadyEditedPane; +import com.fr.design.webattr.ReportWebWidgetConstants; +import com.fr.design.webattr.ToolBarButton; +import com.fr.design.webattr.ToolBarPane; +import com.fr.form.ui.Button; +import com.fr.form.ui.ToolBar; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import com.fr.general.Inter; +import com.fr.main.TemplateWorkBook; +import com.fr.report.web.Location; +import com.fr.report.web.ToolBarManager; +import com.fr.report.web.WebContent; +import com.fr.stable.ArrayUtils; +import com.fr.web.attr.ReportWebAttr; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.List; + +/** + * Author : daisy + * Date: 13-9-9 + * Time: 下午4:58 + */ +public class AuthorityToolBarPane extends BasicBeanPane implements AuthorityEditToolBarComponent { + private static final int SMALL_GAP = 13; + private static final int GAP = 25; + private static final int PRE_GAP = 9; + private static final int COMBOX_WIDTH = 144; + + private static final String[] CHOOSEITEM = new String[]{Inter.getLocText("M-Page_Preview"), Inter.getLocText(new String[]{"Face_Write", "PageSetup-Page"}), Inter.getLocText("M-Data_Analysis")}; + private UIComboBox choseComboBox; + private ToolBarPane toolBarPane; + private AuthorityEditToolBarPane authorityEditToolBarPane = null; + private int selectedIndex = -1; + private UILabel title = null; + private MouseListener mouseListener = new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (!toolBarPane.isEnabled()) { + return; + } + java.util.List buttonlists = toolBarPane.getToolBarButtons(); + int oldIndex = selectedIndex; + selectedIndex = pressButtonIndex(e, buttonlists); + //实现shift多选 + if (e.isShiftDown()) { + if (oldIndex == -1) { + removeSelection(); + ((ToolBarButton) e.getSource()).setSelected(true); + } else { + int max = oldIndex >= selectedIndex ? oldIndex : selectedIndex; + int min = oldIndex <= selectedIndex ? oldIndex : selectedIndex; + for (int i = min; i <= max; i++) { + buttonlists.get(i).setSelected(true); + } + } + } else if (!InputEventBaseOnOS.isControlDown(e)) { + //实现单选 + removeSelection(); + if (selectedIndex != -1) { + ((ToolBarButton) e.getSource()).setSelected(true); + } + } + authorityEditToolBarPane.populate(); + EastRegionContainerPane.getInstance().replaceUpPane(authorityEditToolBarPane); + } + + }; + + + private int pressButtonIndex(MouseEvent e, java.util.List buttonlists) { + if (!(e.getSource() instanceof ToolBarButton)) { + return -1; + } + ToolBarButton button = (ToolBarButton) e.getSource(); + for (int i = 0; i < buttonlists.size(); i++) { + if (ComparatorUtils.equals(button, buttonlists.get(i))) { + return i; + } + } + return -1; + } + + /** + * 去掉选择 + */ + public void removeSelection() { + for (ToolBarButton button : toolBarPane.getToolBarButtons()) { + button.setSelected(false); + } + } + + + private ItemListener itemListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.DESELECTED) { + selectedIndex = -1; + populateToolBarPane(); + authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); + authorityEditToolBarPane.setAuthorityToolBarPane(AuthorityToolBarPane.this); + EastRegionContainerPane.getInstance().replaceUpPane(authorityEditToolBarPane); + EastRegionContainerPane.getInstance().replaceDownPane(RolesAlreadyEditedPane.getInstance()); + } + } + }; + + public AuthorityToolBarPane() { + this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 3)); + this.setBorder(BorderFactory.createEmptyBorder(0, PRE_GAP, 0, 0)); + title = new UILabel(Inter.getLocText(new String[]{"ReportServerP-Toolbar", "Choose_Role"})); + title.setHorizontalAlignment(SwingConstants.CENTER); + this.add(title, 0); + choseComboBox = new UIComboBox(CHOOSEITEM) { + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.width = COMBOX_WIDTH; + return dim; + } + }; + choseComboBox.addItemListener(itemListener); + //默认选择第一个 + choseComboBox.setSelectedIndex(0); + this.add(createGapPanel(SMALL_GAP)); + this.add(choseComboBox); + toolBarPane = new ToolBarPane(); + toolBarPane.setBorder(null); + toolBarPane.removeDefaultMouseListener(); + this.add(createGapPanel(GAP)); + this.add(toolBarPane); + populateDefaultToolBarWidgets(); + populateBean(getReportWebAttr()); + toolBarPane.addAuthorityListener(mouseListener); + authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); + authorityEditToolBarPane.setAuthorityToolBarPane(this); + checkToolBarPaneEnable(); + } + + private JPanel createGapPanel(final int gap) { + return new JPanel() { + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.width = gap; + return dim; + } + }; + } + + + private void populateToolBarPane() { + toolBarPane.removeAll(); + populateDefaultToolBarWidgets(); + populateBean(getReportWebAttr()); + toolBarPane.addAuthorityListener(mouseListener); + toolBarPane.repaint(); + authorityEditToolBarPane = new AuthorityEditToolBarPane(toolBarPane.getToolBarButtons()); + checkToolBarPaneEnable(); + } + + /** + * 使用普通用户远程设计时,如果工具栏使用的是“采用服务器设置”,则工具栏按钮为灰不可用 + */ + private void checkToolBarPaneEnable() { + List toolBarButtons = toolBarPane.getToolBarButtons(); + boolean isnotEnable = ComparatorUtils.equals(title.getText(), Inter.getLocText(new String[]{"Server", "ReportServerP-Toolbar", "Choose_Role"})) + && !FRContext.getCurrentEnv().isRoot(); + for (ToolBarButton button : toolBarButtons) { + button.setEnabled(!isnotEnable); + } + toolBarPane.setEnabled(!isnotEnable); + } + + /** + * 更新权限工具栏面板 + */ + public void populateAuthority() { + toolBarPane.repaint(); + } + + + private ReportWebAttr getReportWebAttr() { + JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (!editingTemplate.isJWorkBook()) { + return null; + } + JWorkBook editingWorkBook = (JWorkBook) editingTemplate; + TemplateWorkBook wbTpl = editingWorkBook.getTarget(); + return wbTpl.getReportWebAttr(); + } + + + //将该报表的设置过权限的属性记录一下 + public void setAuthorityWebAttr(Widget widget, boolean isSelected, String selectedRole) { + JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (!editingTemplate.isJWorkBook()) { + return; + } + JWorkBook editingWorkBook = (JWorkBook) editingTemplate; + TemplateWorkBook wbTpl = editingWorkBook.getTarget(); + + ReportWebAttr rw = wbTpl.getReportWebAttr(); + ConfigManagerProvider cm = ConfigManager.getProviderInstance(); + ReportWebAttr webAttr = ((ReportWebAttr) cm.getGlobalAttribute(ReportWebAttr.class)); + + //wbTpl.clear先清空 + //再将所有的保存进去 + //看是存在服务器还存在模板里面 + if (choseComboBox.getSelectedIndex() == 0) { + //分页 + if (rw == null || rw.getWebPage() == null) { + dealWithWebContent(webAttr.getWebPage(), widget, isSelected, selectedRole); + } + } else if (choseComboBox.getSelectedIndex() == 1) { + //填报 + if (rw == null || rw.getWebPage() == null) { + dealWithWebContent(webAttr.getWebWrite(), widget, isSelected, selectedRole); + } + } else { + //view + if (rw == null || rw.getWebPage() == null) { + dealWithWebContent(webAttr.getWebView(), widget, isSelected, selectedRole); + } + } + + } + + private void dealWithWebContent(WebContent wc, Widget widget, boolean isSelected, String selectedRole) { + ToolBarManager[] managers = wc.getToolBarManagers(); + if (managers == null) { + return; + } + for (int i = 0; i < managers.length; i++) { + ToolBar tb = managers[i].getToolBar(); + for (int j = 0; j < tb.getWidgetSize(); j++) { + if (widget instanceof Button && tb.getWidget(j) instanceof Button) { + if (ComparatorUtils.equals(((Button) widget).getIconName(), + ((Button) tb.getWidget(j)).getIconName())) { + if (!isSelected) { + tb.getWidget(j).getWidgetPrivilegeControl().addInvisibleRole(selectedRole); + } else { + tb.getWidget(j).getWidgetPrivilegeControl().removeInvisibleRole(selectedRole); + } + } + } + } + } + wc.setToolBarManagers(managers); + } + + + public void populateBean(ReportWebAttr reportWebAttr) { + this.remove(title); + // 如果是空值就说明采用服务器配置了 + if (reportWebAttr == null || this.getWebContent(reportWebAttr) == null) { + title = new UILabel(Inter.getLocText(new String[]{"Server", "ReportServerP-Toolbar", "Choose_Role"})); + populateServerSettings(); + this.add(title, 0); + return; + } + // 模板设置 + T webContent = this.getWebContent(reportWebAttr); + title = new UILabel(Inter.getLocText(new String[]{"the_template", "ReportServerP-Toolbar", "Choose_Role"})); + this.add(title, 0); + populate(webContent.getToolBarManagers()); + } + + public ReportWebAttr updateBean() { + return null; + } + + public void populate(ToolBarManager[] toolBarManager) { + if (ArrayUtils.isEmpty(toolBarManager)) { + return; + } + if (toolBarManager.length == 0) { + return; + } + for (int i = 0; i < toolBarManager.length; i++) { + toolBarPane.populateBean(toolBarManager[i].getToolBar()); + } + } + + + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.height = ToolBarMenuDock.PANLE_HEIGNT; + return dim; + } + + + public void populateBean(ToolBarManager[] toolBarManager) { + if (ArrayUtils.isEmpty(toolBarManager)) { + return; + } + for (int i = 0; i < toolBarManager.length; i++) { + Location location = toolBarManager[i].getToolBarLocation(); + if (location instanceof Location.Embed) { + toolBarPane.populateBean(toolBarManager[i].getToolBar()); + } + } + } + + + private void populateServerSettings() { + ConfigManagerProvider cm = ConfigManager.getProviderInstance(); + ReportWebAttr webAttr = ((ReportWebAttr) cm.getGlobalAttribute(ReportWebAttr.class)); + if (this.getWebContent(webAttr) != null) { + populate(this.getWebContent(webAttr).getToolBarManagers()); + } + } + + protected String title4PopupWindow() { + return null; + } + + + private T getWebContent(ReportWebAttr reportWebAttr) { + if (choseComboBox.getSelectedIndex() == 0) { + return reportWebAttr == null ? null : (T) reportWebAttr.getWebPage(); + } else if (choseComboBox.getSelectedIndex() == 1) { + return reportWebAttr == null ? null : (T) reportWebAttr.getWebWrite(); + } else { + return reportWebAttr == null ? null : (T) reportWebAttr.getWebView(); + } + + } + + private void populateDefaultToolBarWidgets() { + if (choseComboBox.getSelectedIndex() == 0) { + ReportWebWidgetConstants.getPageToolBarInstance(); + } else if (choseComboBox.getSelectedIndex() == 1) { + ReportWebWidgetConstants.getWriteToolBarInstance(); + } else { + ReportWebWidgetConstants.getViewToolBarInstance(); + } + } + + private ToolBarManager getDefaultToolBarManager() { + if (choseComboBox.getSelectedIndex() == 0) { + return ToolBarManager.createDefaultToolBar(); + } else if (choseComboBox.getSelectedIndex() == 1) { + return ToolBarManager.createDefaultWriteToolBar(); + } else { + return ToolBarManager.createDefaultViewToolBar(); + } + + } + + +} \ No newline at end of file diff --git a/designer/src/com/fr/grid/GridKeyListener.java b/designer/src/com/fr/grid/GridKeyListener.java index 8e3148bf5..e60097fd6 100644 --- a/designer/src/com/fr/grid/GridKeyListener.java +++ b/designer/src/com/fr/grid/GridKeyListener.java @@ -1,5 +1,6 @@ package com.fr.grid; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.mainframe.ElementCasePane; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; @@ -71,7 +72,7 @@ public class GridKeyListener implements KeyListener { // Richie:Ctrl + A全选单元格 case KeyEvent.VK_A: boolean macOS = OperatingSystem.isMacOS() && evt.isMetaDown(); - boolean windows = OperatingSystem.isWindows() && evt.isControlDown(); + boolean windows = OperatingSystem.isWindows() && InputEventBaseOnOS.isControlDown(evt); if (macOS || windows) { reportPane.setSelection(new CellSelection(0, 0, report.getColumnCount(), report.getRowCount())); isNeedRepaint = true; @@ -168,7 +169,7 @@ public class GridKeyListener implements KeyListener { return; } KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); - if (newEvt == null || evt.isControlDown()) {// uneditable. + if (newEvt == null || InputEventBaseOnOS.isControlDown(evt)) {// uneditable. return; } char ch = evt.getKeyChar(); diff --git a/designer/src/com/fr/grid/GridMouseAdapter.java b/designer/src/com/fr/grid/GridMouseAdapter.java index 9f14df471..8a4053353 100644 --- a/designer/src/com/fr/grid/GridMouseAdapter.java +++ b/designer/src/com/fr/grid/GridMouseAdapter.java @@ -1,26 +1,14 @@ package com.fr.grid; -import java.awt.Cursor; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.JPopupMenu; -import javax.swing.SwingUtilities; - import com.fr.base.BaseUtils; import com.fr.base.DynamicUnitList; import com.fr.base.ScreenResolution; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.constants.UIConstants; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.present.CellWriteAttrPane; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; @@ -37,7 +25,12 @@ import com.fr.stable.ColumnRow; import com.fr.stable.StringUtils; import com.fr.stable.unit.FU; import com.fr.stable.unit.OLDPIX; -import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.HashMap; +import java.util.Map; /** * the MouseListener of the Grid @@ -45,800 +38,800 @@ import com.fr.design.utils.gui.GUICoreUtils; * @editor zhou 2012-3-22下午1:53:59 */ public class GridMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener { - private static final int WIDGET_WIDTH = 13; - private static final int TIME_DELAY = 100; - private static final int TOOLTIP_X = 30; - private static final int TOOLTIP_X_Y_FIX = 4; - private static final double COPY_CROSS_INNER_DISTANCE = 1.5; - private static final double COPY_CROSS_OUTER_DISTANCE = 2.5; - /** - * 拖拽时候刷新时间间隔 - */ - private static int DRAG_REFRESH_TIME = 10; - /** - * 对应的表格-Grid - */ - private Grid grid; - /** - * the Point(x,y) where the mouse pressed - */ - private int oldEvtX = 0; - private int oldEvtY = 0; - // the old location, used for Move float element. - private int oldLocationX; - private int oldLocationY; - private long lastMouseMoveTime = 0; // 最后的MouseMove时间. - // 保存各个悬浮元素到oldLocation距离 - private Map floatNamePointMap; - /** - * august:因为CellSelection里面没有记录的变量了,必须要有个变量来存按住shift键的位置之前的鼠标的位置 - * 用户可能一直按住shift键不放,所以按住shift键之前的鼠标位置是必须有的. - */ - private ColumnRow tempOldSelectedCell; - - private int ECBlockGap = 40; - - protected GridMouseAdapter(Grid grid) { - this.grid = grid; - } - - /** - * @param evt - */ - public void mousePressed(MouseEvent evt) { - if (!grid.isEnabled()) { - return; - } - oldEvtX = evt.getX(); - oldEvtY = evt.getY(); - grid.stopEditing(); - - if (!grid.hasFocus() && grid.isRequestFocusEnabled()) { - grid.requestFocus(); - } - - if (grid.getDrawingFloatElement() != null) { - doWithDrawingFloatElement(); - } else { - if (SwingUtilities.isRightMouseButton(evt)) { - doWithRightButtonPressed(); - } else { - doWithLeftButtonPressed(evt); - } - // 用户没有按住Shift键时,tempOldSelectedCell是一直变化的。如果一直按住shift,是不变的 - ElementCasePane ePane = grid.getElementCasePane(); - if (!evt.isShiftDown() && ePane.getSelection() instanceof CellSelection) { - tempOldSelectedCell = GridUtils.getAdjustEventColumnRow(ePane, oldEvtX, oldEvtY); - } - } - - } - - /** - * 将悬浮元素(只有文本和公式)添加到鼠标点击的位置 - */ - private void doWithDrawingFloatElement() { - ElementCasePane reportPane = grid.getElementCasePane(); - TemplateElementCase report = reportPane.getEditingElementCase(); - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - - int horizentalScrollValue = grid.getHorizontalValue(); - int verticalScrollValue = grid.getVerticalValue(); - int resolution = ScreenResolution.getScreenResolution(); - FU evtX_fu = FU.valueOfPix(this.oldEvtX, resolution); - FU evtY_fu = FU.valueOfPix(this.oldEvtY, resolution); - - FU leftDistance = FU.getInstance(evtX_fu.toFU() + columnWidthList.getRangeValue(0, horizentalScrollValue).toFU()); - FU topDistance = FU.getInstance(evtY_fu.toFU() + rowHeightList.getRangeValue(0, verticalScrollValue).toFU()); - - grid.getDrawingFloatElement().setLeftDistance(leftDistance); - grid.getDrawingFloatElement().setTopDistance(topDistance); - - report.addFloatElement(grid.getDrawingFloatElement()); - reportPane.setSelection(new FloatSelection(grid.getDrawingFloatElement().getName())); - } - - /** - * 处理右击事件,弹出右键菜单. - */ - private void doWithRightButtonPressed() { - ElementCasePane reportPane = grid.getElementCasePane(); - Object[] tmpFloatElementCursor = GridUtils.getAboveFloatElementCursor(reportPane, this.oldEvtX, this.oldEvtY); - if (!ArrayUtils.isEmpty(tmpFloatElementCursor)) { - FloatElement selectedFloatElement = (FloatElement) tmpFloatElementCursor[0]; - reportPane.setSelection(new FloatSelection(selectedFloatElement.getName())); - } else { - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, this.oldEvtX, this.oldEvtY); - if (!reportPane.getSelection().containsColumnRow(selectedCellPoint)) { - GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - } - } - reportPane.repaint(); - JPopupMenu cellPopupMenu = reportPane.createPopupMenu(); - if (cellPopupMenu != null) { - GUICoreUtils.showPopupMenu(cellPopupMenu, this.grid, this.oldEvtX - 1, this.oldEvtY - 1); - } - } - - /** - * 处理左击事件 - */ - private void doWithLeftButtonPressed(MouseEvent evt) { - if(BaseUtils.isAuthorityEditing()){ - grid.setEditable(false); - } - - ElementCasePane reportPane = grid.getElementCasePane(); - TemplateElementCase report = reportPane.getEditingElementCase(); - boolean isShiftDown = evt.isShiftDown(); - boolean isControlDown = evt.isControlDown(); - int clickCount = evt.getClickCount(); - // peter:需要判断是否在可移动CellSelection的区域 - grid.setDragType(isMoveCellSelection(this.oldEvtX, this.oldEvtY)); - if (clickCount >= 2) { - grid.setDragType(GridUtils.DRAG_NONE); - } - if (grid.getDragType() != GridUtils.DRAG_NONE) {// Drag的标志. - Selection selection = reportPane.getSelection(); - if (selection instanceof CellSelection) { - // peter:设置DragRecatagle的标志. - if (grid.getDragRectangle() == null) { - grid.setDragRectangle(new Rectangle()); - } - CellSelection cs = ((CellSelection) selection).clone(); - grid.getDragRectangle().setBounds(cs.toRectangle()); - return; - } - } - // peter:选择GridSelection,支持Shift - doOneClickSelection(this.oldEvtX, this.oldEvtY, isShiftDown, isControlDown); - // 得到点击所在的column and row - ColumnRow columnRow = GridUtils.getEventColumnRow(reportPane, this.oldEvtX, this.oldEvtY); - TemplateCellElement cellElement = report.getTemplateCellElement(columnRow.getColumn(), columnRow.getRow()); - if (clickCount >= 2 && !BaseUtils.isAuthorityEditing()) { - grid.startEditing(); - } - if (clickCount == 1 && cellElement != null && cellElement.getWidget() != null && !BaseUtils.isAuthorityEditing()) { - showWidetWindow(cellElement, report); - } - reportPane.repaint(); - } - - /** - * 显示控件编辑窗口 - * - * @param cellElement - * @param report - */ - - private void showWidetWindow(TemplateCellElement cellElement, TemplateElementCase report) { - int resolution = ScreenResolution.getScreenResolution(); - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - double fixed_pos_x = this.oldEvtX - columnWidthList.getRangeValue(grid.getHorizontalValue(), cellElement.getColumn()).toPixD(resolution); - double fixed_pos_y = this.oldEvtY - rowHeightList.getRangeValue(grid.getVerticalValue(), cellElement.getRow()).toPixD(resolution); - double cell_width = columnWidthList.getRangeValue(cellElement.getColumn(), cellElement.getColumn() + cellElement.getColumnSpan()).toPixD(resolution); - double cell_height = rowHeightList.getRangeValue(cellElement.getRow(), cellElement.getRow() + cellElement.getRowSpan()).toPixD(resolution); - if (fitSizeToShow(cell_width, cell_height, fixed_pos_x, fixed_pos_y)) { - CellWriteAttrPane.showWidgetWindow(grid.getElementCasePane()); - } - } - - private boolean fitSizeToShow(double cell_width, double cell_height, double fixed_pos_x, double fixed_pos_y) { - return cell_width - fixed_pos_x > 0 && cell_height - fixed_pos_y > 0 - && cell_width - fixed_pos_x < WIDGET_WIDTH && cell_height - fixed_pos_y < WIDGET_WIDTH; - } - - /** - * @param evt - */ - public void mouseReleased(MouseEvent evt) { - if (!grid.isEnabled() || !grid.isEditable()) { - return; - } - boolean isDataChanged = false; - ElementCasePane reportPane = grid.getElementCasePane(); - Selection selection = reportPane.getSelection(); - if (grid.getDrawingFloatElement() != null) { - if (grid.getDrawingFloatElement().getWidth().equal_zero() && grid.getDrawingFloatElement().getHeight().equal_zero()) { - grid.getDrawingFloatElement().setWidth(new OLDPIX(100)); - grid.getDrawingFloatElement().setHeight(new OLDPIX(100)); - } - grid.setDrawingFloatElement(null); - } else if (selection instanceof FloatSelection) { - grid.setCursor(Cursor.getDefaultCursor()); - } - if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION) { - if (selection instanceof CellSelection) { - grid.getElementCasePane().cut(); - // mouse release的时候要判断下是否在reportPane范围内 - if (outOfBounds(evt, reportPane)) { - GridUtils.doSelectCell(reportPane, grid.getDragRectangle().x, grid.getDragRectangle().y); - } else { - mousePressed(evt); - } - grid.getElementCasePane().paste(); - isDataChanged = true; - } - } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER) { - if (selection instanceof CellSelection) { - CellSelection cs = (CellSelection) selection; - // august:智能拖拽扩展单元格值 - IntelliElements.iterating(reportPane, cs.toRectangle(), grid.getDragRectangle()); - if (grid.getDragRectangle() != null) { - reportPane.setSelection(new CellSelection(grid.getDragRectangle().x, grid.getDragRectangle().y, grid.getDragRectangle().width, grid.getDragRectangle().height)); - } - isDataChanged = true; - } - } else if (grid.getDragType() == GridUtils.DRAG_FLOAT) { - isDataChanged = true; - } - grid.setDragType(GridUtils.DRAG_NONE); - grid.setDragRectangle(null); - if (isDataChanged) { + private static final int WIDGET_WIDTH = 13; + private static final int TIME_DELAY = 100; + private static final int TOOLTIP_X = 30; + private static final int TOOLTIP_X_Y_FIX = 4; + private static final double COPY_CROSS_INNER_DISTANCE = 1.5; + private static final double COPY_CROSS_OUTER_DISTANCE = 2.5; + /** + * 拖拽时候刷新时间间隔 + */ + private static int DRAG_REFRESH_TIME = 10; + /** + * 对应的表格-Grid + */ + private Grid grid; + /** + * the Point(x,y) where the mouse pressed + */ + private int oldEvtX = 0; + private int oldEvtY = 0; + // the old location, used for Move float element. + private int oldLocationX; + private int oldLocationY; + private long lastMouseMoveTime = 0; // 最后的MouseMove时间. + // 保存各个悬浮元素到oldLocation距离 + private Map floatNamePointMap; + /** + * august:因为CellSelection里面没有记录的变量了,必须要有个变量来存按住shift键的位置之前的鼠标的位置 + * 用户可能一直按住shift键不放,所以按住shift键之前的鼠标位置是必须有的. + */ + private ColumnRow tempOldSelectedCell; + + private int ECBlockGap = 40; + + protected GridMouseAdapter(Grid grid) { + this.grid = grid; + } + + /** + * @param evt + */ + public void mousePressed(MouseEvent evt) { + if (!grid.isEnabled()) { + return; + } + oldEvtX = evt.getX(); + oldEvtY = evt.getY(); + grid.stopEditing(); + + if (!grid.hasFocus() && grid.isRequestFocusEnabled()) { + grid.requestFocus(); + } + + if (grid.getDrawingFloatElement() != null) { + doWithDrawingFloatElement(); + } else { + if (SwingUtilities.isRightMouseButton(evt)) { + doWithRightButtonPressed(); + } else { + doWithLeftButtonPressed(evt); + } + // 用户没有按住Shift键时,tempOldSelectedCell是一直变化的。如果一直按住shift,是不变的 + ElementCasePane ePane = grid.getElementCasePane(); + if (!evt.isShiftDown() && ePane.getSelection() instanceof CellSelection) { + tempOldSelectedCell = GridUtils.getAdjustEventColumnRow(ePane, oldEvtX, oldEvtY); + } + } + + } + + /** + * 将悬浮元素(只有文本和公式)添加到鼠标点击的位置 + */ + private void doWithDrawingFloatElement() { + ElementCasePane reportPane = grid.getElementCasePane(); + TemplateElementCase report = reportPane.getEditingElementCase(); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + + int horizentalScrollValue = grid.getHorizontalValue(); + int verticalScrollValue = grid.getVerticalValue(); + int resolution = ScreenResolution.getScreenResolution(); + FU evtX_fu = FU.valueOfPix(this.oldEvtX, resolution); + FU evtY_fu = FU.valueOfPix(this.oldEvtY, resolution); + + FU leftDistance = FU.getInstance(evtX_fu.toFU() + columnWidthList.getRangeValue(0, horizentalScrollValue).toFU()); + FU topDistance = FU.getInstance(evtY_fu.toFU() + rowHeightList.getRangeValue(0, verticalScrollValue).toFU()); + + grid.getDrawingFloatElement().setLeftDistance(leftDistance); + grid.getDrawingFloatElement().setTopDistance(topDistance); + + report.addFloatElement(grid.getDrawingFloatElement()); + reportPane.setSelection(new FloatSelection(grid.getDrawingFloatElement().getName())); + } + + /** + * 处理右击事件,弹出右键菜单. + */ + private void doWithRightButtonPressed() { + ElementCasePane reportPane = grid.getElementCasePane(); + Object[] tmpFloatElementCursor = GridUtils.getAboveFloatElementCursor(reportPane, this.oldEvtX, this.oldEvtY); + if (!ArrayUtils.isEmpty(tmpFloatElementCursor)) { + FloatElement selectedFloatElement = (FloatElement) tmpFloatElementCursor[0]; + reportPane.setSelection(new FloatSelection(selectedFloatElement.getName())); + } else { + ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, this.oldEvtX, this.oldEvtY); + if (!reportPane.getSelection().containsColumnRow(selectedCellPoint)) { + GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + } + } + reportPane.repaint(); + JPopupMenu cellPopupMenu = reportPane.createPopupMenu(); + if (cellPopupMenu != null) { + GUICoreUtils.showPopupMenu(cellPopupMenu, this.grid, this.oldEvtX - 1, this.oldEvtY - 1); + } + } + + /** + * 处理左击事件 + */ + private void doWithLeftButtonPressed(MouseEvent evt) { + if (BaseUtils.isAuthorityEditing()) { + grid.setEditable(false); + } + + ElementCasePane reportPane = grid.getElementCasePane(); + TemplateElementCase report = reportPane.getEditingElementCase(); + boolean isShiftDown = evt.isShiftDown(); + boolean isControlDown = InputEventBaseOnOS.isControlDown(evt); + int clickCount = evt.getClickCount(); + // peter:需要判断是否在可移动CellSelection的区域 + grid.setDragType(isMoveCellSelection(this.oldEvtX, this.oldEvtY)); + if (clickCount >= 2) { + grid.setDragType(GridUtils.DRAG_NONE); + } + if (grid.getDragType() != GridUtils.DRAG_NONE) {// Drag的标志. + Selection selection = reportPane.getSelection(); + if (selection instanceof CellSelection) { + // peter:设置DragRecatagle的标志. + if (grid.getDragRectangle() == null) { + grid.setDragRectangle(new Rectangle()); + } + CellSelection cs = ((CellSelection) selection).clone(); + grid.getDragRectangle().setBounds(cs.toRectangle()); + return; + } + } + // peter:选择GridSelection,支持Shift + doOneClickSelection(this.oldEvtX, this.oldEvtY, isShiftDown, isControlDown); + // 得到点击所在的column and row + ColumnRow columnRow = GridUtils.getEventColumnRow(reportPane, this.oldEvtX, this.oldEvtY); + TemplateCellElement cellElement = report.getTemplateCellElement(columnRow.getColumn(), columnRow.getRow()); + if (clickCount >= 2 && !BaseUtils.isAuthorityEditing()) { + grid.startEditing(); + } + if (clickCount == 1 && cellElement != null && cellElement.getWidget() != null && !BaseUtils.isAuthorityEditing()) { + showWidetWindow(cellElement, report); + } + reportPane.repaint(); + } + + /** + * 显示控件编辑窗口 + * + * @param cellElement + * @param report + */ + + private void showWidetWindow(TemplateCellElement cellElement, TemplateElementCase report) { + int resolution = ScreenResolution.getScreenResolution(); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + double fixed_pos_x = this.oldEvtX - columnWidthList.getRangeValue(grid.getHorizontalValue(), cellElement.getColumn()).toPixD(resolution); + double fixed_pos_y = this.oldEvtY - rowHeightList.getRangeValue(grid.getVerticalValue(), cellElement.getRow()).toPixD(resolution); + double cell_width = columnWidthList.getRangeValue(cellElement.getColumn(), cellElement.getColumn() + cellElement.getColumnSpan()).toPixD(resolution); + double cell_height = rowHeightList.getRangeValue(cellElement.getRow(), cellElement.getRow() + cellElement.getRowSpan()).toPixD(resolution); + if (fitSizeToShow(cell_width, cell_height, fixed_pos_x, fixed_pos_y)) { + CellWriteAttrPane.showWidgetWindow(grid.getElementCasePane()); + } + } + + private boolean fitSizeToShow(double cell_width, double cell_height, double fixed_pos_x, double fixed_pos_y) { + return cell_width - fixed_pos_x > 0 && cell_height - fixed_pos_y > 0 + && cell_width - fixed_pos_x < WIDGET_WIDTH && cell_height - fixed_pos_y < WIDGET_WIDTH; + } + + /** + * @param evt + */ + public void mouseReleased(MouseEvent evt) { + if (!grid.isEnabled() || !grid.isEditable()) { + return; + } + boolean isDataChanged = false; + ElementCasePane reportPane = grid.getElementCasePane(); + Selection selection = reportPane.getSelection(); + if (grid.getDrawingFloatElement() != null) { + if (grid.getDrawingFloatElement().getWidth().equal_zero() && grid.getDrawingFloatElement().getHeight().equal_zero()) { + grid.getDrawingFloatElement().setWidth(new OLDPIX(100)); + grid.getDrawingFloatElement().setHeight(new OLDPIX(100)); + } + grid.setDrawingFloatElement(null); + } else if (selection instanceof FloatSelection) { + grid.setCursor(Cursor.getDefaultCursor()); + } + if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION) { + if (selection instanceof CellSelection) { + grid.getElementCasePane().cut(); + // mouse release的时候要判断下是否在reportPane范围内 + if (outOfBounds(evt, reportPane)) { + GridUtils.doSelectCell(reportPane, grid.getDragRectangle().x, grid.getDragRectangle().y); + } else { + mousePressed(evt); + } + grid.getElementCasePane().paste(); + isDataChanged = true; + } + } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER) { + if (selection instanceof CellSelection) { + CellSelection cs = (CellSelection) selection; + // august:智能拖拽扩展单元格值 + IntelliElements.iterating(reportPane, cs.toRectangle(), grid.getDragRectangle()); + if (grid.getDragRectangle() != null) { + reportPane.setSelection(new CellSelection(grid.getDragRectangle().x, grid.getDragRectangle().y, grid.getDragRectangle().width, grid.getDragRectangle().height)); + } + isDataChanged = true; + } + } else if (grid.getDragType() == GridUtils.DRAG_FLOAT) { + isDataChanged = true; + } + grid.setDragType(GridUtils.DRAG_NONE); + grid.setDragRectangle(null); + if (isDataChanged) { reportPane.setSupportDefaultParentCalculate(true); - reportPane.fireTargetModified(); + reportPane.fireTargetModified(); reportPane.setSupportDefaultParentCalculate(false); - } - doWithFormatBrush(reportPane); - reportPane.repaint(); - } - - private void doWithFormatBrush(ElementCasePane reportPane) { - if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) { - return; - } - - if (reportPane.getCellNeedTOFormat() != null) { - reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane); - reportPane.fireTargetModified(); - - } - if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_ONCE) { - reportPane.cancelFormatBrush(); - } - if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_MORE) { - reportPane.getFormatBrush().setSelected(true); - } - } - - private boolean outOfBounds(MouseEvent evt, ElementCasePane reportPane) { - return evt.getY() > reportPane.getHeight() || evt.getY() < 0 || evt.getX() > reportPane.getWidth() || evt.getX() < 0; - } - - /** - * @param evt - */ - public void mouseMoved(final MouseEvent evt) { - ElementCasePane reportPane = grid.getElementCasePane(); - boolean isGridForSelection = !grid.isEnabled() || !grid.isEditable(); - if (isGridForSelection || grid.isEditing()) { - if (grid.IsNotShowingTableSelectPane()) { - grid.setCursor(UIConstants.CELL_DEFAULT_CURSOR); - return; - } - if (DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL) { - grid.setCursor(UIConstants.FORMAT_BRUSH_CURSOR); - } else { - grid.setCursor(GUICoreUtils.createCustomCursor(BaseUtils.readImage("com/fr/design/images/buttonicon/select.png"), - new Point(0, 0), "select", grid)); - } - - return; - } - // peter:停留一段时间. - long systemCurrentTime = System.currentTimeMillis(); - if (systemCurrentTime - lastMouseMoveTime <= TIME_DELAY) { - return; - } - lastMouseMoveTime = systemCurrentTime;// 记录最后一次的时间. - mouseMoveOnGrid(evt.getX(), evt.getY()); - } - - /** - * @param evt - */ - public void mouseDragged(MouseEvent evt) { - if (!grid.isEnabled()) { - return; - } - - boolean isControlDown = evt.isControlDown(); - - long systemCurrentTime = System.currentTimeMillis(); - if (systemCurrentTime - lastMouseMoveTime <= DRAG_REFRESH_TIME) {// alex:Drag - return; - } else { - lastMouseMoveTime = systemCurrentTime; - } - - // right mouse cannot Drag.. - if (SwingUtilities.isRightMouseButton(evt)) { - return; - } - - doWithMouseDragged(evt.getX(), evt.getY(), isControlDown); - } - - private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown) { - ElementCasePane reportPane = grid.getElementCasePane(); - - if (reportPane.mustInVisibleRange()) { - Grid grid = reportPane.getGrid(); - if (evtX > grid.getWidth() - 2 || evtY > grid.getHeight() - 2) { - return; - } - } - Selection selection = reportPane.getSelection(); - - if (selection instanceof FloatSelection && !BaseUtils.isAuthorityEditing()) { - doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection); - grid.setDragType(GridUtils.DRAG_FLOAT); - } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER && !BaseUtils.isAuthorityEditing()) { - doWithCellElementDragged(evtX, evtY, (CellSelection) selection); - } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION && !BaseUtils.isAuthorityEditing()) { - // peter:获得调整过的Selected Column Row. - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); - if (selectedCellPoint.getColumn() != grid.getDragRectangle().x || selectedCellPoint.getRow() != grid.getDragRectangle().y) { - grid.getDragRectangle().x = selectedCellPoint.getColumn(); - grid.getDragRectangle().y = selectedCellPoint.getRow(); - } - } else {// august: 拖拽选中多个单元格 - doShiftSelectCell(evtX, evtY); - } - grid.getElementCasePane().repaint(); - } - - /** - * 拖拽悬浮元素 - * - * @param evtX - * @param evtY - * @param fs - */ - - private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs) { - ElementCase report = grid.getElementCasePane().getEditingElementCase(); - int resolution = ScreenResolution.getScreenResolution(); - String floatName = fs.getSelectedFloatName(); - FloatElement floatElement = report.getFloatElement(floatName); - int cursorType = grid.getCursor().getType(); - - if (cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.NE_RESIZE_CURSOR || cursorType == Cursor.SE_RESIZE_CURSOR || cursorType == Cursor.SW_RESIZE_CURSOR) { - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); - FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); - FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); - floatElement.setLeftDistance(leftDistance); - floatElement.setTopDistance(topDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); - } else if (cursorType == Cursor.S_RESIZE_CURSOR || cursorType == Cursor.N_RESIZE_CURSOR) { - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); - FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); - floatElement.setTopDistance(topDistance); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); - } else if (cursorType == Cursor.W_RESIZE_CURSOR || cursorType == Cursor.E_RESIZE_CURSOR) { - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); - FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); - floatElement.setLeftDistance(leftDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); - } else if (cursorType == Cursor.MOVE_CURSOR) { - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - int horizentalValue = grid.getHorizontalValue(); - int verticalValue = grid.getVerticalValue(); - String floatElementName = fs.getSelectedFloatName(); - FloatElement tempFolatElement = report.getFloatElement(floatElementName); - Point tempFolatElementPoint = floatNamePointMap.get(floatElementName); - int floatX1ForTempFloatElement = tempFolatElementPoint.x + Math.max(oldLocationX + (evtX - oldEvtX), 0); - int floatY1ForTempFloatElement = tempFolatElementPoint.y + Math.max(oldLocationY + (evtY - oldEvtY), 0); - FU floatX1ForTempFloatElement_fu = FU.valueOfPix(floatX1ForTempFloatElement, resolution); - FU leftDistance = floatX1ForTempFloatElement_fu.add(columnWidthList.getRangeValue(0, horizentalValue)); - FU floatY1ForTempFloatElement_fu = FU.valueOfPix(floatY1ForTempFloatElement, resolution); - FU topDistance = floatY1ForTempFloatElement_fu.add(rowHeightList.getRangeValue(0, verticalValue)); - tempFolatElement.setLeftDistance(leftDistance); - tempFolatElement.setTopDistance(topDistance); - } - - } - - /** - * 拖拽单元格 - * - * @param evtX - * @param evtY - * @param cs - */ - - private void doWithCellElementDragged(int evtX, int evtY, CellSelection cs) { - ElementCasePane reportPane = grid.getElementCasePane(); - java.awt.Rectangle cellRectangle = cs.toRectangle(); - - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); - if (cellRectangle.contains(selectedCellPoint.getColumn(), selectedCellPoint.getRow())) { - grid.getDragRectangle().setBounds(cellRectangle); - } else { - int xDistance = evtX - this.oldEvtX; - int yDistance = evtY - this.oldEvtY; - if (Math.abs(yDistance) > Math.abs(xDistance)) { - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = cellRectangle.width; - if (yDistance >= 0) { - // 聚合报表要求拖拽的时候要在本块的内部进行 不能无限往下拖 - if (reportPane instanceof ECBlockPane && evtY > reportPane.getBounds().height - ECBlockGap) { - return; - } - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = selectedCellPoint.getRow() - cellRectangle.y + 1; - } else { - if (selectedCellPoint.getRow() >= cellRectangle.y && selectedCellPoint.getRow() < cellRectangle.y + cellRectangle.height) { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.height; - } else { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.y - selectedCellPoint.getRow() + cellRectangle.height; - } - } - } else { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.height; - if (xDistance >= 0) { - if (reportPane instanceof ECBlockPane && evtX > reportPane.getBounds().width - ECBlockGap) { - return; - } - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = selectedCellPoint.getColumn() - cellRectangle.x + 1; - } else { - if (selectedCellPoint.getColumn() >= cellRectangle.x && selectedCellPoint.getColumn() < cellRectangle.x + cellRectangle.width) { - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = cellRectangle.width; - } else { - grid.getDragRectangle().x = selectedCellPoint.getColumn(); - grid.getDragRectangle().width = cellRectangle.x - selectedCellPoint.getColumn() + cellRectangle.width; - } - } - } - } - reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn() + 1, selectedCellPoint.getRow() + 1); - } - - private void doShiftSelectCell(double evtX, double evtY) { - ElementCasePane reportPane = grid.getElementCasePane(); - Selection s = reportPane.getSelection(); - if (s instanceof FloatSelection) { - return; - } - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); - int selectedCellPointX = selectedCellPoint.getColumn(); - int selectedCellPointY = selectedCellPoint.getRow(); - CellSelection gridSelection = ((CellSelection) s).clone(); - //反向选择单元格 - int tempOldSelectedCellX = tempOldSelectedCell.getColumn(); - int tempOldSelectedCellY = tempOldSelectedCell.getRow(); + } + doWithFormatBrush(reportPane); + reportPane.repaint(); + } + + private void doWithFormatBrush(ElementCasePane reportPane) { + if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) { + return; + } + + if (reportPane.getCellNeedTOFormat() != null) { + reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane); + reportPane.fireTargetModified(); + + } + if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_ONCE) { + reportPane.cancelFormatBrush(); + } + if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_MORE) { + reportPane.getFormatBrush().setSelected(true); + } + } + + private boolean outOfBounds(MouseEvent evt, ElementCasePane reportPane) { + return evt.getY() > reportPane.getHeight() || evt.getY() < 0 || evt.getX() > reportPane.getWidth() || evt.getX() < 0; + } + + /** + * @param evt + */ + public void mouseMoved(final MouseEvent evt) { + ElementCasePane reportPane = grid.getElementCasePane(); + boolean isGridForSelection = !grid.isEnabled() || !grid.isEditable(); + if (isGridForSelection || grid.isEditing()) { + if (grid.IsNotShowingTableSelectPane()) { + grid.setCursor(UIConstants.CELL_DEFAULT_CURSOR); + return; + } + if (DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL) { + grid.setCursor(UIConstants.FORMAT_BRUSH_CURSOR); + } else { + grid.setCursor(GUICoreUtils.createCustomCursor(BaseUtils.readImage("com/fr/design/images/buttonicon/select.png"), + new Point(0, 0), "select", grid)); + } + + return; + } + // peter:停留一段时间. + long systemCurrentTime = System.currentTimeMillis(); + if (systemCurrentTime - lastMouseMoveTime <= TIME_DELAY) { + return; + } + lastMouseMoveTime = systemCurrentTime;// 记录最后一次的时间. + mouseMoveOnGrid(evt.getX(), evt.getY()); + } + + /** + * @param evt + */ + public void mouseDragged(MouseEvent evt) { + if (!grid.isEnabled()) { + return; + } + + boolean isControlDown = InputEventBaseOnOS.isControlDown(evt); + + long systemCurrentTime = System.currentTimeMillis(); + if (systemCurrentTime - lastMouseMoveTime <= DRAG_REFRESH_TIME) {// alex:Drag + return; + } else { + lastMouseMoveTime = systemCurrentTime; + } + + // right mouse cannot Drag.. + if (SwingUtilities.isRightMouseButton(evt)) { + return; + } + + doWithMouseDragged(evt.getX(), evt.getY(), isControlDown); + } + + private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown) { + ElementCasePane reportPane = grid.getElementCasePane(); + + if (reportPane.mustInVisibleRange()) { + Grid grid = reportPane.getGrid(); + if (evtX > grid.getWidth() - 2 || evtY > grid.getHeight() - 2) { + return; + } + } + Selection selection = reportPane.getSelection(); + + if (selection instanceof FloatSelection && !BaseUtils.isAuthorityEditing()) { + doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection); + grid.setDragType(GridUtils.DRAG_FLOAT); + } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER && !BaseUtils.isAuthorityEditing()) { + doWithCellElementDragged(evtX, evtY, (CellSelection) selection); + } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION && !BaseUtils.isAuthorityEditing()) { + // peter:获得调整过的Selected Column Row. + ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); + if (selectedCellPoint.getColumn() != grid.getDragRectangle().x || selectedCellPoint.getRow() != grid.getDragRectangle().y) { + grid.getDragRectangle().x = selectedCellPoint.getColumn(); + grid.getDragRectangle().y = selectedCellPoint.getRow(); + } + } else {// august: 拖拽选中多个单元格 + doShiftSelectCell(evtX, evtY); + } + grid.getElementCasePane().repaint(); + } + + /** + * 拖拽悬浮元素 + * + * @param evtX + * @param evtY + * @param fs + */ + + private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs) { + ElementCase report = grid.getElementCasePane().getEditingElementCase(); + int resolution = ScreenResolution.getScreenResolution(); + String floatName = fs.getSelectedFloatName(); + FloatElement floatElement = report.getFloatElement(floatName); + int cursorType = grid.getCursor().getType(); + + if (cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.NE_RESIZE_CURSOR || cursorType == Cursor.SE_RESIZE_CURSOR || cursorType == Cursor.SW_RESIZE_CURSOR) { + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); + FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); + FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); + floatElement.setLeftDistance(leftDistance); + floatElement.setTopDistance(topDistance); + floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); + floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + } else if (cursorType == Cursor.S_RESIZE_CURSOR || cursorType == Cursor.N_RESIZE_CURSOR) { + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); + floatElement.setTopDistance(topDistance); + floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + } else if (cursorType == Cursor.W_RESIZE_CURSOR || cursorType == Cursor.E_RESIZE_CURSOR) { + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); + FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); + floatElement.setLeftDistance(leftDistance); + floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); + } else if (cursorType == Cursor.MOVE_CURSOR) { + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + int horizentalValue = grid.getHorizontalValue(); + int verticalValue = grid.getVerticalValue(); + String floatElementName = fs.getSelectedFloatName(); + FloatElement tempFolatElement = report.getFloatElement(floatElementName); + Point tempFolatElementPoint = floatNamePointMap.get(floatElementName); + int floatX1ForTempFloatElement = tempFolatElementPoint.x + Math.max(oldLocationX + (evtX - oldEvtX), 0); + int floatY1ForTempFloatElement = tempFolatElementPoint.y + Math.max(oldLocationY + (evtY - oldEvtY), 0); + FU floatX1ForTempFloatElement_fu = FU.valueOfPix(floatX1ForTempFloatElement, resolution); + FU leftDistance = floatX1ForTempFloatElement_fu.add(columnWidthList.getRangeValue(0, horizentalValue)); + FU floatY1ForTempFloatElement_fu = FU.valueOfPix(floatY1ForTempFloatElement, resolution); + FU topDistance = floatY1ForTempFloatElement_fu.add(rowHeightList.getRangeValue(0, verticalValue)); + tempFolatElement.setLeftDistance(leftDistance); + tempFolatElement.setTopDistance(topDistance); + } + + } + + /** + * 拖拽单元格 + * + * @param evtX + * @param evtY + * @param cs + */ + + private void doWithCellElementDragged(int evtX, int evtY, CellSelection cs) { + ElementCasePane reportPane = grid.getElementCasePane(); + java.awt.Rectangle cellRectangle = cs.toRectangle(); + + ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); + if (cellRectangle.contains(selectedCellPoint.getColumn(), selectedCellPoint.getRow())) { + grid.getDragRectangle().setBounds(cellRectangle); + } else { + int xDistance = evtX - this.oldEvtX; + int yDistance = evtY - this.oldEvtY; + if (Math.abs(yDistance) > Math.abs(xDistance)) { + grid.getDragRectangle().x = cellRectangle.x; + grid.getDragRectangle().width = cellRectangle.width; + if (yDistance >= 0) { + // 聚合报表要求拖拽的时候要在本块的内部进行 不能无限往下拖 + if (reportPane instanceof ECBlockPane && evtY > reportPane.getBounds().height - ECBlockGap) { + return; + } + grid.getDragRectangle().y = cellRectangle.y; + grid.getDragRectangle().height = selectedCellPoint.getRow() - cellRectangle.y + 1; + } else { + if (selectedCellPoint.getRow() >= cellRectangle.y && selectedCellPoint.getRow() < cellRectangle.y + cellRectangle.height) { + grid.getDragRectangle().y = cellRectangle.y; + grid.getDragRectangle().height = cellRectangle.height; + } else { + grid.getDragRectangle().y = cellRectangle.y; + grid.getDragRectangle().height = cellRectangle.y - selectedCellPoint.getRow() + cellRectangle.height; + } + } + } else { + grid.getDragRectangle().y = cellRectangle.y; + grid.getDragRectangle().height = cellRectangle.height; + if (xDistance >= 0) { + if (reportPane instanceof ECBlockPane && evtX > reportPane.getBounds().width - ECBlockGap) { + return; + } + grid.getDragRectangle().x = cellRectangle.x; + grid.getDragRectangle().width = selectedCellPoint.getColumn() - cellRectangle.x + 1; + } else { + if (selectedCellPoint.getColumn() >= cellRectangle.x && selectedCellPoint.getColumn() < cellRectangle.x + cellRectangle.width) { + grid.getDragRectangle().x = cellRectangle.x; + grid.getDragRectangle().width = cellRectangle.width; + } else { + grid.getDragRectangle().x = selectedCellPoint.getColumn(); + grid.getDragRectangle().width = cellRectangle.x - selectedCellPoint.getColumn() + cellRectangle.width; + } + } + } + } + reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn() + 1, selectedCellPoint.getRow() + 1); + } + + private void doShiftSelectCell(double evtX, double evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + Selection s = reportPane.getSelection(); + if (s instanceof FloatSelection) { + return; + } + ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); + int selectedCellPointX = selectedCellPoint.getColumn(); + int selectedCellPointY = selectedCellPoint.getRow(); + CellSelection gridSelection = ((CellSelection) s).clone(); + //反向选择单元格 + int tempOldSelectedCellX = tempOldSelectedCell.getColumn(); + int tempOldSelectedCellY = tempOldSelectedCell.getRow(); // int tempOldSelectedCellX = gridSelection.getEditRectangle().x; // int tempOldSelectedCellY = gridSelection.getEditRectangle().y; - int column = selectedCellPointX >= tempOldSelectedCellX ? tempOldSelectedCellX : selectedCellPointX; - int row = selectedCellPointY >= tempOldSelectedCellY ? tempOldSelectedCellY : selectedCellPointY; - int columnSpan = Math.abs(selectedCellPointX - tempOldSelectedCellX) + 1; - int rowSpan = Math.abs(selectedCellPointY - tempOldSelectedCellY) + 1; - Rectangle oldrectangle = new Rectangle(column, row, columnSpan, rowSpan); - // ajust them to got the correct selected bounds. - Rectangle newrectangle = grid.caculateIntersectsUnion(reportPane.getEditingElementCase(), oldrectangle); - gridSelection.setBounds(newrectangle.x, newrectangle.y, newrectangle.width, newrectangle.height); - gridSelection.clearCellRectangles(gridSelection.getCellRectangleCount() - 1); - gridSelection.addCellRectangle(newrectangle); - reportPane.setSelection(gridSelection); - if (!reportPane.mustInVisibleRange()) { - reportPane.ensureColumnRowVisible(selectedCellPointX, selectedCellPointY); - } - } - - - private void doControlSelectCell(double evtX, double evtY) { - ElementCasePane reportPane = grid.getElementCasePane(); - ElementCase report = reportPane.getEditingElementCase(); - //上一次选中的单元格 - Selection s = reportPane.getSelection(); - if (s instanceof FloatSelection) { - return; - } - - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); - //拷贝,而不是直接强制使用以监听单元格选择变化 - CellSelection gridSelection = ((CellSelection) s).clone(); - gridSelection.setSelectedType(((CellSelection) s).getSelectedType()); - CellElement cellElement = report.getCellElement(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - if (cellElement == null) { - gridSelection.setBounds(selectedCellPoint.getColumn(), selectedCellPoint.getRow(), 1, 1); - int point = gridSelection.containsCell(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - if (point == -1) { - gridSelection.addCellRectangle(new Rectangle(selectedCellPoint.getColumn(), selectedCellPoint.getRow(), 1, 1)); - } else { - gridSelection.clearCellRectangles(point); - } - - } else { - gridSelection.setBounds(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan()); - gridSelection.addCellRectangle(new Rectangle(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); - - - } - - reportPane.setSelection(gridSelection); - - if (!reportPane.mustInVisibleRange()) { - reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - } - - - } - - - /** - * 鼠标在Grid上面移动. - */ - private void mouseMoveOnGrid(int evtX, int evtY) { - grid.setToolTipText(null); - if (grid.getDrawingFloatElement() != null) { - grid.setCursor(UIConstants.DRAW_CURSOR); // august:是否是将要画悬浮元素,就是那个笔的形状 - } else { - Object[] floatElementCursor = GridUtils.getAboveFloatElementCursor(grid.getElementCasePane(), evtX, evtY); - if (!ArrayUtils.isEmpty(floatElementCursor)) {// 鼠标在悬浮元素上移动 - grid.setCursor((Cursor) floatElementCursor[1]); - } else {// 鼠标在单元格上移动 - doMouseMoveOnCells(evtX, evtY); - } - } - } - - /** - * 鼠标在单元格上移动 - * - * @param evtX - * @param evtY - */ - private void doMouseMoveOnCells(int evtX, int evtY) { - ElementCasePane reportPane = grid.getElementCasePane(); - TemplateElementCase report = reportPane.getEditingElementCase(); - //如果是格式刷状态 - if (DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL) { - grid.setCursor(UIConstants.FORMAT_BRUSH_CURSOR); - } else { - grid.setCursor(UIConstants.CELL_DEFAULT_CURSOR); - } - ColumnRow selectedCellColumnRow = GridUtils.getEventColumnRow(reportPane, evtX, evtY); - TemplateCellElement curCellElement = report.getTemplateCellElement(selectedCellColumnRow.getColumn(), selectedCellColumnRow.getRow()); - - if (curCellElement != null) { - setCursorAndToolTips(curCellElement, report); - } - - int dragType = isMoveCellSelection(evtX, evtY); - if (dragType == GridUtils.DRAG_CELLSELECTION) {// 判断是否移动选中的区域. - grid.setCursor(new Cursor(Cursor.MOVE_CURSOR)); - } // peter:判断是否复制移动的角落. - else if (dragType == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER) { - grid.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); - } - - } - - /** - * 只根据CellGUIAttr里面的tooltips显示了,原先的显示条件属性、形态、控件等无意义 - * - * @param curCellElement - * @param report - */ - private void setCursorAndToolTips(TemplateCellElement curCellElement, TemplateElementCase report) { - int resolution = ScreenResolution.getScreenResolution(); - // 计算相对Grid的显示位置. - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - - CellGUIAttr cellGUIAttr = curCellElement.getCellGUIAttr(); - if (cellGUIAttr == null) { - cellGUIAttr = CellGUIAttr.DEFAULT_CELLGUIATTR; - } - grid.setToolTipText(cellGUIAttr.getTooltipText()); - double tooltipX = columnWidthList.getRangeValue(grid.getHorizontalValue(), curCellElement.getColumn()).toPixD(resolution) + TOOLTIP_X_Y_FIX; - double tooltipY = rowHeightList.getRangeValue(grid.getVerticalValue(), curCellElement.getRow() + curCellElement.getRowSpan()).toPixD(resolution) + TOOLTIP_X_Y_FIX; - - // peter:显示tooltip - if (StringUtils.isNotBlank(grid.getToolTipText())) { - grid.setTooltipLocation(tooltipX + TOOLTIP_X, tooltipY); - } - } - - /** - * 是否移动CellSelection - */ - private int isMoveCellSelection(double evtX, double evtY) { - ElementCasePane reportPane = grid.getElementCasePane(); - - // p:判断是否在选中区域的边框,可以移动CellSelelction选中区域 - Selection selection = reportPane.getSelection(); - if (!(selection instanceof CellSelection)) { - return GridUtils.DRAG_NONE; - } - - if ((selection instanceof CellSelection) - && ((CellSelection) selection).getCellRectangleCount() != 1) {// p:没有选择Cell. - return GridUtils.DRAG_NONE; - } - - CellSelection cs = (CellSelection) selection; - - ElementCase report = reportPane.getEditingElementCase(); - - // peter:计算相对Grid的显示位置. - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - - int resolution = ScreenResolution.getScreenResolution(); - - double leftColDistance = columnWidthList.getRangeValue(grid.getHorizontalValue(), cs.getColumn()).toPixD(resolution); - double rightColDistance = columnWidthList.getRangeValue(grid.getHorizontalValue(), cs.getColumn() + cs.getColumnSpan()).toPixD(resolution); - double topRowDistance = rowHeightList.getRangeValue(grid.getVerticalValue(), cs.getRow()).toPixD(resolution); - double bottomRowDistance = rowHeightList.getRangeValue(grid.getVerticalValue(), cs.getRow() + cs.getRowSpan()).toPixD(resolution); - - // 首先判断是否在可以复制的右下角落. - if (fitCellSelectionBottomRight(evtX, evtY, rightColDistance, bottomRowDistance)) { - return GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER; - } - - // 这个dist值调小一点,尽量让用户不使用drag and drop 来编辑报表支持 - double dist = 1.0; - if (fitCellSelection(evtX, leftColDistance, rightColDistance, dist)) { - if (evtY >= (topRowDistance - dist) && evtY <= (bottomRowDistance + dist)) { - return GridUtils.DRAG_CELLSELECTION; - } - } else if (fitCellSelection(evtY, topRowDistance, bottomRowDistance, dist)) { - if (evtX >= (leftColDistance - dist) && evtX <= (rightColDistance + dist)) { - return GridUtils.DRAG_CELLSELECTION; - } - } - - return GridUtils.DRAG_NONE; - } - - private boolean fitCellSelection(double evt, double d1, double d2, double dist) { - return (evt >= (d1 - dist) && evt <= (d1 + dist)) - || (evt >= (d2 - dist) && evt <= (d2 + dist)); - } - - private boolean fitCellSelectionBottomRight(double evtX, double evtY, double rightColDistance, double bottomRowDistance) { - return evtX > rightColDistance - COPY_CROSS_INNER_DISTANCE && evtX < rightColDistance + COPY_CROSS_OUTER_DISTANCE - && evtY > bottomRowDistance - COPY_CROSS_INNER_DISTANCE && bottomRowDistance < bottomRowDistance + COPY_CROSS_OUTER_DISTANCE; - } - - /** - * Do one click selection - */ - private void doOneClickSelection(int evtX, int evtY, boolean isShiftDown, boolean isControlDown) { - ElementCasePane reportPane = grid.getElementCasePane(); - // check float elements. - Object[] tmpFloatElementCursor = GridUtils.getAboveFloatElementCursor(reportPane, evtX, evtY); - if (!ArrayUtils.isEmpty(tmpFloatElementCursor)) {// p:选中了悬浮元素. - doSelectFloatElement(tmpFloatElementCursor, evtX, evtY); - } else if (isShiftDown) { - doShiftSelectCell(evtX, evtY); - } else if (isControlDown) { - doControlSelectCell(evtX, evtY); - } else { - ColumnRow selectedCellPoint = GridUtils.getEventColumnRow(reportPane, evtX, evtY); - int type = reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - if (type == ElementCasePane.NO_OVER) { - GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow()); - } else if (type == ElementCasePane.VERTICAL_OVER) { - //聚合报表块选在下边界的时候,有时会向下移,阻止向下移 - GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow() - 1); - } else if (type == ElementCasePane.HORIZONTAL_OVER) { - //聚合报表块选在右边界的时候,有时会向右移,阻止向右移 - GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn() - 1, selectedCellPoint.getRow()); - } else { - GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn() - 1, selectedCellPoint.getRow() - 1); - } - - return; - } - - } - - /** - * 选中悬浮元素 - * - * @param tmpFloatElementCursor - * @param evtX - * @param evtY - */ - - private void doSelectFloatElement(Object[] tmpFloatElementCursor, int evtX, int evtY) { - ElementCasePane reportPane = grid.getElementCasePane(); - ElementCase report = reportPane.getEditingElementCase(); - FloatElement floatElement = (FloatElement) tmpFloatElementCursor[0]; - String floatName = floatElement.getName(); - reportPane.setSelection(new FloatSelection(floatName)); - double[] floatArray = GridUtils.caculateFloatElementLocations(floatElement, ReportHelper.getColumnWidthList(report), ReportHelper.getRowHeightList(report), reportPane - .getGrid().getVerticalValue(), reportPane.getGrid().getHorizontalValue()); - - int cursorType = ((Cursor) tmpFloatElementCursor[1]).getType(); - if (cursorType == Cursor.MOVE_CURSOR) { - this.oldEvtX = evtX; - this.oldEvtY = evtY; - FloatElement el = report.getFloatElement(floatName); - int resolution = ScreenResolution.getScreenResolution(); - int verticalValue = grid.getVerticalValue(); - int horizentalValue = grid.getHorizontalValue(); - DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - this.oldLocationX = FU.getInstance(el.getLeftDistance().toFU() - columnWidthList.getRangeValue(0, horizentalValue).toFU()).toPixI(resolution); - this.oldLocationY = FU.getInstance(el.getTopDistance().toFU() - rowHeightList.getRangeValue(0, verticalValue).toFU()).toPixI(resolution); - if (floatNamePointMap == null) { - floatNamePointMap = new HashMap(); - } - floatNamePointMap.clear(); - FloatElement tempFolatElement = report.getFloatElement(floatName); - int floatX1ForTempFloatElement = FU.getInstance(tempFolatElement.getLeftDistance().toFU() - columnWidthList.getRangeValue(0, horizentalValue).toFU()) - .toPixI(resolution) - oldLocationX; - int floatY1ForTempFloatElement = FU.getInstance(tempFolatElement.getTopDistance().toFU() - rowHeightList.getRangeValue(0, verticalValue).toFU()).toPixI(resolution) - - oldLocationY; - floatNamePointMap.put(floatName, new Point(floatX1ForTempFloatElement, floatY1ForTempFloatElement)); - } else if (cursorType == Cursor.NW_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[2], floatArray[3]); - } else if (cursorType == Cursor.NE_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[0], floatArray[3]); - } else if (cursorType == Cursor.SE_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[0], floatArray[1]); - } else if (cursorType == Cursor.SW_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[2], floatArray[1]); - } else if (cursorType == Cursor.N_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[0], floatArray[3]); - } else if (cursorType == Cursor.S_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[0], floatArray[1]); - } else if (cursorType == Cursor.W_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[2], floatArray[1]); - } else if (cursorType == Cursor.E_RESIZE_CURSOR) { - setOld_X_AndOld_Y(floatArray[0], floatArray[1]); - } - } - - private void setOld_X_AndOld_Y(double x, double y) { - this.oldEvtX = (int) x; - this.oldEvtY = (int) y; - } - - /** - * @param e - */ - public void mouseWheelMoved(MouseWheelEvent e) { - ElementCasePane reportPane = grid.getElementCasePane(); - if (reportPane.isHorizontalScrollBarVisible()) { - reportPane.getVerticalScrollBar().setValue(reportPane.getVerticalScrollBar().getValue() + e.getWheelRotation() * 3); - } - } - - /** - * @param e - */ - public void mouseClicked(MouseEvent e) { - } - - /** - * @param e - */ - public void mouseEntered(MouseEvent e) { - } - - /** - * @param e - */ - public void mouseExited(MouseEvent e) { - } + int column = selectedCellPointX >= tempOldSelectedCellX ? tempOldSelectedCellX : selectedCellPointX; + int row = selectedCellPointY >= tempOldSelectedCellY ? tempOldSelectedCellY : selectedCellPointY; + int columnSpan = Math.abs(selectedCellPointX - tempOldSelectedCellX) + 1; + int rowSpan = Math.abs(selectedCellPointY - tempOldSelectedCellY) + 1; + Rectangle oldrectangle = new Rectangle(column, row, columnSpan, rowSpan); + // ajust them to got the correct selected bounds. + Rectangle newrectangle = grid.caculateIntersectsUnion(reportPane.getEditingElementCase(), oldrectangle); + gridSelection.setBounds(newrectangle.x, newrectangle.y, newrectangle.width, newrectangle.height); + gridSelection.clearCellRectangles(gridSelection.getCellRectangleCount() - 1); + gridSelection.addCellRectangle(newrectangle); + reportPane.setSelection(gridSelection); + if (!reportPane.mustInVisibleRange()) { + reportPane.ensureColumnRowVisible(selectedCellPointX, selectedCellPointY); + } + } + + + private void doControlSelectCell(double evtX, double evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + ElementCase report = reportPane.getEditingElementCase(); + //上一次选中的单元格 + Selection s = reportPane.getSelection(); + if (s instanceof FloatSelection) { + return; + } + + ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(reportPane, evtX, evtY); + //拷贝,而不是直接强制使用以监听单元格选择变化 + CellSelection gridSelection = ((CellSelection) s).clone(); + gridSelection.setSelectedType(((CellSelection) s).getSelectedType()); + CellElement cellElement = report.getCellElement(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + if (cellElement == null) { + gridSelection.setBounds(selectedCellPoint.getColumn(), selectedCellPoint.getRow(), 1, 1); + int point = gridSelection.containsCell(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + if (point == -1) { + gridSelection.addCellRectangle(new Rectangle(selectedCellPoint.getColumn(), selectedCellPoint.getRow(), 1, 1)); + } else { + gridSelection.clearCellRectangles(point); + } + + } else { + gridSelection.setBounds(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan()); + gridSelection.addCellRectangle(new Rectangle(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); + + + } + + reportPane.setSelection(gridSelection); + + if (!reportPane.mustInVisibleRange()) { + reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + } + + + } + + + /** + * 鼠标在Grid上面移动. + */ + private void mouseMoveOnGrid(int evtX, int evtY) { + grid.setToolTipText(null); + if (grid.getDrawingFloatElement() != null) { + grid.setCursor(UIConstants.DRAW_CURSOR); // august:是否是将要画悬浮元素,就是那个笔的形状 + } else { + Object[] floatElementCursor = GridUtils.getAboveFloatElementCursor(grid.getElementCasePane(), evtX, evtY); + if (!ArrayUtils.isEmpty(floatElementCursor)) {// 鼠标在悬浮元素上移动 + grid.setCursor((Cursor) floatElementCursor[1]); + } else {// 鼠标在单元格上移动 + doMouseMoveOnCells(evtX, evtY); + } + } + } + + /** + * 鼠标在单元格上移动 + * + * @param evtX + * @param evtY + */ + private void doMouseMoveOnCells(int evtX, int evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + TemplateElementCase report = reportPane.getEditingElementCase(); + //如果是格式刷状态 + if (DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL) { + grid.setCursor(UIConstants.FORMAT_BRUSH_CURSOR); + } else { + grid.setCursor(UIConstants.CELL_DEFAULT_CURSOR); + } + ColumnRow selectedCellColumnRow = GridUtils.getEventColumnRow(reportPane, evtX, evtY); + TemplateCellElement curCellElement = report.getTemplateCellElement(selectedCellColumnRow.getColumn(), selectedCellColumnRow.getRow()); + + if (curCellElement != null) { + setCursorAndToolTips(curCellElement, report); + } + + int dragType = isMoveCellSelection(evtX, evtY); + if (dragType == GridUtils.DRAG_CELLSELECTION) {// 判断是否移动选中的区域. + grid.setCursor(new Cursor(Cursor.MOVE_CURSOR)); + } // peter:判断是否复制移动的角落. + else if (dragType == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER) { + grid.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); + } + + } + + /** + * 只根据CellGUIAttr里面的tooltips显示了,原先的显示条件属性、形态、控件等无意义 + * + * @param curCellElement + * @param report + */ + private void setCursorAndToolTips(TemplateCellElement curCellElement, TemplateElementCase report) { + int resolution = ScreenResolution.getScreenResolution(); + // 计算相对Grid的显示位置. + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + + CellGUIAttr cellGUIAttr = curCellElement.getCellGUIAttr(); + if (cellGUIAttr == null) { + cellGUIAttr = CellGUIAttr.DEFAULT_CELLGUIATTR; + } + grid.setToolTipText(cellGUIAttr.getTooltipText()); + double tooltipX = columnWidthList.getRangeValue(grid.getHorizontalValue(), curCellElement.getColumn()).toPixD(resolution) + TOOLTIP_X_Y_FIX; + double tooltipY = rowHeightList.getRangeValue(grid.getVerticalValue(), curCellElement.getRow() + curCellElement.getRowSpan()).toPixD(resolution) + TOOLTIP_X_Y_FIX; + + // peter:显示tooltip + if (StringUtils.isNotBlank(grid.getToolTipText())) { + grid.setTooltipLocation(tooltipX + TOOLTIP_X, tooltipY); + } + } + + /** + * 是否移动CellSelection + */ + private int isMoveCellSelection(double evtX, double evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + + // p:判断是否在选中区域的边框,可以移动CellSelelction选中区域 + Selection selection = reportPane.getSelection(); + if (!(selection instanceof CellSelection)) { + return GridUtils.DRAG_NONE; + } + + if ((selection instanceof CellSelection) + && ((CellSelection) selection).getCellRectangleCount() != 1) {// p:没有选择Cell. + return GridUtils.DRAG_NONE; + } + + CellSelection cs = (CellSelection) selection; + + ElementCase report = reportPane.getEditingElementCase(); + + // peter:计算相对Grid的显示位置. + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + + int resolution = ScreenResolution.getScreenResolution(); + + double leftColDistance = columnWidthList.getRangeValue(grid.getHorizontalValue(), cs.getColumn()).toPixD(resolution); + double rightColDistance = columnWidthList.getRangeValue(grid.getHorizontalValue(), cs.getColumn() + cs.getColumnSpan()).toPixD(resolution); + double topRowDistance = rowHeightList.getRangeValue(grid.getVerticalValue(), cs.getRow()).toPixD(resolution); + double bottomRowDistance = rowHeightList.getRangeValue(grid.getVerticalValue(), cs.getRow() + cs.getRowSpan()).toPixD(resolution); + + // 首先判断是否在可以复制的右下角落. + if (fitCellSelectionBottomRight(evtX, evtY, rightColDistance, bottomRowDistance)) { + return GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER; + } + + // 这个dist值调小一点,尽量让用户不使用drag and drop 来编辑报表支持 + double dist = 1.0; + if (fitCellSelection(evtX, leftColDistance, rightColDistance, dist)) { + if (evtY >= (topRowDistance - dist) && evtY <= (bottomRowDistance + dist)) { + return GridUtils.DRAG_CELLSELECTION; + } + } else if (fitCellSelection(evtY, topRowDistance, bottomRowDistance, dist)) { + if (evtX >= (leftColDistance - dist) && evtX <= (rightColDistance + dist)) { + return GridUtils.DRAG_CELLSELECTION; + } + } + + return GridUtils.DRAG_NONE; + } + + private boolean fitCellSelection(double evt, double d1, double d2, double dist) { + return (evt >= (d1 - dist) && evt <= (d1 + dist)) + || (evt >= (d2 - dist) && evt <= (d2 + dist)); + } + + private boolean fitCellSelectionBottomRight(double evtX, double evtY, double rightColDistance, double bottomRowDistance) { + return evtX > rightColDistance - COPY_CROSS_INNER_DISTANCE && evtX < rightColDistance + COPY_CROSS_OUTER_DISTANCE + && evtY > bottomRowDistance - COPY_CROSS_INNER_DISTANCE && bottomRowDistance < bottomRowDistance + COPY_CROSS_OUTER_DISTANCE; + } + + /** + * Do one click selection + */ + private void doOneClickSelection(int evtX, int evtY, boolean isShiftDown, boolean isControlDown) { + ElementCasePane reportPane = grid.getElementCasePane(); + // check float elements. + Object[] tmpFloatElementCursor = GridUtils.getAboveFloatElementCursor(reportPane, evtX, evtY); + if (!ArrayUtils.isEmpty(tmpFloatElementCursor)) {// p:选中了悬浮元素. + doSelectFloatElement(tmpFloatElementCursor, evtX, evtY); + } else if (isShiftDown) { + doShiftSelectCell(evtX, evtY); + } else if (isControlDown) { + doControlSelectCell(evtX, evtY); + } else { + ColumnRow selectedCellPoint = GridUtils.getEventColumnRow(reportPane, evtX, evtY); + int type = reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + if (type == ElementCasePane.NO_OVER) { + GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow()); + } else if (type == ElementCasePane.VERTICAL_OVER) { + //聚合报表块选在下边界的时候,有时会向下移,阻止向下移 + GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn(), selectedCellPoint.getRow() - 1); + } else if (type == ElementCasePane.HORIZONTAL_OVER) { + //聚合报表块选在右边界的时候,有时会向右移,阻止向右移 + GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn() - 1, selectedCellPoint.getRow()); + } else { + GridUtils.doSelectCell(reportPane, selectedCellPoint.getColumn() - 1, selectedCellPoint.getRow() - 1); + } + + return; + } + + } + + /** + * 选中悬浮元素 + * + * @param tmpFloatElementCursor + * @param evtX + * @param evtY + */ + + private void doSelectFloatElement(Object[] tmpFloatElementCursor, int evtX, int evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + ElementCase report = reportPane.getEditingElementCase(); + FloatElement floatElement = (FloatElement) tmpFloatElementCursor[0]; + String floatName = floatElement.getName(); + reportPane.setSelection(new FloatSelection(floatName)); + double[] floatArray = GridUtils.caculateFloatElementLocations(floatElement, ReportHelper.getColumnWidthList(report), ReportHelper.getRowHeightList(report), reportPane + .getGrid().getVerticalValue(), reportPane.getGrid().getHorizontalValue()); + + int cursorType = ((Cursor) tmpFloatElementCursor[1]).getType(); + if (cursorType == Cursor.MOVE_CURSOR) { + this.oldEvtX = evtX; + this.oldEvtY = evtY; + FloatElement el = report.getFloatElement(floatName); + int resolution = ScreenResolution.getScreenResolution(); + int verticalValue = grid.getVerticalValue(); + int horizentalValue = grid.getHorizontalValue(); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + this.oldLocationX = FU.getInstance(el.getLeftDistance().toFU() - columnWidthList.getRangeValue(0, horizentalValue).toFU()).toPixI(resolution); + this.oldLocationY = FU.getInstance(el.getTopDistance().toFU() - rowHeightList.getRangeValue(0, verticalValue).toFU()).toPixI(resolution); + if (floatNamePointMap == null) { + floatNamePointMap = new HashMap(); + } + floatNamePointMap.clear(); + FloatElement tempFolatElement = report.getFloatElement(floatName); + int floatX1ForTempFloatElement = FU.getInstance(tempFolatElement.getLeftDistance().toFU() - columnWidthList.getRangeValue(0, horizentalValue).toFU()) + .toPixI(resolution) - oldLocationX; + int floatY1ForTempFloatElement = FU.getInstance(tempFolatElement.getTopDistance().toFU() - rowHeightList.getRangeValue(0, verticalValue).toFU()).toPixI(resolution) + - oldLocationY; + floatNamePointMap.put(floatName, new Point(floatX1ForTempFloatElement, floatY1ForTempFloatElement)); + } else if (cursorType == Cursor.NW_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[2], floatArray[3]); + } else if (cursorType == Cursor.NE_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[0], floatArray[3]); + } else if (cursorType == Cursor.SE_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[0], floatArray[1]); + } else if (cursorType == Cursor.SW_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[2], floatArray[1]); + } else if (cursorType == Cursor.N_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[0], floatArray[3]); + } else if (cursorType == Cursor.S_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[0], floatArray[1]); + } else if (cursorType == Cursor.W_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[2], floatArray[1]); + } else if (cursorType == Cursor.E_RESIZE_CURSOR) { + setOld_X_AndOld_Y(floatArray[0], floatArray[1]); + } + } + + private void setOld_X_AndOld_Y(double x, double y) { + this.oldEvtX = (int) x; + this.oldEvtY = (int) y; + } + + /** + * @param e + */ + public void mouseWheelMoved(MouseWheelEvent e) { + ElementCasePane reportPane = grid.getElementCasePane(); + if (reportPane.isHorizontalScrollBarVisible()) { + reportPane.getVerticalScrollBar().setValue(reportPane.getVerticalScrollBar().getValue() + e.getWheelRotation() * 3); + } + } + + /** + * @param e + */ + public void mouseClicked(MouseEvent e) { + } + + /** + * @param e + */ + public void mouseEntered(MouseEvent e) { + } + + /** + * @param e + */ + public void mouseExited(MouseEvent e) { + } } \ No newline at end of file diff --git a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java new file mode 100644 index 000000000..cee80d334 --- /dev/null +++ b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java @@ -0,0 +1,21 @@ +package com.fr.common.inputevent; + +import com.fr.stable.OperatingSystem; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * Created by hzzz on 2017/5/26. + */ +public class InputEventBaseOnOS { + private static final boolean isMacOS = OperatingSystem.isMacOS(); + + public static boolean isControlDown(MouseEvent e) { + return isMacOS ? e.isMetaDown() : e.isControlDown(); + } + + public static boolean isControlDown(KeyEvent e) { + return isMacOS ? e.isMetaDown() : e.isControlDown(); + } +} diff --git a/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java b/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java index 47ddbdac3..512b5713b 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java +++ b/designer_base/src/com/fr/design/gui/icombobox/ExtendedComboBox.java @@ -1,5 +1,7 @@ package com.fr.design.gui.icombobox; +import com.fr.common.inputevent.InputEventBaseOnOS; + import java.awt.Component; import java.awt.Dimension; import java.awt.Point; @@ -76,7 +78,7 @@ public class ExtendedComboBox extends UIComboBox { protected JList createList() { return new JList(comboBox.getModel()) { public void processMouseEvent(MouseEvent e) { - if (e.isControlDown()) { + if (InputEventBaseOnOS.isControlDown(e)) { // Fix for 4234053. Filter out the Control // Key from the list. // ie., don't allow CTRL key deselection. diff --git a/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java b/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java index ae1089fa9..f5cd1eabb 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java +++ b/designer_base/src/com/fr/design/gui/icombobox/UIComboBoxUI.java @@ -16,6 +16,7 @@ import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.constants.UIConstants; import sun.swing.DefaultLookup; @@ -209,7 +210,7 @@ public class UIComboBoxUI extends BasicComboBoxUI implements MouseListener { @Override public void processMouseEvent(MouseEvent e) { - if (e.isControlDown()) { + if (InputEventBaseOnOS.isControlDown(e)) { e = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers() ^ DEFAULT_MODIFIER, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); } diff --git a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java index 0ef0f829a..fa21465cb 100644 --- a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java +++ b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java @@ -22,6 +22,7 @@ import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.stable.StringUtils; @@ -176,7 +177,7 @@ public class CheckBoxList extends JComponent { @Override protected void processMouseEvent(MouseEvent e) { if (e.getX() < 20) { - if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { + if (InputEventBaseOnOS.isControlDown(e) || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { int[] indices = getSelectedIndices(); if (indices.length == 0) { super.processMouseEvent(e); diff --git a/designer_base/src/com/fr/design/gui/itable/TableSorter.java b/designer_base/src/com/fr/design/gui/itable/TableSorter.java index 0ea84af03..93b2c5154 100644 --- a/designer_base/src/com/fr/design/gui/itable/TableSorter.java +++ b/designer_base/src/com/fr/design/gui/itable/TableSorter.java @@ -15,6 +15,8 @@ import java.util.List; import java.util.Map; import javax.swing.Icon; + +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.gui.ilable.UILabel; import javax.swing.JTable; import javax.swing.event.TableModelEvent; @@ -396,7 +398,7 @@ public class TableSorter extends AbstractTableModel { int column = columnModel.getColumn(viewColumn).getModelIndex(); if (column != -1) { int status = getSortingStatus(column); - if (!e.isControlDown()) { + if (!InputEventBaseOnOS.isControlDown(e)) { cancelSorting(); } // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or diff --git a/designer_base/src/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java b/designer_base/src/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java index b463ca7eb..0224a4349 100644 --- a/designer_base/src/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java +++ b/designer_base/src/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java @@ -1,5 +1,6 @@ package com.fr.design.gui.itree.refreshabletree; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.general.NameObject; import com.fr.design.gui.itree.refreshabletree.loader.ChildrenLoaderFactory; import com.fr.general.ComparatorUtils; @@ -147,7 +148,7 @@ public abstract class UserObjectRefreshJTree> extends } } // marks:鼠标在上次选中的paths上,则将上次的paths设为的树的路径,否则将鼠标所在的节点设为选中的节点 - if (!(e.isShiftDown() || e.isControlDown())) { + if (!(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) { if (isFind) { setSelectionPaths(oldPaths); } else { diff --git a/designer_base/src/com/fr/design/roleAuthority/UIRoleTreeUI.java b/designer_base/src/com/fr/design/roleAuthority/UIRoleTreeUI.java index e6b049b33..9b996410a 100644 --- a/designer_base/src/com/fr/design/roleAuthority/UIRoleTreeUI.java +++ b/designer_base/src/com/fr/design/roleAuthority/UIRoleTreeUI.java @@ -1,5 +1,6 @@ package com.fr.design.roleAuthority; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.gui.itree.UITreeUI; import javax.swing.tree.TreePath; @@ -15,7 +16,7 @@ import java.awt.event.MouseEvent; public class UIRoleTreeUI extends UITreeUI { protected void selectPathForEvent(TreePath path, MouseEvent event) { /* Adjust from the anchor point. */ - if (event.isControlDown() && tree.isPathSelected(path)) { + if (InputEventBaseOnOS.isControlDown(event) && tree.isPathSelected(path)) { tree.removeSelectionPath(path); } else if (event.isShiftDown()) { tree.setAnchorSelectionPath(null); diff --git a/designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java b/designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java index 13eaa18ac..2fde27019 100644 --- a/designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java +++ b/designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java @@ -1,5 +1,6 @@ package com.fr.design.designer.beans.models; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.events.DesignerEvent; @@ -61,7 +62,7 @@ public class SelectionModel { * @param e 鼠标事件 */ public void selectACreatorAtMouseEvent(MouseEvent e) { - if (!e.isControlDown() && !e.isShiftDown()) { + if (!InputEventBaseOnOS.isControlDown(e) && !e.isShiftDown()) { // 如果Ctrl或者Shift键盘没有按下,则清除已经选择的组件 selection.reset(); } @@ -372,7 +373,7 @@ public class SelectionModel { public Direction getDirectionAt(MouseEvent e) { Direction dir; - if (e.isControlDown() || e.isShiftDown()) { + if (InputEventBaseOnOS.isControlDown(e) || e.isShiftDown()) { XCreator creator = designer.getComponentAt(e.getX(), e.getY(), selection.getSelectedCreators()); if (creator != designer.getRootComponent() && selection.addedable(creator)) { return Location.add; From 082987e03ce28d22fcb691cb93e23c035d62f53e Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 10:12:54 +0800 Subject: [PATCH 17/20] PMD --- designer/src/com/fr/grid/GridKeyListener.java | 16 +++------- .../common/inputevent/InputEventBaseOnOS.java | 6 ++-- .../com/fr/design/gui/ilist/CheckBoxList.java | 29 +++++++++---------- .../com/fr/design/gui/itable/TableSorter.java | 16 ++++------ 4 files changed, 27 insertions(+), 40 deletions(-) diff --git a/designer/src/com/fr/grid/GridKeyListener.java b/designer/src/com/fr/grid/GridKeyListener.java index e60097fd6..b3d57ab67 100644 --- a/designer/src/com/fr/grid/GridKeyListener.java +++ b/designer/src/com/fr/grid/GridKeyListener.java @@ -6,7 +6,6 @@ import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; import com.fr.report.elementcase.ElementCase; -import com.fr.stable.OperatingSystem; import java.awt.*; import java.awt.event.KeyEvent; @@ -18,6 +17,7 @@ import java.awt.event.KeyListener; */ public class GridKeyListener implements KeyListener { private static final int DIFF = 48; // 103 - 55 = 48, 小键盘和大键盘数字的差值 48 + private static final int DELAY = 32; private Grid grid; // Keypressed last time private long keyPressedLastTime = 0; @@ -31,8 +31,7 @@ public class GridKeyListener implements KeyListener { if (!grid.isEnabled() || evt.isConsumed()) {// 如果用户在自己的KyeListener里面consume了.就不执行下面的代码了. return; } - KeyEvent newEvt = KeyEventWork.processKeyEvent(evt); - if (newEvt == null) { + if (KeyEventWork.processKeyEvent(evt) == null) { return; } long systemCurrentTime = System.currentTimeMillis(); @@ -47,17 +46,14 @@ public class GridKeyListener implements KeyListener { keyPressedLastTime = systemCurrentTime; } dealWithFloatSelection(reportPane, code); - } else { - if (systemCurrentTime - keyPressedLastTime <= 32) { + if (systemCurrentTime - keyPressedLastTime <= DELAY) { return; } else { keyPressedLastTime = systemCurrentTime; } dealWithCellSelection(evt, code); - } - switch (code) { case KeyEvent.VK_PAGE_UP: {// page up reportPane.getVerticalScrollBar().setValue(Math.max(0, grid.getVerticalValue() - grid.getVerticalExtent())); @@ -71,16 +67,12 @@ public class GridKeyListener implements KeyListener { } // Richie:Ctrl + A全选单元格 case KeyEvent.VK_A: - boolean macOS = OperatingSystem.isMacOS() && evt.isMetaDown(); - boolean windows = OperatingSystem.isWindows() && InputEventBaseOnOS.isControlDown(evt); - if (macOS || windows) { + if (InputEventBaseOnOS.isControlDown(evt)) { reportPane.setSelection(new CellSelection(0, 0, report.getColumnCount(), report.getRowCount())); - isNeedRepaint = true; } isNeedRepaint = true; break; } - if (isNeedRepaint) { reportPane.repaint(); } diff --git a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java index cee80d334..29b6b9ce3 100644 --- a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java +++ b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java @@ -9,13 +9,13 @@ import java.awt.event.MouseEvent; * Created by hzzz on 2017/5/26. */ public class InputEventBaseOnOS { - private static final boolean isMacOS = OperatingSystem.isMacOS(); + private static final boolean IS_MACOS = OperatingSystem.isMacOS(); public static boolean isControlDown(MouseEvent e) { - return isMacOS ? e.isMetaDown() : e.isControlDown(); + return IS_MACOS ? e.isMetaDown() : e.isControlDown(); } public static boolean isControlDown(KeyEvent e) { - return isMacOS ? e.isMetaDown() : e.isControlDown(); + return IS_MACOS ? e.isMetaDown() : e.isControlDown(); } } diff --git a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java index fa21465cb..28c9e85e8 100644 --- a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java +++ b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java @@ -22,7 +22,6 @@ import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; -import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.stable.StringUtils; @@ -32,7 +31,7 @@ import com.fr.stable.StringUtils; public class CheckBoxList extends JComponent { /** * 选择状态----全选和全不选 - * + * * @editor zhou * @since 2012-4-1下午2:39:10 */ @@ -54,7 +53,7 @@ public class CheckBoxList extends JComponent { /** * Class constructor. - * + * * @param items * Items with which to populate the list. * @param default_state @@ -177,7 +176,7 @@ public class CheckBoxList extends JComponent { @Override protected void processMouseEvent(MouseEvent e) { if (e.getX() < 20) { - if (InputEventBaseOnOS.isControlDown(e) || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { + if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { int[] indices = getSelectedIndices(); if (indices.length == 0) { super.processMouseEvent(e); @@ -190,17 +189,17 @@ public class CheckBoxList extends JComponent { } int id = e.getID(); switch (id) { - case MouseEvent.MOUSE_PRESSED: - break; - case MouseEvent.MOUSE_RELEASED: - break; - case MouseEvent.MOUSE_CLICKED: - doCheck(); - break; - case MouseEvent.MOUSE_EXITED: - break; - case MouseEvent.MOUSE_ENTERED: - break; + case MouseEvent.MOUSE_PRESSED: + break; + case MouseEvent.MOUSE_RELEASED: + break; + case MouseEvent.MOUSE_CLICKED: + doCheck(); + break; + case MouseEvent.MOUSE_EXITED: + break; + case MouseEvent.MOUSE_ENTERED: + break; } } diff --git a/designer_base/src/com/fr/design/gui/itable/TableSorter.java b/designer_base/src/com/fr/design/gui/itable/TableSorter.java index 93b2c5154..4b2f2995c 100644 --- a/designer_base/src/com/fr/design/gui/itable/TableSorter.java +++ b/designer_base/src/com/fr/design/gui/itable/TableSorter.java @@ -81,7 +81,7 @@ import javax.swing.table.TableModel; public class TableSorter extends AbstractTableModel { protected TableModel tableModel; - + private static final int ADD = 4; public static final int DESCENDING = -1; public static final int NOT_SORTED = 0; public static final int ASCENDING = 1; @@ -343,17 +343,14 @@ public class TableSorter extends AbstractTableModel { fireTableChanged(e); return; } - - // If the table structure has changed, cancel the sorting; the - // sorting columns may have been either moved or deleted from - // the model. + // If the table structure has changed, cancel the sorting; the + // sorting columns may have been either moved or deleted from the model. if (e.getFirstRow() == TableModelEvent.HEADER_ROW) { cancelSorting(); fireTableChanged(e); return; } - - // We can map a cell event through to the view without widening + // We can map a cell event through to the view without widening // when the following conditions apply: // // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, @@ -382,8 +379,7 @@ public class TableSorter extends AbstractTableModel { column, e.getType())); return; } - - // Something has happened to the data that may have invalidated the row order. + // Something has happened to the data that may have invalidated the row order. clearSortingState(); fireTableDataChanged(); return; @@ -404,7 +400,7 @@ public class TableSorter extends AbstractTableModel { // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. status = status + (e.isShiftDown() ? -1 : 1); - status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1} + status = (status + ADD) % 3 - 1; // signed mod, returning {-1, 0, 1} setSortingStatus(column, status); } } From 53bd97161031350f1a1cd2e941b08ea752ffb0d2 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 10:15:10 +0800 Subject: [PATCH 18/20] PMD --- .../common/inputevent/InputEventBaseOnOS.java | 312 +++++++++++++++++- 1 file changed, 301 insertions(+), 11 deletions(-) diff --git a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java index 29b6b9ce3..1ea424c67 100644 --- a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java +++ b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java @@ -1,21 +1,311 @@ -package com.fr.common.inputevent; - -import com.fr.stable.OperatingSystem; +package com.fr.design.gui.ilist; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EventListener; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; + +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.stable.StringUtils; /** - * Created by hzzz on 2017/5/26. + * CheckBoxs + JList. */ -public class InputEventBaseOnOS { - private static final boolean IS_MACOS = OperatingSystem.isMacOS(); +public class CheckBoxList extends JComponent { + /** + * 选择状态----全选和全不选 + * + * @editor zhou + * @since 2012-4-1下午2:39:10 + */ + public static enum SelectedState { + ALL, NONE + } + + private boolean[] selects; + private JList jlist; + private UICheckBox chooseAll; + + public CheckBoxList(Object[] items) { + this(items, SelectedState.NONE, StringUtils.EMPTY); + } + + public CheckBoxList(Object[] items, String name) { + this(items, SelectedState.NONE, name); + } + + /** + * Class constructor. + * + * @param items + * Items with which to populate the list. + * @param default_state + * default state, true or false + */ + public CheckBoxList(Object[] items, SelectedState state, String name) { + jlist = new BOXLIST(items); + jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + this.selects = new boolean[items.length]; + boolean default_state = (state == SelectedState.ALL); + Arrays.fill(this.selects, default_state); + + jlist.setCellRenderer(new CheckListCellRenderer()); + jlist.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + doCheck(); + } + + public void mouseReleased(MouseEvent e) { + doCheck(); + } + }); + jlist.addKeyListener(new KeyAdapter() { + + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == ' ') { + doCheck(); + } + } + + }); + this.setLayout(new BorderLayout()); + chooseAll = new UICheckBox(name, default_state); + chooseAll.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (chooseAll.isSelected()) { + setSelected(true); + } else { + setSelected(false); + } + } + }); + this.add(chooseAll, BorderLayout.NORTH); + this.add(jlist, BorderLayout.CENTER); + } + + /* + * 用于CellRenderer显示value为text + */ + protected String value2Text(Object value) { + return value != null ? value.toString() : StringUtils.EMPTY; + } + + public void setItems(Object[] os) { + if (os == null) { + this.setSelected(false); + } else { + for (int i = 0, len = os.length; i < len; i++) { + Object o = os[i]; + for (int j = 0, jen = jlist.getModel().getSize(); j < jen; j++) { + if (o.equals(jlist.getModel().getElementAt(j))) { + this.setSelected(j, true); + } + } + } + } + this.repaint(); + } + + /** + * Is selected + */ + public boolean isSelected(int index) { + if (selects == null || index >= selects.length) { + return false; + } + + return selects[index]; + } + + public void setSelected(int index, boolean isSelected) { + if (selects == null || index >= selects.length) { + return; + } + + selects[index] = isSelected; + this.repaint(this.getBounds()); + + this.fireCheckBoxListSelectionChangeListener(); + } + + private void setSelected(boolean isSelected) { + if (selects == null) { + return; + } + for (int i = 0; i < selects.length; i++) { + selects[i] = isSelected; + } + this.repaint(this.getBounds()); + + this.fireCheckBoxListSelectionChangeListener(); + } - public static boolean isControlDown(MouseEvent e) { - return IS_MACOS ? e.isMetaDown() : e.isControlDown(); + /** + * Returns an array of the objects that have been selected. Overrides the + * JList method. + */ + public Object[] getSelectedValues() { + return this.jlist.getSelectedValues(); } - public static boolean isControlDown(KeyEvent e) { - return IS_MACOS ? e.isMetaDown() : e.isControlDown(); + private class BOXLIST extends JList { + public BOXLIST(Object[] items) { + super(items); + } + + @Override + protected void processMouseEvent(MouseEvent e) { + if (e.getX() < 20) { + if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { + int[] indices = getSelectedIndices(); + if (indices.length == 0) { + super.processMouseEvent(e); + } + } else { + super.processMouseEvent(e); + } + } else { + super.processMouseEvent(e); + } + int id = e.getID(); + switch (id) { + case MouseEvent.MOUSE_PRESSED: + break; + case MouseEvent.MOUSE_RELEASED: + break; + case MouseEvent.MOUSE_CLICKED: + doCheck(); + break; + case MouseEvent.MOUSE_EXITED: + break; + case MouseEvent.MOUSE_ENTERED: + break; + } + } + + @Override + protected void processMouseMotionEvent(MouseEvent e) { + if (e.getX() < 20) { + return; + } + + super.processMouseEvent(e); + } + + @Override + public Object[] getSelectedValues() { + List list = new ArrayList(selects.length); + for (int i = 0; i < selects.length; i++) { + if (selects[i]) { + list.add(this.getModel().getElementAt(i)); + } + } + + return list.toArray(); + } + + } + + private void doCheck() { + // p:这里必须改变所有选择checkbox. + int index = jlist.getSelectedIndex(); + boolean sValue = !selects[index]; + + // p:开始设置所有选择的checkbox. + int[] indices = jlist.getSelectedIndices(); + for (int i = 0; i < indices.length; i++) { + setSelected(indices[i], sValue); + } + for (boolean selected : selects) { + if (!selected) { + chooseAll.setSelected(false); + return; + } + } + chooseAll.setSelected(true); + repaint(); + } + + private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); + + private class CheckListCellRenderer extends UICheckBox implements ListCellRenderer { + + public CheckListCellRenderer() { + this.setOpaque(true); + this.setBorder(noFocusBorder); + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + this.setText(value2Text(value)); + this.setSelected(selects[index]); + this.setFont(list.getFont()); + + if (isSelected) { + this.setBackground(list.getSelectionBackground()); + this.setForeground(list.getSelectionForeground()); + } else { + this.setBackground(list.getBackground()); + this.setForeground(list.getForeground()); + } + + if (cellHasFocus) { + this.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); + } else { + this.setBorder(noFocusBorder); + } + + return this; + } + } + + public void addCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { + this.listenerList.add(CheckBoxListSelectionChangeListener.class, l); } -} + + public void removeCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { + this.listenerList.remove(CheckBoxListSelectionChangeListener.class, l); + } + + public void fireCheckBoxListSelectionChangeListener() { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == CheckBoxListSelectionChangeListener.class) { + ((CheckBoxListSelectionChangeListener)listeners[i + 1]).selectionChanged(this); + } + } + + } + + public static interface CheckBoxListSelectionChangeListener extends EventListener { + public void selectionChanged(CheckBoxList target); + } + + public ListModel getModel() { + return jlist.getModel(); + } + +} \ No newline at end of file From 35aa59377d871190b64b4f8a89fca01324346744 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 10:16:13 +0800 Subject: [PATCH 19/20] PMD --- .../common/inputevent/InputEventBaseOnOS.java | 312 +----------------- 1 file changed, 11 insertions(+), 301 deletions(-) diff --git a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java index 1ea424c67..29b6b9ce3 100644 --- a/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java +++ b/designer_base/src/com/fr/common/inputevent/InputEventBaseOnOS.java @@ -1,311 +1,21 @@ -package com.fr.design.gui.ilist; +package com.fr.common.inputevent; + +import com.fr.stable.OperatingSystem; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EventListener; -import java.util.List; - -import javax.swing.JComponent; -import javax.swing.JList; -import javax.swing.ListCellRenderer; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; -import javax.swing.UIManager; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; - -import com.fr.design.gui.icheckbox.UICheckBox; -import com.fr.stable.StringUtils; /** - * CheckBoxs + JList. + * Created by hzzz on 2017/5/26. */ -public class CheckBoxList extends JComponent { - /** - * 选择状态----全选和全不选 - * - * @editor zhou - * @since 2012-4-1下午2:39:10 - */ - public static enum SelectedState { - ALL, NONE - } - - private boolean[] selects; - private JList jlist; - private UICheckBox chooseAll; - - public CheckBoxList(Object[] items) { - this(items, SelectedState.NONE, StringUtils.EMPTY); - } - - public CheckBoxList(Object[] items, String name) { - this(items, SelectedState.NONE, name); - } - - /** - * Class constructor. - * - * @param items - * Items with which to populate the list. - * @param default_state - * default state, true or false - */ - public CheckBoxList(Object[] items, SelectedState state, String name) { - jlist = new BOXLIST(items); - jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - this.selects = new boolean[items.length]; - boolean default_state = (state == SelectedState.ALL); - Arrays.fill(this.selects, default_state); - - jlist.setCellRenderer(new CheckListCellRenderer()); - jlist.addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent e) { - doCheck(); - } - - public void mouseReleased(MouseEvent e) { - doCheck(); - } - }); - jlist.addKeyListener(new KeyAdapter() { - - @Override - public void keyTyped(KeyEvent e) { - if (e.getKeyChar() == ' ') { - doCheck(); - } - } - - }); - this.setLayout(new BorderLayout()); - chooseAll = new UICheckBox(name, default_state); - chooseAll.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (chooseAll.isSelected()) { - setSelected(true); - } else { - setSelected(false); - } - } - }); - this.add(chooseAll, BorderLayout.NORTH); - this.add(jlist, BorderLayout.CENTER); - } - - /* - * 用于CellRenderer显示value为text - */ - protected String value2Text(Object value) { - return value != null ? value.toString() : StringUtils.EMPTY; - } - - public void setItems(Object[] os) { - if (os == null) { - this.setSelected(false); - } else { - for (int i = 0, len = os.length; i < len; i++) { - Object o = os[i]; - for (int j = 0, jen = jlist.getModel().getSize(); j < jen; j++) { - if (o.equals(jlist.getModel().getElementAt(j))) { - this.setSelected(j, true); - } - } - } - } - this.repaint(); - } - - /** - * Is selected - */ - public boolean isSelected(int index) { - if (selects == null || index >= selects.length) { - return false; - } - - return selects[index]; - } - - public void setSelected(int index, boolean isSelected) { - if (selects == null || index >= selects.length) { - return; - } - - selects[index] = isSelected; - this.repaint(this.getBounds()); - - this.fireCheckBoxListSelectionChangeListener(); - } - - private void setSelected(boolean isSelected) { - if (selects == null) { - return; - } - for (int i = 0; i < selects.length; i++) { - selects[i] = isSelected; - } - this.repaint(this.getBounds()); - - this.fireCheckBoxListSelectionChangeListener(); - } +public class InputEventBaseOnOS { + private static final boolean IS_MACOS = OperatingSystem.isMacOS(); - /** - * Returns an array of the objects that have been selected. Overrides the - * JList method. - */ - public Object[] getSelectedValues() { - return this.jlist.getSelectedValues(); + public static boolean isControlDown(MouseEvent e) { + return IS_MACOS ? e.isMetaDown() : e.isControlDown(); } - private class BOXLIST extends JList { - public BOXLIST(Object[] items) { - super(items); - } - - @Override - protected void processMouseEvent(MouseEvent e) { - if (e.getX() < 20) { - if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { - int[] indices = getSelectedIndices(); - if (indices.length == 0) { - super.processMouseEvent(e); - } - } else { - super.processMouseEvent(e); - } - } else { - super.processMouseEvent(e); - } - int id = e.getID(); - switch (id) { - case MouseEvent.MOUSE_PRESSED: - break; - case MouseEvent.MOUSE_RELEASED: - break; - case MouseEvent.MOUSE_CLICKED: - doCheck(); - break; - case MouseEvent.MOUSE_EXITED: - break; - case MouseEvent.MOUSE_ENTERED: - break; - } - } - - @Override - protected void processMouseMotionEvent(MouseEvent e) { - if (e.getX() < 20) { - return; - } - - super.processMouseEvent(e); - } - - @Override - public Object[] getSelectedValues() { - List list = new ArrayList(selects.length); - for (int i = 0; i < selects.length; i++) { - if (selects[i]) { - list.add(this.getModel().getElementAt(i)); - } - } - - return list.toArray(); - } - - } - - private void doCheck() { - // p:这里必须改变所有选择checkbox. - int index = jlist.getSelectedIndex(); - boolean sValue = !selects[index]; - - // p:开始设置所有选择的checkbox. - int[] indices = jlist.getSelectedIndices(); - for (int i = 0; i < indices.length; i++) { - setSelected(indices[i], sValue); - } - for (boolean selected : selects) { - if (!selected) { - chooseAll.setSelected(false); - return; - } - } - chooseAll.setSelected(true); - repaint(); - } - - private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - - private class CheckListCellRenderer extends UICheckBox implements ListCellRenderer { - - public CheckListCellRenderer() { - this.setOpaque(true); - this.setBorder(noFocusBorder); - } - - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - this.setText(value2Text(value)); - this.setSelected(selects[index]); - this.setFont(list.getFont()); - - if (isSelected) { - this.setBackground(list.getSelectionBackground()); - this.setForeground(list.getSelectionForeground()); - } else { - this.setBackground(list.getBackground()); - this.setForeground(list.getForeground()); - } - - if (cellHasFocus) { - this.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); - } else { - this.setBorder(noFocusBorder); - } - - return this; - } - } - - public void addCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { - this.listenerList.add(CheckBoxListSelectionChangeListener.class, l); + public static boolean isControlDown(KeyEvent e) { + return IS_MACOS ? e.isMetaDown() : e.isControlDown(); } - - public void removeCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { - this.listenerList.remove(CheckBoxListSelectionChangeListener.class, l); - } - - public void fireCheckBoxListSelectionChangeListener() { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == CheckBoxListSelectionChangeListener.class) { - ((CheckBoxListSelectionChangeListener)listeners[i + 1]).selectionChanged(this); - } - } - - } - - public static interface CheckBoxListSelectionChangeListener extends EventListener { - public void selectionChanged(CheckBoxList target); - } - - public ListModel getModel() { - return jlist.getModel(); - } - -} \ No newline at end of file +} From 85b2ed5e0424c000f47ef1e8f772a37223ed20e8 Mon Sep 17 00:00:00 2001 From: hzzz Date: Fri, 26 May 2017 10:20:05 +0800 Subject: [PATCH 20/20] PMD --- .../com/fr/design/gui/ilist/CheckBoxList.java | 585 +++++++++--------- 1 file changed, 287 insertions(+), 298 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java index 28c9e85e8..880e94d55 100644 --- a/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java +++ b/designer_base/src/com/fr/design/gui/ilist/CheckBoxList.java @@ -1,311 +1,300 @@ package com.fr.design.gui.ilist; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.stable.StringUtils; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.*; import java.util.ArrayList; import java.util.Arrays; import java.util.EventListener; import java.util.List; -import javax.swing.JComponent; -import javax.swing.JList; -import javax.swing.ListCellRenderer; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; -import javax.swing.UIManager; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; - -import com.fr.design.gui.icheckbox.UICheckBox; -import com.fr.stable.StringUtils; - /** * CheckBoxs + JList. */ public class CheckBoxList extends JComponent { - /** - * 选择状态----全选和全不选 - * - * @editor zhou - * @since 2012-4-1下午2:39:10 - */ - public static enum SelectedState { - ALL, NONE - } - - private boolean[] selects; - private JList jlist; - private UICheckBox chooseAll; - - public CheckBoxList(Object[] items) { - this(items, SelectedState.NONE, StringUtils.EMPTY); - } - - public CheckBoxList(Object[] items, String name) { - this(items, SelectedState.NONE, name); - } - - /** - * Class constructor. - * - * @param items - * Items with which to populate the list. - * @param default_state - * default state, true or false - */ - public CheckBoxList(Object[] items, SelectedState state, String name) { - jlist = new BOXLIST(items); - jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - this.selects = new boolean[items.length]; - boolean default_state = (state == SelectedState.ALL); - Arrays.fill(this.selects, default_state); - - jlist.setCellRenderer(new CheckListCellRenderer()); - jlist.addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent e) { - doCheck(); - } - - public void mouseReleased(MouseEvent e) { - doCheck(); - } - }); - jlist.addKeyListener(new KeyAdapter() { - - @Override - public void keyTyped(KeyEvent e) { - if (e.getKeyChar() == ' ') { - doCheck(); - } - } - - }); - this.setLayout(new BorderLayout()); - chooseAll = new UICheckBox(name, default_state); - chooseAll.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (chooseAll.isSelected()) { - setSelected(true); - } else { - setSelected(false); - } - } - }); - this.add(chooseAll, BorderLayout.NORTH); - this.add(jlist, BorderLayout.CENTER); - } - - /* - * 用于CellRenderer显示value为text - */ - protected String value2Text(Object value) { - return value != null ? value.toString() : StringUtils.EMPTY; - } - - public void setItems(Object[] os) { - if (os == null) { - this.setSelected(false); - } else { - for (int i = 0, len = os.length; i < len; i++) { - Object o = os[i]; - for (int j = 0, jen = jlist.getModel().getSize(); j < jen; j++) { - if (o.equals(jlist.getModel().getElementAt(j))) { - this.setSelected(j, true); - } - } - } - } - this.repaint(); - } - - /** - * Is selected - */ - public boolean isSelected(int index) { - if (selects == null || index >= selects.length) { - return false; - } - - return selects[index]; - } - - public void setSelected(int index, boolean isSelected) { - if (selects == null || index >= selects.length) { - return; - } - - selects[index] = isSelected; - this.repaint(this.getBounds()); - - this.fireCheckBoxListSelectionChangeListener(); - } - - private void setSelected(boolean isSelected) { - if (selects == null) { - return; - } - for (int i = 0; i < selects.length; i++) { - selects[i] = isSelected; - } - this.repaint(this.getBounds()); - - this.fireCheckBoxListSelectionChangeListener(); - } - - /** - * Returns an array of the objects that have been selected. Overrides the - * JList method. - */ - public Object[] getSelectedValues() { - return this.jlist.getSelectedValues(); - } - - private class BOXLIST extends JList { - public BOXLIST(Object[] items) { - super(items); - } - - @Override - protected void processMouseEvent(MouseEvent e) { - if (e.getX() < 20) { - if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { - int[] indices = getSelectedIndices(); - if (indices.length == 0) { - super.processMouseEvent(e); - } - } else { - super.processMouseEvent(e); - } - } else { - super.processMouseEvent(e); - } - int id = e.getID(); - switch (id) { - case MouseEvent.MOUSE_PRESSED: - break; - case MouseEvent.MOUSE_RELEASED: - break; - case MouseEvent.MOUSE_CLICKED: - doCheck(); - break; - case MouseEvent.MOUSE_EXITED: - break; - case MouseEvent.MOUSE_ENTERED: - break; - } - } - - @Override - protected void processMouseMotionEvent(MouseEvent e) { - if (e.getX() < 20) { - return; - } - - super.processMouseEvent(e); - } - - @Override - public Object[] getSelectedValues() { - List list = new ArrayList(selects.length); - for (int i = 0; i < selects.length; i++) { - if (selects[i]) { - list.add(this.getModel().getElementAt(i)); - } - } - - return list.toArray(); - } - - } - - private void doCheck() { - // p:这里必须改变所有选择checkbox. - int index = jlist.getSelectedIndex(); - boolean sValue = !selects[index]; - - // p:开始设置所有选择的checkbox. - int[] indices = jlist.getSelectedIndices(); - for (int i = 0; i < indices.length; i++) { - setSelected(indices[i], sValue); - } - for (boolean selected : selects) { - if (!selected) { - chooseAll.setSelected(false); - return; - } - } - chooseAll.setSelected(true); - repaint(); - } - - private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - - private class CheckListCellRenderer extends UICheckBox implements ListCellRenderer { - - public CheckListCellRenderer() { - this.setOpaque(true); - this.setBorder(noFocusBorder); - } - - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - this.setText(value2Text(value)); - this.setSelected(selects[index]); - this.setFont(list.getFont()); - - if (isSelected) { - this.setBackground(list.getSelectionBackground()); - this.setForeground(list.getSelectionForeground()); - } else { - this.setBackground(list.getBackground()); - this.setForeground(list.getForeground()); - } - - if (cellHasFocus) { - this.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); - } else { - this.setBorder(noFocusBorder); - } - - return this; - } - } - - public void addCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { - this.listenerList.add(CheckBoxListSelectionChangeListener.class, l); - } - - public void removeCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { - this.listenerList.remove(CheckBoxListSelectionChangeListener.class, l); - } - - public void fireCheckBoxListSelectionChangeListener() { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == CheckBoxListSelectionChangeListener.class) { - ((CheckBoxListSelectionChangeListener)listeners[i + 1]).selectionChanged(this); - } - } - - } - - public static interface CheckBoxListSelectionChangeListener extends EventListener { - public void selectionChanged(CheckBoxList target); - } - - public ListModel getModel() { - return jlist.getModel(); - } + private final static int X_COORDINATE = 20; + + /** + * 选择状态----全选和全不选 + * + * @editor zhou + * @since 2012-4-1下午2:39:10 + */ + public static enum SelectedState { + ALL, NONE + } + + private boolean[] selects; + private JList jlist; + private UICheckBox chooseAll; + + public CheckBoxList(Object[] items) { + this(items, SelectedState.NONE, StringUtils.EMPTY); + } + + public CheckBoxList(Object[] items, String name) { + this(items, SelectedState.NONE, name); + } + + /** + * Class constructor. + * + * @param items Items with which to populate the list. + * @param state default state, true or false + */ + public CheckBoxList(Object[] items, SelectedState state, String name) { + jlist = new BOXLIST(items); + jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + this.selects = new boolean[items.length]; + boolean default_state = (state == SelectedState.ALL); + Arrays.fill(this.selects, default_state); + + jlist.setCellRenderer(new CheckListCellRenderer()); + jlist.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + doCheck(); + } + + public void mouseReleased(MouseEvent e) { + doCheck(); + } + }); + jlist.addKeyListener(new KeyAdapter() { + + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == ' ') { + doCheck(); + } + } + + }); + this.setLayout(new BorderLayout()); + chooseAll = new UICheckBox(name, default_state); + chooseAll.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (chooseAll.isSelected()) { + setSelected(true); + } else { + setSelected(false); + } + } + }); + this.add(chooseAll, BorderLayout.NORTH); + this.add(jlist, BorderLayout.CENTER); + } + + /* + * 用于CellRenderer显示value为text + */ + protected String value2Text(Object value) { + return value != null ? value.toString() : StringUtils.EMPTY; + } + + public void setItems(Object[] os) { + if (os == null) { + this.setSelected(false); + } else { + for (int i = 0, len = os.length; i < len; i++) { + Object o = os[i]; + for (int j = 0, jen = jlist.getModel().getSize(); j < jen; j++) { + if (o.equals(jlist.getModel().getElementAt(j))) { + this.setSelected(j, true); + } + } + } + } + this.repaint(); + } + + /** + * Is selected + */ + public boolean isSelected(int index) { + if (selects == null || index >= selects.length) { + return false; + } + + return selects[index]; + } + + public void setSelected(int index, boolean isSelected) { + if (selects == null || index >= selects.length) { + return; + } + + selects[index] = isSelected; + this.repaint(this.getBounds()); + + this.fireCheckBoxListSelectionChangeListener(); + } + + private void setSelected(boolean isSelected) { + if (selects == null) { + return; + } + for (int i = 0; i < selects.length; i++) { + selects[i] = isSelected; + } + this.repaint(this.getBounds()); + + this.fireCheckBoxListSelectionChangeListener(); + } + + /** + * Returns an array of the objects that have been selected. Overrides the + * JList method. + */ + public Object[] getSelectedValues() { + return this.jlist.getSelectedValues(); + } + + private class BOXLIST extends JList { + public BOXLIST(Object[] items) { + super(items); + } + + @Override + protected void processMouseEvent(MouseEvent e) { + if (e.getX() < X_COORDINATE) { + boolean anyMaskDown = e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown(); + if (anyMaskDown) { + int[] indices = getSelectedIndices(); + if (indices.length == 0) { + super.processMouseEvent(e); + } + } else { + super.processMouseEvent(e); + } + } else { + super.processMouseEvent(e); + } + int id = e.getID(); + switch (id) { + case MouseEvent.MOUSE_PRESSED: + break; + case MouseEvent.MOUSE_RELEASED: + break; + case MouseEvent.MOUSE_CLICKED: + doCheck(); + break; + case MouseEvent.MOUSE_EXITED: + break; + case MouseEvent.MOUSE_ENTERED: + break; + } + } + + @Override + protected void processMouseMotionEvent(MouseEvent e) { + if (e.getX() < X_COORDINATE) { + return; + } + + super.processMouseEvent(e); + } + + @Override + public Object[] getSelectedValues() { + List list = new ArrayList(selects.length); + for (int i = 0; i < selects.length; i++) { + if (selects[i]) { + list.add(this.getModel().getElementAt(i)); + } + } + + return list.toArray(); + } + + } + + private void doCheck() { + // p:这里必须改变所有选择checkbox. + int index = jlist.getSelectedIndex(); + boolean sValue = !selects[index]; + + // p:开始设置所有选择的checkbox. + int[] indices = jlist.getSelectedIndices(); + for (int i = 0; i < indices.length; i++) { + setSelected(indices[i], sValue); + } + for (boolean selected : selects) { + if (!selected) { + chooseAll.setSelected(false); + return; + } + } + chooseAll.setSelected(true); + repaint(); + } + + private static final Border NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + + private class CheckListCellRenderer extends UICheckBox implements ListCellRenderer { + + public CheckListCellRenderer() { + this.setOpaque(true); + this.setBorder(NO_FOCUS_BORDER); + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + this.setText(value2Text(value)); + this.setSelected(selects[index]); + this.setFont(list.getFont()); + + if (isSelected) { + this.setBackground(list.getSelectionBackground()); + this.setForeground(list.getSelectionForeground()); + } else { + this.setBackground(list.getBackground()); + this.setForeground(list.getForeground()); + } + + if (cellHasFocus) { + this.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); + } else { + this.setBorder(NO_FOCUS_BORDER); + } + + return this; + } + } + + public void addCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { + this.listenerList.add(CheckBoxListSelectionChangeListener.class, l); + } + + public void removeCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { + this.listenerList.remove(CheckBoxListSelectionChangeListener.class, l); + } + + public void fireCheckBoxListSelectionChangeListener() { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == CheckBoxListSelectionChangeListener.class) { + ((CheckBoxListSelectionChangeListener) listeners[i + 1]).selectionChanged(this); + } + } + + } + + public static interface CheckBoxListSelectionChangeListener extends EventListener { + public void selectionChanged(CheckBoxList target); + } + + public ListModel getModel() { + return jlist.getModel(); + } } \ No newline at end of file