diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index fce7832ac..6460cadb9 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -1,6 +1,7 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; +import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.DBUtils; import com.fr.data.core.db.TableProcedure; @@ -17,7 +18,7 @@ import com.fr.design.data.datapane.preview.PreviewLabel.Previewable; import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.data.tabledata.Prepare4DataSourceChange; import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.icombobox.FRTreeComboBox; +import com.fr.design.gui.icombobox.SearchPreTaskTreeComboBox; import com.fr.design.gui.icombobox.FilterableComboBoxModel; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxEditor; @@ -59,6 +60,10 @@ import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; /** * @author zhou @@ -80,21 +85,25 @@ public class ChoosePane extends BasicBeanPane implements Refresha /** * 表名 */ - protected FRTreeComboBox tableNameComboBox; + protected SearchPreTaskTreeComboBox tableNameComboBox; private SwingWorker populateWorker; + private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new NamedThreadFactory("ChoosePaneThread")); private PopupMenuListener popupMenuListener = new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - new Thread() { + FutureTask task = new FutureTask(new Callable() { @Override - public void run() { + public Object call() { calculateTableDataNames(); + return null; } - }.start(); + }); + SERVICE.submit(task); + tableNameComboBox.setPreSearchTask(task); } @Override @@ -158,7 +167,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha schemaBox = new StringUIComboBox(); schemaBox.setEditor(new ComboBoxEditor()); - tableNameComboBox = new FRTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); + tableNameComboBox = new SearchPreTaskTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); tableNameComboBox.setEditable(true); tableNameComboBox.setRenderer(listCellRenderer); registerDSChangeListener(); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java index 4bf6bf190..c47a0d75c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java @@ -99,6 +99,9 @@ public class JDBCDefPane extends JPanel { private IntegerEditor DBCP_NUMTESTSPEREVICTIONRUN = new IntegerEditor(); private IntegerEditor DBCP_MINEVICTABLEIDLETIMEMILLIS = new IntegerEditor(); + private JDBCDatabaseConnection jdbcDatabase; + private boolean needRefresh = true; + public JDBCDefPane() { this.setBorder(UITitledBorder.createBorderWithTitle("JDBC" + ":")); this.setLayout(FRGUIPaneFactory.createLabelFlowLayout()); @@ -199,9 +202,11 @@ public class JDBCDefPane extends JPanel { } public void populate(JDBCDatabaseConnection jdbcDatabase) { + needRefresh = false; if (jdbcDatabase == null) { jdbcDatabase = new JDBCDatabaseConnection(); } + this.jdbcDatabase = jdbcDatabase; if (ComparatorUtils.equals(jdbcDatabase.getDriver(), "sun.jdbc.odbc.JdbcOdbcDriver") && jdbcDatabase.getURL().startsWith("jdbc:odbc:Driver={Microsoft")) { this.dbtypeComboBox.setSelectedItem("Access"); @@ -235,6 +240,7 @@ public class JDBCDefPane extends JPanel { if (dbcpAttr == null) { dbcpAttr = new DBCPConnectionPoolAttr(); jdbcDatabase.setDbcpAttr(dbcpAttr); + this.jdbcDatabase.setDbcpAttr(dbcpAttr); } this.DBCP_INITIAL_SIZE.setValue(dbcpAttr.getInitialSize()); this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive()); @@ -248,10 +254,13 @@ public class JDBCDefPane extends JPanel { this.DBCP_MINEVICTABLEIDLETIMEMILLIS.setValue(dbcpAttr.getMinEvictableIdleTimeMillis() / TIME_MULTIPLE); this.DBCP_NUMTESTSPEREVICTIONRUN.setValue(dbcpAttr.getNumTestsPerEvictionRun()); this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.setValue(dbcpAttr.getTimeBetweenEvictionRunsMillis()); + needRefresh = true; } public JDBCDatabaseConnection update() { - JDBCDatabaseConnection jdbcDatabase = new JDBCDatabaseConnection(); + if (jdbcDatabase == null) { + jdbcDatabase = new JDBCDatabaseConnection(); + } Object driveItem = this.driverComboBox.getSelectedItem(); jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString()); jdbcDatabase.setURL(this.urlTextField.getText().trim()); @@ -297,6 +306,10 @@ public class JDBCDefPane extends JPanel { urlTextField.setText(dus[i].getURL()); } } + // 更改数据库类型后 数据库名称置空和之前逻辑保持一致 + if (needRefresh) { + jdbcDatabase.setDatabase(StringUtils.EMPTY); + } } }; diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java index a7a913335..f0c60d2e8 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java @@ -597,6 +597,10 @@ public class FRTreeComboBox extends UIComboBox { return this.item; } + public boolean isSetting() { + return setting; + } + public void insertUpdate(DocumentEvent e) { changeHandler(); } @@ -614,11 +618,18 @@ public class FRTreeComboBox extends UIComboBox { return; } setPopupVisible(true); + search(); + } + + /** + * 模糊搜索,选中首个匹配项 + */ + protected void search() { this.item = textField.getText(); TreeNode root = (TreeNode) tree.getModel().getRoot(); TreePath parent = new TreePath(root); TreeNode node = (TreeNode) parent.getLastPathComponent(); - dealSamePath(parent,node,textField); + dealSamePath(parent, node, textField); this.getEditorComponent().requestFocus(); } diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java new file mode 100644 index 000000000..9ee2a5949 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java @@ -0,0 +1,79 @@ +package com.fr.design.gui.icombobox; + +import com.fr.design.ui.util.UIUtil; +import com.fr.log.FineLoggerFactory; + +import javax.swing.JTree; +import javax.swing.SwingWorker; +import javax.swing.tree.TreeCellRenderer; +import java.util.concurrent.FutureTask; + +/** + * 模糊搜索前需执行完前置任务的TreeComboBox + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2021/4/14 + */ +public class SearchPreTaskTreeComboBox extends FRTreeComboBox { + + /** + * 模糊搜索前任务 + */ + private FutureTask preSearchTask; + + public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { + super(tree, renderer, editable); + } + + public FutureTask getPreSearchTask() { + return preSearchTask; + } + + public void setPreSearchTask(FutureTask preSearchTask) { + this.preSearchTask = preSearchTask; + } + + protected UIComboBoxEditor createEditor() { + return new SearchPreTaskComboBoxEditor(this); + } + + private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor { + + public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) { + super(comboBox); + } + + protected void changeHandler() { + if (isSetting()) { + return; + } + setPopupVisible(true); + // 模糊搜索异步 + new SwingWorker() { + @Override + protected Void doInBackground() { + FutureTask task = getPreSearchTask(); + try { + // 确保模糊搜索前任务执行完成后,再进行模糊搜索 + if (task != null) { + task.get(); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (task != null) { + // 任务执行后置空,否则会被别的操作重复触发 + setPreSearchTask(null); + } + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + search(); + } + }); + return null; + } + }.execute(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 43c3f43ad..1f4f331d8 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -1158,7 +1158,7 @@ public class FILEChooserPane extends BasicPane { }; } if (FILEChooserPane.this.showWebReport) { - webReportFILE = new FileNodeFILE(FRContext.getCommonOperator().getWebRootPath()); + webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); } if (FILEChooserPane.this.showLoc) { processSystemFile(); @@ -1219,7 +1219,7 @@ public class FILEChooserPane extends BasicPane { } if (FILEChooserPane.this.showWebReport) { - webReportFILE = new FileNodeFILE(FRContext.getCommonOperator().getWebRootPath()); + webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); } if (FILEChooserPane.this.showLoc) { processSystemFile(); diff --git a/designer-base/src/main/java/com/fr/file/FILEFactory.java b/designer-base/src/main/java/com/fr/file/FILEFactory.java index 5a19108ee..3d48bab34 100644 --- a/designer-base/src/main/java/com/fr/file/FILEFactory.java +++ b/designer-base/src/main/java/com/fr/file/FILEFactory.java @@ -32,7 +32,7 @@ public class FILEFactory { return new FileNodeFILE(new FileNode(path.substring(envPath.length() + 1), false)); } else if (path.startsWith(WEBREPORT_PREFIX)) { return new FileNodeFILE(new FileNode(path.substring(WEBREPORT_PREFIX.length()), false), - FRContext.getCommonOperator().getWebRootPath()); + FileNodeFILE.webRootPath); } else if (path.startsWith(FILE_PREFIX)) { return new FileFILE(new java.io.File(path.substring(FILE_PREFIX.length()))); } else { @@ -50,7 +50,7 @@ public class FILEFactory { fixFILENodeAuth(new FileNode(path.substring(ENV_PREFIX.length()), true)); } else if (path.startsWith(WEBREPORT_PREFIX)) { return new FileNodeFILE(new FileNode(path.substring(WEBREPORT_PREFIX.length()), true), - FRContext.getCommonOperator().getWebRootPath()); + FileNodeFILE.webRootPath); } else if (path.startsWith(FILE_PREFIX)) { return new FileFILE(new java.io.File(path.substring(FILE_PREFIX.length()))); } else { diff --git a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java index d096faf8a..bcf1ff768 100644 --- a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java +++ b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java @@ -32,7 +32,7 @@ import java.util.Arrays; public class FileNodeFILE implements FILE { - private static String webRootPath = FRContext.getCommonOperator().getWebRootPath(); + public static String webRootPath = FRContext.getCommonOperator().getWebRootPath(); private static String[] supportTypes = FRContext.getFileNodes().getSupportedTypes(); static { diff --git a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg index 2d64f68f7..217f23e15 100644 --- a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg +++ b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg @@ -1,5 +1,5 @@ - + icon_报表web属性_打印预览_normal diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index c0eb39297..22d74d774 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -347,15 +347,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { //拖拽组件原大小、位置 Rectangle backupBound = creator.getBackupBound(); backupBound.x -= container.getX(); - // REPORT-34739 对绝对画布块的backupBound.y的调整还需要考虑一下参数面板块的高度造成的偏移 - int paraHeight = 0; - if (creator.acceptType(XWAbsoluteLayout.class)) { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jTemplate instanceof JForm) { - paraHeight = ((JForm) jTemplate).getFormDesign().getParaHeight(); - } - } - backupBound.y -= (container.getY() - paraHeight); + backupBound.y -= container.getY(); //当前拖拽组件的位置 int x = creator.getX(); int y = creator.getY(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java index cbebbcba1..97228209a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java @@ -12,6 +12,7 @@ import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; @@ -270,7 +271,9 @@ public class FormSelection { LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator); if (layoutAdapter != null) { if (creator.acceptType(XWAbsoluteLayout.class) && recs.size() > i) { - creator.setBackupBound(recs.get(i)); + Rectangle rectangle = recs.get(i); + check4ParaPane(rectangle); + creator.setBackupBound(rectangle); } else { creator.setBackupBound(backupBounds); } @@ -280,6 +283,19 @@ public class FormSelection { } } + /** + * 检查下有没有参数面板,如果存在,处理下参数面板造成的偏移量 + * @param rectangle + */ + private void check4ParaPane(Rectangle rectangle) { + int paraHeight = 0; + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jTemplate instanceof JForm) { + paraHeight = ((JForm) jTemplate).getFormDesign().getParaHeight(); + } + rectangle.y += paraHeight; + } + private void removeCreatorFromContainer(XCreator creator) { XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator); if (parent == null) {