From adfd2a3ecc80beaf03efe9fe48d68e60a814c7a4 Mon Sep 17 00:00:00 2001 From: "yaoh.wu" Date: Mon, 5 Feb 2018 10:10:03 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-6868=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=88=97=E5=8D=95=E5=85=83=E6=A0=BC=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=A2=91=E7=B9=81=E5=BC=B9=E5=87=BAsql=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=AF=B9=E8=AF=9D=E6=A1=86=EF=BC=9B=20=E6=97=A0?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=EF=BC=8C=E5=88=A0=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectedConfirmedDataColumnPane.java | 3 +- .../dscolumn/SelectedDataColumnPane.java | 161 ++++--- .../cellquick/CellDSColumnEditor.java | 4 +- .../com/fr/design/gui/demo/ComboBoxDemo.java | 48 +- .../design/gui/demo/SwingComponentsDemo.java | 17 +- .../fr/design/gui/icombobox/LazyComboBox.java | 401 ++++++++--------- .../fr/design/gui/icombobox/UIComboBox.java | 410 +++++++++--------- 7 files changed, 531 insertions(+), 513 deletions(-) diff --git a/designer/src/com/fr/design/dscolumn/SelectedConfirmedDataColumnPane.java b/designer/src/com/fr/design/dscolumn/SelectedConfirmedDataColumnPane.java index 9552f6ba95..ca13b4a59b 100644 --- a/designer/src/com/fr/design/dscolumn/SelectedConfirmedDataColumnPane.java +++ b/designer/src/com/fr/design/dscolumn/SelectedConfirmedDataColumnPane.java @@ -17,6 +17,7 @@ public class SelectedConfirmedDataColumnPane extends SelectedDataColumnPane { super(false); } + @Override protected void initTableNameComboBox() { tableNameComboBox = new TableDataComboBox(new WorkBook()); tableNameComboBox.addItemListener(new ItemListener() { @@ -39,7 +40,7 @@ public class SelectedConfirmedDataColumnPane extends SelectedDataColumnPane { TemplateTableDataWrapper wrapper = new TemplateTableDataWrapper(source.getTableData(name), name); tableNameComboBox.setSelectedItem(wrapper); tableNameComboBox.getModel().setSelectedItem(wrapper); - } catch (Exception e) { + } catch (Exception ignored) { } } } \ No newline at end of file diff --git a/designer/src/com/fr/design/dscolumn/SelectedDataColumnPane.java b/designer/src/com/fr/design/dscolumn/SelectedDataColumnPane.java index 62538e7d05..9b1ad0088f 100644 --- a/designer/src/com/fr/design/dscolumn/SelectedDataColumnPane.java +++ b/designer/src/com/fr/design/dscolumn/SelectedDataColumnPane.java @@ -37,8 +37,7 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.Objects; import java.util.regex.Pattern; /** @@ -50,29 +49,83 @@ import java.util.regex.Pattern; * @since 8.0 */ public class SelectedDataColumnPane extends BasicPane { + + /** + * 参数编辑器面板 + */ private UITableEditorPane editorPane; + /** + * 参数 + */ private Parameter[] ps; - + /** + * 数据集下拉框 + */ TableDataComboBox tableNameComboBox; + /** + * 动态参数注入按钮 + */ + private UIButton paramButton; + /** + * 数据列下拉框 + */ LazyComboBox columnNameComboBox; + + /** + * 数据集下拉框和数据列下拉框监听器 + */ private ItemListener itemListener; - private UIButton paramButton; + + /** + * 当前编辑的模板面板,用于触发保存操作 + */ private ElementCasePane casePane; - private CellElement cellElement; // 保存当前选中的 CE + /** + * 保存当前选中的 CE + */ + private CellElement cellElement; + + private static final Pattern COLUMN_NAME_PATTERN = Pattern.compile("[^\\d]"); + + /** + * 数据集下拉框变动后修改数据列下拉框加载状态的监听器 + */ + private ItemListener loadInstantListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + columnNameComboBox.setLoaded(false); + } + } + }; - public SelectedDataColumnPane() { - this(true, false, null); + /** + * 创建横向布局附带显示动态参数注入按钮的数据集数据列选择面板 + */ + SelectedDataColumnPane() { + this(true, false); } - public SelectedDataColumnPane(boolean showParameterButton) { - this(showParameterButton, false, null); + /** + * 创建横向布局的数据集数据列选择面板 + * + * @param showParameterButton 是否显示动态参数注入按钮 + */ + SelectedDataColumnPane(boolean showParameterButton) { + this(showParameterButton, false); } - public SelectedDataColumnPane(boolean showParameterButton, boolean verticalLayout, TemplateCellElement cellElement) { + /** + * 创建数据集数据列选择面板 + * + * @param showParameterButton 是否显示动态参数注入按钮 + * @param verticalLayout 是否是垂直布局 + */ + public SelectedDataColumnPane(boolean showParameterButton, boolean verticalLayout) { if (verticalLayout) { - initComponentVerticalLayout(cellElement); + initComponentVerticalLayout(); } else { initComponent(showParameterButton); } @@ -86,7 +139,7 @@ public class SelectedDataColumnPane extends BasicPane { public void initComponent(boolean showParameterButton) { initTableNameComboBox(); if (showParameterButton) { - initWithParameterButton(); + initParameterButton(); } columnNameComboBox = new LazyComboBox() { @@ -126,9 +179,9 @@ public class SelectedDataColumnPane extends BasicPane { /** * 初始化竖直布局的组件 */ - private void initComponentVerticalLayout(TemplateCellElement cellElement) { + private void initComponentVerticalLayout() { initTableNameComboBox(); - initWithParameterButton(cellElement); + initVerticalParameterButton(); columnNameComboBox = new LazyComboBox() { @Override public Object[] load() { @@ -156,6 +209,13 @@ public class SelectedDataColumnPane extends BasicPane { } + /** + * 更新面板数据 + * + * @param source 数据源 + * @param cellElement 单元格 + * @param casePane 当前编辑的模板面板 + */ public void populate(TableDataSource source, TemplateCellElement cellElement, ElementCasePane casePane) { tableNameComboBox.refresh(source); this.casePane = casePane; @@ -163,9 +223,8 @@ public class SelectedDataColumnPane extends BasicPane { return; } this.cellElement = cellElement; - if (itemListener != null) { - removeListener(itemListener); - } + removeListener(); + Object value = cellElement.getValue(); if (!(value instanceof DSColumn)) { return; @@ -176,9 +235,14 @@ public class SelectedDataColumnPane extends BasicPane { columnNameComboBox.setSelectedItem(TableDataColumn.getColumnName(dsColumn.getColumn())); ps = dsColumn.getParameters(); - addListener(itemListener); + addListener(); } + /** + * 保存数据到单元格对象中 + * + * @param cellElement 单元格 + */ public void update(CellElement cellElement) { if (cellElement == null) { return; @@ -187,7 +251,7 @@ public class SelectedDataColumnPane extends BasicPane { if (this.tableNameComboBox.getSelectedItem() == null && this.columnNameComboBox.getSelectedItem() == null) { return; } - DSColumn dsColumn = null; + DSColumn dsColumn; if (value == null || !(value instanceof DSColumn)) { dsColumn = new DSColumn(); cellElement.setValue(dsColumn); @@ -195,7 +259,7 @@ public class SelectedDataColumnPane extends BasicPane { dsColumn = (DSColumn) cellElement.getValue(); SimpleDSColumn simpleDSColumn = updateColumnPane(); - dsColumn.setDSName(simpleDSColumn.getDsName()); + dsColumn.setDSName(Objects.requireNonNull(simpleDSColumn).getDsName()); dsColumn.setColumn(simpleDSColumn.getColumn()); dsColumn.setParameters((ps != null && ps.length > 0) ? ps : null); @@ -205,6 +269,7 @@ public class SelectedDataColumnPane extends BasicPane { * 释放模板对象 */ public void release() { + this.cellElement = null; this.casePane = null; this.tableNameComboBox.setModel(new DefaultComboBoxModel()); } @@ -214,7 +279,7 @@ public class SelectedDataColumnPane extends BasicPane { * * @return 更新后的值 */ - public SimpleDSColumn updateColumnPane() { + private SimpleDSColumn updateColumnPane() { SimpleDSColumn dsColumn = new SimpleDSColumn(); TableDataWrapper tableDataWrappe = this.tableNameComboBox.getSelectedItem(); if (tableDataWrappe == null) { @@ -224,9 +289,8 @@ public class SelectedDataColumnPane extends BasicPane { TableDataColumn column; String columnExp = (String) this.columnNameComboBox.getSelectedItem(); if (isColumnName(columnExp)) { - String number = columnExp.substring(1); - Pattern pattern = Pattern.compile("[^\\d]"); - if (pattern.matcher(number).find()) { + String number = Objects.requireNonNull(columnExp).substring(1); + if (COLUMN_NAME_PATTERN.matcher(number).find()) { column = TableDataColumn.createColumn(columnExp); } else { int serialNumber = Integer.parseInt(columnExp.substring(1)); @@ -239,47 +303,31 @@ public class SelectedDataColumnPane extends BasicPane { return dsColumn; } + public void setListener(ItemListener i) { + this.itemListener = i; + } + /** * 添加监听事件 - * - * @param i 监听事件 */ - public void addListener(ItemListener i) { - itemListener = i; - tableNameComboBox.addItemListener(i); - columnNameComboBox.addItemListener(i); + private void addListener() { + tableNameComboBox.addItemListener(this.itemListener); + columnNameComboBox.addItemListener(this.itemListener); } /** * 移除监听事件 - * - * @param i 监听事件 */ - public void removeListener(ItemListener i) { - tableNameComboBox.removeItemListener(i); - columnNameComboBox.removeItemListener(i); + private void removeListener() { + tableNameComboBox.removeItemListener(this.itemListener); + columnNameComboBox.removeItemListener(this.itemListener); } protected void initTableNameComboBox() { tableNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource()); - final ExecutorService executorService = Executors.newSingleThreadExecutor(); - tableNameComboBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - executorService.execute(new Runnable() { - @Override - public void run() { - synchronized (columnNameComboBox) { - columnNameComboBox.loadInstant(); - } - } - }); - } - } - }); tableNameComboBox.setPreferredSize(new Dimension(100, 20)); + tableNameComboBox.addItemListener(this.loadInstantListener); } @Override @@ -288,8 +336,8 @@ public class SelectedDataColumnPane extends BasicPane { } - private void initWithParameterButton() { - editorPane = new UITableEditorPane(new ParameterTableModel()); + private void initParameterButton() { + editorPane = new UITableEditorPane<>(new ParameterTableModel()); paramButton = new UIButton(Inter.getLocText("TableData_Dynamic_Parameter_Setting")); paramButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -307,10 +355,11 @@ public class SelectedDataColumnPane extends BasicPane { }); } - private void initWithParameterButton(final TemplateCellElement cellElement) { - editorPane = new UITableEditorPane(new ParameterTableModel()); + private void initVerticalParameterButton() { + editorPane = new UITableEditorPane<>(new ParameterTableModel()); paramButton = new UIButton(Inter.getLocText("FR-Designer-Basic_Dynamic_Parameter_Injection")); paramButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { BasicDialog paramDialog = editorPane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { @Override @@ -337,6 +386,6 @@ public class SelectedDataColumnPane extends BasicPane { if (this.tableNameComboBox.getSelectedItem() != null) { return this.tableNameComboBox.getSelectedItem().calculateColumnNameList(); } - return new ArrayList(); + return new ArrayList<>(); } } \ No newline at end of file diff --git a/designer/src/com/fr/quickeditor/cellquick/CellDSColumnEditor.java b/designer/src/com/fr/quickeditor/cellquick/CellDSColumnEditor.java index ea872d01cf..be8c7c962f 100644 --- a/designer/src/com/fr/quickeditor/cellquick/CellDSColumnEditor.java +++ b/designer/src/com/fr/quickeditor/cellquick/CellDSColumnEditor.java @@ -247,9 +247,9 @@ public class CellDSColumnEditor extends CellQuickEditor { }; DSColumnBasicEditorPane() { - dataPane = new SelectedDataColumnPane(true, true, cellElement); + dataPane = new SelectedDataColumnPane(true, true); groupPane = new ResultSetGroupDockingPane(); - dataPane.addListener(dataListener); + dataPane.setListener(dataListener); groupPane.setListener(groupListener); double[] rowSize = {P}, columnSize = {P, F}; diff --git a/designer_base/src/com/fr/design/gui/demo/ComboBoxDemo.java b/designer_base/src/com/fr/design/gui/demo/ComboBoxDemo.java index 499243b45f..da7657d079 100644 --- a/designer_base/src/com/fr/design/gui/demo/ComboBoxDemo.java +++ b/designer_base/src/com/fr/design/gui/demo/ComboBoxDemo.java @@ -1,34 +1,37 @@ package com.fr.design.gui.demo; -import java.awt.BorderLayout; -import java.awt.Component; -import java.util.ArrayList; - -import javax.swing.DefaultListCellRenderer; -import com.fr.design.gui.ilable.UILabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JTree; -import javax.swing.ListCellRenderer; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreePath; - import com.fr.base.FRContext; -import com.fr.design.gui.icombobox.filter.Filter; +import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.gui.icombobox.ComboCheckBox; import com.fr.design.gui.icombobox.DictionaryComboBox; import com.fr.design.gui.icombobox.ExtendedComboBox; import com.fr.design.gui.icombobox.FRTreeComboBox; import com.fr.design.gui.icombobox.FilterComboBox; import com.fr.design.gui.icombobox.LazyComboBox; +import com.fr.design.gui.icombobox.filter.Filter; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.parameter.ParameterInputPane; import com.fr.general.Inter; +import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.ListCellRenderer; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.BorderLayout; +import java.awt.Component; +import java.util.ArrayList; + /** * Created by IntelliJ IDEA. * User: Richer @@ -42,12 +45,12 @@ public class ComboBoxDemo extends JPanel { double f = TableLayout.FILL; Component[][] coms = new Component[][]{ - {new UILabel(Inter.getLocText("Form-ComboCheckBox")+":"), createComboCheckBox()}, - {new UILabel(Inter.getLocText(new String[]{"DS-Dictionary", "Form-ComboBox"})+":"), createDictComboBox()}, - {new UILabel(Inter.getLocText("long_data_can_not_show_fully")+":"), createExtendedComboBox()}, - {new UILabel(Inter.getLocText(new String[]{"Filter", "Form-ComboBox"})+":"), createFilterComboBox()}, - {new UILabel(Inter.getLocText("Form-ComboBox")+":"), createTreeComboBox()}, - {new UILabel(Inter.getLocText(new String[]{"Delay", "Load", "Form-ComboBox"})+":"), createLazyComboBox()} + {new UILabel(Inter.getLocText("Form-ComboCheckBox") + ":"), createComboCheckBox()}, + {new UILabel(Inter.getLocText(new String[]{"DS-Dictionary", "Form-ComboBox"}) + ":"), createDictComboBox()}, + {new UILabel(Inter.getLocText("long_data_can_not_show_fully") + ":"), createExtendedComboBox()}, + {new UILabel(Inter.getLocText(new String[]{"Filter", "Form-ComboBox"}) + ":"), createFilterComboBox()}, + {new UILabel(Inter.getLocText("Form-ComboBox") + ":"), createTreeComboBox()}, + {new UILabel(Inter.getLocText(new String[]{"Delay", "Load", "Form-ComboBox"}) + ":"), createLazyComboBox()} }; double[] rowSize = new double[coms.length]; double[] columnSize = {p, f}; @@ -165,6 +168,7 @@ public class ComboBoxDemo extends JPanel { // 睡5秒 try { Thread.sleep(5000); + } catch (InterruptedException e) { FRContext.getLogger().error(e.getMessage(), e); } diff --git a/designer_base/src/com/fr/design/gui/demo/SwingComponentsDemo.java b/designer_base/src/com/fr/design/gui/demo/SwingComponentsDemo.java index b819c337fc..eb026a5699 100644 --- a/designer_base/src/com/fr/design/gui/demo/SwingComponentsDemo.java +++ b/designer_base/src/com/fr/design/gui/demo/SwingComponentsDemo.java @@ -1,16 +1,15 @@ package com.fr.design.gui.demo; -import java.awt.BorderLayout; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.gui.GUICoreUtils; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; - -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.utils.DesignUtils; -import com.fr.design.utils.gui.GUICoreUtils; +import java.awt.BorderLayout; /** * Created by IntelliJ IDEA. @@ -19,10 +18,10 @@ import com.fr.design.utils.gui.GUICoreUtils; * Time: 下午4:54 */ public class SwingComponentsDemo extends JFrame { - public SwingComponentsDemo() { - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + private SwingComponentsDemo() { + this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); init(); - JPanel contentPane = (JPanel)getContentPane(); + JPanel contentPane = (JPanel) getContentPane(); contentPane.setLayout(FRGUIPaneFactory.createBorderLayout()); JTabbedPane tab = new JTabbedPane(); contentPane.add(tab, BorderLayout.CENTER); @@ -40,12 +39,12 @@ public class SwingComponentsDemo extends JFrame { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { JFrame f = new SwingComponentsDemo(); f.setSize(500, 500); f.setVisible(true); GUICoreUtils.centerWindow(f); - f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); } }); } diff --git a/designer_base/src/com/fr/design/gui/icombobox/LazyComboBox.java b/designer_base/src/com/fr/design/gui/icombobox/LazyComboBox.java index 43711b0118..2ec5590f64 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/LazyComboBox.java +++ b/designer_base/src/com/fr/design/gui/icombobox/LazyComboBox.java @@ -1,211 +1,192 @@ -/* - * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. - */ -package com.fr.design.gui.icombobox; - -import java.awt.Dimension; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; -import javax.swing.plaf.basic.BasicComboPopup; - -import com.fr.general.Inter; - -/** - * @author richer - * @since 6.5.5 创建于2011-6-15 延迟加载的下拉框 - */ -public abstract class LazyComboBox extends UIComboBox implements PopupMenuListener { - protected boolean loaded = false; - private List ls = new ArrayList(); - private Object initialSelected = null; - private static final int NUM=80; - - public static final Object PENDING = new Object() { - - @Override - public String toString() { - return Inter.getLocText("Loading") + "..."; - } - }; - - public LazyComboBox() { - super(); - this.setEditor(new FilterComboBoxEditor()); - addPopupMenuListener(this); -// updateUI(); - } - - public void setLoaded(boolean loaded) { - this.loaded = loaded; - } - - public abstract Object[] load(); - - public void setSelectedItem(Object anObject) { - initialSelected = anObject; - if (loaded) { - super.setSelectedItem(anObject); - } else { - - setModel(new DefaultComboBoxModel(new Object[] { anObject })); - super.setSelectedItem(anObject); - } - } - - /** - * 通过调用该方法,在点击下拉框按钮之前就加载好数据,不需要出现loading了 - */ - public void loadInstant() { - setLoaded(true); - loadList(); - } - - @Override - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - if (loaded) { - return; - } - DefaultComboBoxModel loadingModel = new DefaultComboBoxModel(new String[]{"", Inter.getLocText("Loading") + "..."}); - LazyComboBox.this.setModel(loadingModel); - new SwingWorker() { - - @Override - protected Void doInBackground() throws Exception { - final Object selectedObj = getSelectedItem(); - loadList(); - return null; - } - - @Override - public void done() { - LazyComboBox.this.updateUI(); - LazyComboBox.this.fireEvent(); - LazyComboBox.this.showPopup(); - } - - }.execute(); - - - } - - /** - * 计算加载下拉列表 - */ - public void loadList() { - DefaultComboBoxModel model = new DefaultComboBoxModel(load()); - model.setSelectedItem(initialSelected); - LazyComboBox.this.setModel(model); - LazyComboBox.this.selectedItemReminder = initialSelected ; - loaded = true; - } - - @Override - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - - } - - @Override - public void popupMenuCanceled(PopupMenuEvent e) { - - } - - public void addClickListener(EventListener l) { - if (ls == null) { - ls = new ArrayList(); - } - ls.add(l); - } - - public void fireEvent() { - for (int i = 0, n = ls.size(); i < n; i++) { - ls.get(i).fireEvent(); - } - } - - @Override - public Dimension getPreferredSize() { - Dimension dim = super.getPreferredSize(); - dim.width = NUM; - return dim; - } - - private static class LazyPopMenu extends BasicComboPopup { - - public LazyPopMenu(final JComboBox combo) { - super(combo); - LazyComboBox comboc = (LazyComboBox) combo; - comboc.addClickListener(new EventListener() { - - @Override - public void fireEvent() { - LazyPopMenu.this.show(); - combo.showPopup(); - } - }); - } - } - - private interface EventListener { - void fireEvent(); - } - - class FilterComboBoxEditor extends UIComboBoxEditor implements DocumentListener { - private Object item; - private volatile boolean filtering = false; - private volatile boolean setting = false; - - public FilterComboBoxEditor() { - super(); - textField.getDocument().addDocumentListener(this); - } - - public void setItem(Object item) { - if (filtering) { - return; - } - this.item = item; - - this.setting = true; - textField.setSetting(true); - String newText = (item == null) ? "" : item.toString(); - textField.setText(newText); - textField.setSetting(false); - this.setting = false; - } - - public Object getItem() { - return this.item; - } - - public void insertUpdate(DocumentEvent e) { - handleChange(); - } - - public void removeUpdate(DocumentEvent e) { - handleChange(); - } - - public void changedUpdate(DocumentEvent e) { - handleChange(); - } - - protected void handleChange() { - if (setting) { - return; - } - filtering = true; - String xx = textField.getText(); - LazyComboBox.this.setSelectedItem(xx); - this.item = textField.getText(); - - setPopupVisible(true); - filtering = false; - } - } +/* + * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. + */ +package com.fr.design.gui.icombobox; + +import com.fr.general.FRLogger; +import com.fr.general.Inter; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import java.awt.Dimension; +import java.util.concurrent.ExecutionException; + +/** + * @author richer + * @version 2018年2月6日14点43分 by @yaoh.wu + * @since 6.5.5 创建于2011-6-15 延迟加载的下拉框 + */ +public abstract class LazyComboBox extends UIComboBox implements PopupMenuListener { + + private static final int NUM = 80; + private static final String[] PENDING_CONTENT = new String[]{"", Inter.getLocText("Loading") + "..."}; + + /** + * 是否加载完成 + */ + protected boolean loaded = false; + + /** + * 初始化选项 + */ + private Object initialSelected = null; + + + protected LazyComboBox() { + super(); + this.setEditor(new FilterComboBoxEditor()); + addPopupMenuListener(this); + } + + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + /** + * 加载下拉框中的选项 + * + * @return 下拉框中的选项 + */ + public abstract Object[] load(); + + @Override + public void setSelectedItem(Object anObject) { + initialSelected = anObject; + if (loaded) { + super.setSelectedItem(anObject); + } else { + this.setModel(new DefaultComboBoxModel<>(new Object[]{anObject})); + super.setSelectedItem(anObject); + } + } + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + if (loaded) { + return; + } + DefaultComboBoxModel loadingModel = new DefaultComboBoxModel<>(PENDING_CONTENT); + this.setModel(loadingModel); + new SwingWorker() { + + @Override + protected Object[] doInBackground() { + return load(); + } + + @Override + public void done() { + try { + LazyComboBox.this.loadList(get()); + } catch (InterruptedException | ExecutionException exception) { + FRLogger.getLogger().debug(exception.getMessage()); + } + LazyComboBox.this.showPopup(); + } + }.execute(); + } + + + /** + * 加载下拉列表 + */ + public void loadList() { + DefaultComboBoxModel model = new DefaultComboBoxModel<>(load()); + model.setSelectedItem(initialSelected); + this.setModel(model); + this.selectedItemReminder = initialSelected; + loaded = true; + } + + /** + * 加载下拉列表 + * + * @param contents 下拉列表内容 + */ + private void loadList(Object[] contents) { + DefaultComboBoxModel model = new DefaultComboBoxModel<>(contents); + model.setSelectedItem(initialSelected); + this.setModel(model); + this.selectedItemReminder = initialSelected; + loaded = true; + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + + } + + @Override + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.width = NUM; + return dim; + } + + class FilterComboBoxEditor extends UIComboBoxEditor implements DocumentListener { + private Object item; + private volatile boolean filtering = false; + private volatile boolean setting = false; + + public FilterComboBoxEditor() { + super(); + textField.getDocument().addDocumentListener(this); + } + + @Override + public void setItem(Object item) { + if (filtering) { + return; + } + this.item = item; + this.setting = true; + textField.setSetting(true); + String newText = (item == null) ? "" : item.toString(); + textField.setText(newText); + textField.setSetting(false); + this.setting = false; + } + + @Override + public Object getItem() { + return this.item; + } + + @Override + public void insertUpdate(DocumentEvent e) { + handleChange(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + handleChange(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + handleChange(); + } + + void handleChange() { + if (setting) { + return; + } + filtering = true; + String xx = textField.getText(); + LazyComboBox.this.setSelectedItem(xx); + this.item = textField.getText(); + + setPopupVisible(true); + filtering = false; + } + } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/icombobox/UIComboBox.java b/designer_base/src/com/fr/design/gui/icombobox/UIComboBox.java index 350b99eadc..14a90da7b2 100644 --- a/designer_base/src/com/fr/design/gui/icombobox/UIComboBox.java +++ b/designer_base/src/com/fr/design/gui/icombobox/UIComboBox.java @@ -1,214 +1,198 @@ -package com.fr.design.gui.icombobox; - -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 javax.swing.*; -import javax.swing.plaf.ComboBoxUI; -import javax.swing.plaf.basic.ComboPopup; -import java.awt.*; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.Vector; - -/** - * august:非常beautiful的ComboBox,不支持编辑状态. 内容过长时,鼠标移动过去会有ToolTips,不会有横向滚动条 - * 假如支持编辑,因为UIComboBox的TextField 的绘制 并不是靠Renderer来控制 , - * 它会通过paintCurrentValueBackground()来绘制背景, - * 然后通过paintCurrentValue(),去绘制UIComboBox里显示的值。所考虑情况比现在复杂多多多多多了,所以暂时不支持 - * 另外,项的内容最好不要有图标 - * - * @author zhou - * @since 2012-5-9下午3:18:58 - */ -public class UIComboBox extends JComboBox implements UIObserver, GlobalNameObserver { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private static final int SIZE = 20; - - private static final int SIZE5 = 5; - - protected UIObserverListener uiObserverListener; - - private String comboBoxName = ""; - - private GlobalNameListener globalNameListener = null; - - public UIComboBox() { - super(); - init(); - } - - public UIComboBox(ComboBoxModel model) { - super(model); - init(); - } - - public UIComboBox(Object[] items) { - super(items); - init(); - } - - public UIComboBox(Vector items) { - super(items); - init(); - } - - private void init() { - setOpaque(false); - setUI(getUIComboBoxUI()); - setRenderer(new UIComboBoxRenderer()); - setEditor(new UIComboBoxEditor()); - initListener(); - } - - protected void initListener() { - if (shouldResponseChangeListener()) { - this.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - fireSetGlobalName(); - } - }); - this.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (uiObserverListener == null) { - return; - } - fireSetGlobalName(); - if (e.getStateChange() == ItemEvent.SELECTED) { - uiObserverListener.doChange(); - } - } - }); - } - } - - protected void fireSetGlobalName() { - if (globalNameListener != null && shouldResponseNameListener()) { - globalNameListener.setGlobalName(comboBoxName); - } - } - - - protected ComboBoxUI getUIComboBoxUI() { - return new UIComboBoxUI(); - } - - /** - * 只允许设置为UIComboBoxRenderer,所以要继承UIComboBoxRenderer - */ - @Override - public void setRenderer(ListCellRenderer aRenderer) { - if (aRenderer instanceof UIComboBoxRenderer) { - super.setRenderer(aRenderer); - } else { - //throw new IllegalArgumentException("Must be UIComboBoxRenderer"); - } - } - - protected ComboPopup createPopup() { - return null; - } - - public void setGlobalName(String name) { - comboBoxName = name; - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(super.getPreferredSize().width + SIZE5, SIZE);//加5的原因在于:render里,每一个项前面了空了一格,要多几像素 - } - - /** - * 鼠标进入事件 - */ - public void mouseEnterEvent() { - - } - - /** - * 鼠标离开事件 - */ - public void mouseExitEvent() { - - } - - /** - * - */ - public void updateUI() { - setUI(getUIComboBoxUI()); - } - - - /** - * - * @param listener 观察者监听事件 - */ - public void registerChangeListener(UIObserverListener listener) { - uiObserverListener = listener; - } - - public void removeChangeListener(){ - uiObserverListener = null; - } - - public UIObserverListener getUiObserverListener(){ - return uiObserverListener; - } - - /** - * @return - */ - public boolean shouldResponseChangeListener() { - return true; - } - - /** - * - * @param listener 观察者监听事件 - */ - public void registerNameListener(GlobalNameListener listener) { - globalNameListener = listener; - } - - /** - * - * @return - */ - public boolean shouldResponseNameListener() { - return true; - } - - - /** - * @param args - */ - public static void main(String... args) { - LayoutManager layoutManager = null; - JFrame jf = new JFrame("test"); - jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - JPanel content = (JPanel) jf.getContentPane(); - content.setLayout(layoutManager); - UIComboBox bb = new UIComboBox(new String[]{"", "jerry", "kunsnat", "richer"}); - bb.setEditable(true); - bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height); - content.add(bb); - GUICoreUtils.centerWindow(jf); - jf.setSize(400, 400); - jf.setVisible(true); - } - - +package com.fr.design.gui.icombobox; + +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 javax.swing.ComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.ListCellRenderer; +import javax.swing.plaf.ComboBoxUI; +import javax.swing.plaf.basic.ComboPopup; +import java.awt.Dimension; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Vector; + +/** + * august:非常beautiful的ComboBox,不支持编辑状态. 内容过长时,鼠标移动过去会有ToolTips,不会有横向滚动条 + * 假如支持编辑,因为UIComboBox的TextField 的绘制 并不是靠Renderer来控制 , + * 它会通过paintCurrentValueBackground()来绘制背景, + * 然后通过paintCurrentValue(),去绘制UIComboBox里显示的值。所考虑情况比现在复杂多多多多多了,所以暂时不支持 + * 另外,项的内容最好不要有图标 + * + * @author zhou + * @since 2012-5-9下午3:18:58 + */ +public class UIComboBox extends JComboBox implements UIObserver, GlobalNameObserver { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private static final int SIZE = 20; + + private static final int SIZE5 = 5; + + protected UIObserverListener uiObserverListener; + + private String comboBoxName = ""; + + private GlobalNameListener globalNameListener = null; + + public UIComboBox() { + super(); + init(); + } + + public UIComboBox(ComboBoxModel model) { + super(model); + init(); + } + + public UIComboBox(Object[] items) { + super(items); + init(); + } + + public UIComboBox(Vector items) { + super(items); + init(); + } + + private void init() { + setOpaque(false); + setUI(getUIComboBoxUI()); + setRenderer(new UIComboBoxRenderer()); + setEditor(new UIComboBoxEditor()); + initListener(); + } + + protected void initListener() { + if (shouldResponseChangeListener()) { + this.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + fireSetGlobalName(); + } + }); + this.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (uiObserverListener == null) { + return; + } + fireSetGlobalName(); + if (e.getStateChange() == ItemEvent.SELECTED) { + uiObserverListener.doChange(); + } + } + }); + } + } + + protected void fireSetGlobalName() { + if (globalNameListener != null && shouldResponseNameListener()) { + globalNameListener.setGlobalName(comboBoxName); + } + } + + + protected ComboBoxUI getUIComboBoxUI() { + return new UIComboBoxUI(); + } + + /** + * 只允许设置为UIComboBoxRenderer,所以要继承UIComboBoxRenderer + */ + @Override + public void setRenderer(ListCellRenderer aRenderer) { + if (aRenderer instanceof UIComboBoxRenderer) { + super.setRenderer(aRenderer); + } + } + + protected ComboPopup createPopup() { + return null; + } + + @Override + public void setGlobalName(String name) { + comboBoxName = name; + } + + @Override + public Dimension getPreferredSize() { + //加5的原因在于:render里,每一个项前面了空了一格,要多几像素 + return new Dimension(super.getPreferredSize().width + SIZE5, SIZE); + } + + /** + * 鼠标进入事件 + */ + public void mouseEnterEvent() { + + } + + /** + * 鼠标离开事件 + */ + public void mouseExitEvent() { + + } + + /** + * + */ + @Override + public void updateUI() { + setUI(getUIComboBoxUI()); + } + + + /** + * @param listener 观察者监听事件 + */ + @Override + public void registerChangeListener(UIObserverListener listener) { + uiObserverListener = listener; + } + + public void removeChangeListener() { + uiObserverListener = null; + } + + public UIObserverListener getUiObserverListener() { + return uiObserverListener; + } + + /** + * @return 是否响应变更事件 + */ + @Override + public boolean shouldResponseChangeListener() { + return true; + } + + /** + * @param listener 观察者监听事件 + */ + @Override + public void registerNameListener(GlobalNameListener listener) { + globalNameListener = listener; + } + + /** + * @return 是否响应名称事件 + */ + @Override + public boolean shouldResponseNameListener() { + return true; + } + + } \ No newline at end of file