Browse Source

Merge branch 'bugfix/10.0' of ssh://cloud.finedevelop.com:7999/~joe.jiang/design into bugfix/10.0

bugfix/10.0
Joe.Jiang 5 years ago
parent
commit
63ac2590df
  1. 4
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  2. 5
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  3. 39
      designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRWCardTagLayoutAdapter.java
  4. 21
      designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java
  5. 10
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java
  6. 23
      designer-form/src/test/java/com/fr/design/designer/beans/adapters/layout/FRWCardTagLayoutAdapterTest.java
  7. 18
      designer-form/src/test/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayoutTest.java
  8. 147
      designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java
  9. 60
      designer-realize/src/test/java/com/fr/design/mainframe/socketio/DesignerSocketIOTest.java

4
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -14,6 +14,7 @@ import com.fr.design.widget.FRWidgetFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.os.OperatingSystem;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
@ -268,6 +269,9 @@ abstract class UIControlPane extends JControlPane {
addWindowFocusListener(new WindowAdapter() {
@Override
public void windowLostFocus(WindowEvent e) {
if (OperatingSystem.isLinux()) {
requestFocus();
}
hideDialog();
}
});

5
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -458,10 +458,15 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
}
private void refreshContainer() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
validate();
repaint();
revalidate();
}
});
}
public int getToolPaneY() {
return 0;

39
designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRWCardTagLayoutAdapter.java

@ -0,0 +1,39 @@
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
/**
* 针对tabpane的布局适配器
* Created by kerry on 2019-12-10
*/
public class FRWCardTagLayoutAdapter extends AbstractLayoutAdapter {
public FRWCardTagLayoutAdapter(XLayoutContainer container) {
super(container);
}
/**
* 对于这种布局方式不允许其他组件添加
*
* @param creator
* @param x
* @param y
*/
@Override
protected void addComp(XCreator creator, int x, int y) {
}
/**
* 对于这种布局方式不允许其他组件添加
*
* @param creator 组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return
*/
@Override
public boolean accept(XCreator creator, int x, int y) {
return false;
}
}

21
designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java

@ -18,9 +18,7 @@ import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.stable.ArrayUtils;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@ -177,6 +175,22 @@ public class SelectionModel {
}
private void pasteXWFitLayout() {
if (selection.getSelectedCreator().getClass().equals(XWTabFitLayout.class)) {
XLayoutContainer container = (XLayoutContainer) selection.getSelectedCreator();
//tab布局编辑器内部左上角第一个坐标点
int leftUpX = container.toData().getMargin().getLeft() + 1;
int leftUpY = container.toData().getMargin().getTop() + 1;
//选中第一个坐标点坐在的组件
selection.setSelectedCreator((XCreator) container.getComponentAt(leftUpX, leftUpY));
Rectangle rectangle = selection.getRelativeBounds();
if (hasSelectedPasteSource()) {
selectedPaste();
} else {
FormSelectionUtils.paste2Container(designer, container, clipboard,
rectangle.x + rectangle.width / 2,
rectangle.y + DELTA_X_Y);
}
} else {
//自适应布局编辑器内部左上角第一个坐标点
int leftUpX = designer.getRootComponent().toData().getMargin().getLeft() + 1;
int leftUpY = designer.getRootComponent().toData().getMargin().getTop() + 1;
@ -192,6 +206,7 @@ public class SelectionModel {
rectangle.y + DELTA_X_Y);
}
}
}
/**
* 粘贴时选择组件

10
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java

@ -8,8 +8,7 @@ import com.fr.base.ScreenResolution;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.ComponentAdapter;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRHorizontalLayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRVerticalLayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRWCardTagLayoutAdapter;
import com.fr.design.designer.beans.models.SelectionModel;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
@ -311,12 +310,7 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout {
@Override
public LayoutAdapter getLayoutAdapter() {
if (isHori()) {
return new FRHorizontalLayoutAdapter(this);
}else{
return new FRVerticalLayoutAdapter(this);
}
return new FRWCardTagLayoutAdapter(this);
}
private boolean isHori(){

23
designer-form/src/test/java/com/fr/design/designer/beans/adapters/layout/FRWCardTagLayoutAdapterTest.java

@ -0,0 +1,23 @@
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.designer.creator.XElementCase;
import com.fr.design.designer.creator.cardlayout.XWCardTagLayout;
import com.fr.form.ui.ElementCaseEditor;
import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import org.junit.Assert;
import org.junit.Test;
import java.awt.Dimension;
/**
* Created by kerry on 2019-12-10
*/
public class FRWCardTagLayoutAdapterTest {
@Test
public void testAccept() {
FRWCardTagLayoutAdapter adapter = new FRWCardTagLayoutAdapter(
new XWCardTagLayout(new WCardTagLayout(), new Dimension(100, 100)));
Assert.assertFalse(adapter.accept(new XElementCase(
new ElementCaseEditor(), new Dimension(100, 100)), 1, 1));
}
}

18
designer-form/src/test/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayoutTest.java

@ -0,0 +1,18 @@
package com.fr.design.designer.creator.cardlayout;
import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import org.junit.Assert;
import org.junit.Test;
import java.awt.Dimension;
/**
* Created by kerry on 2019-12-10
*/
public class XWCardTagLayoutTest {
@Test
public void testGetLayoutAdapter() {
XWCardTagLayout tagLayout = new XWCardTagLayout(new WCardTagLayout(), new Dimension(100, 100));
Assert.assertEquals("com.fr.design.designer.beans.adapters.layout.FRWCardTagLayoutAdapter", tagLayout.getLayoutAdapter().getClass().getName());
}
}

147
designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

@ -13,7 +13,6 @@ import com.fr.report.RemoteDesignConstants;
import com.fr.serialization.SerializerHelper;
import com.fr.stable.ArrayUtils;
import com.fr.third.apache.log4j.spi.LoggingEvent;
import com.fr.third.guava.base.Optional;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.base.WorkspaceConstants;
@ -36,28 +35,19 @@ public class DesignerSocketIO {
Disconnecting
}
private static Optional<Socket> socketIO = Optional.absent();
private static Socket socket = null;
private static Status status = Status.Disconnected;
//维护一个当前工作环境的uri列表
private static String[] uri;
//维护一个关于uri列表的计数器
private static int count;
private static final Emitter.Listener printLog = new Emitter.Listener() {
@Override
public void call(Object... objects) {
if (ArrayUtils.isNotEmpty(objects)) {
try {
LoggingEvent event = SerializerHelper.deserialize((byte[]) objects[0]);
DesignerLogger.log(event);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
};
public static void close() {
if (socketIO.isPresent()) {
if (socket != null) {
status = Status.Disconnecting;
socketIO.get().close();
socketIO = Optional.absent();
socket.close();
socket = null;
}
}
@ -66,24 +56,90 @@ public class DesignerSocketIO {
if (current.isLocal()) {
return;
}
//每当更换工作环境,更新uri列表,同时更新计数器count
try {
uri = getSocketUri();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
count = 0;
//建立socket并注册监听
createSocket();
}
private static void createSocket(){
//根据uri和计数器建立连接,并注册监听
try {
String[] uri = getSocketUri(current);
socketIO = Optional.of(IO.socket(new URI(uri[0])));
socketIO.get().on(WorkspaceConstants.WS_LOGRECORD, printLog);
socketIO.get().on(WorkspaceConstants.CONFIG_MODIFY, new Emitter.Listener() {
if(count<uri.length) {
socket = IO.socket(new URI(uri[count]));
socket.on(WorkspaceConstants.WS_LOGRECORD, printLog);
socket.on(WorkspaceConstants.CONFIG_MODIFY, modifyConfig);
socket.on(Socket.EVENT_CONNECT_ERROR, failRetry);
socket.on(Socket.EVENT_DISCONNECT, disConnectHint);
socket.connect();
status = Status.Connected;
}else {
//表示所有的uri都连接不成功
FineLoggerFactory.getLogger().warn("All uris failed to connect");
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private static String[] getSocketUri() throws IOException {
Workspace current = WorkContext.getCurrent();
URL url = new URL(current.getPath());
Integer[] ports = current.get(SocketInfoOperator.class).getPort();
WorkspaceConnection connection = current.getConnection();
String[] result = new String[ports.length];
for (int i = 0; i < ports.length; i++) {
result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s",
url.getProtocol(),
url.getHost(),
ports[i],
WorkspaceConstants.WS_NAMESPACE,
DecisionServiceConstants.WEB_SOCKET_TOKEN_NAME,
connection.getToken(),
RemoteDesignConstants.USER_LOCK_ID,
connection.getId());
}
return result;
}
//失败重试监听器:1、关闭失败的socket 2、计数器加1 3、调用创建socket方法
private static final Emitter.Listener failRetry = new Emitter.Listener() {
@Override
public void call(Object... args) {
status = Status.Disconnecting;
socket.close();
count++;
createSocket();
}
};
//日志输出监听器
private static final Emitter.Listener printLog = new Emitter.Listener() {
@Override
public void call(Object... objects) {
assert objects != null && objects.length == 1;
String param = (String) objects[0];
EventDispatcher.fire(RemoteConfigEvent.EDIT, param);
if (ArrayUtils.isNotEmpty(objects)) {
try {
LoggingEvent event = SerializerHelper.deserialize((byte[]) objects[0]);
DesignerLogger.log(event);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
});
socketIO.get().on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
}
}
};
//断开连接提醒监听器
private static final Emitter.Listener disConnectHint = new Emitter.Listener() {
@Override
public void call(Object... objects) {
/*
* todo 远程心跳断开不一定 socketio 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
* socketio 只用推日志和通知配置变更
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
* socket 只用推日志和通知配置变更
*/
if (status != Status.Disconnecting) {
try {
@ -105,31 +161,16 @@ public class DesignerSocketIO {
}
status = Status.Disconnected;
}
});
socketIO.get().connect();
status = Status.Connected;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
};
private static String[] getSocketUri(Workspace current) throws IOException {
URL url = new URL(current.getPath());
Integer[] ports = WorkContext.getCurrent().get(SocketInfoOperator.class).getPort();
WorkspaceConnection connection = WorkContext.getCurrent().getConnection();
String[] result = new String[ports.length];
for (int i = 0; i < ports.length; i++) {
result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s",
url.getProtocol(),
url.getHost(),
ports[i],
WorkspaceConstants.WS_NAMESPACE,
DecisionServiceConstants.WEB_SOCKET_TOKEN_NAME,
connection.getToken(),
RemoteDesignConstants.USER_LOCK_ID,
connection.getId());
//配置变更监听器
private static final Emitter.Listener modifyConfig = new Emitter.Listener() {
@Override
public void call(Object... objects) {
assert objects != null && objects.length == 1;
String param = (String) objects[0];
EventDispatcher.fire(RemoteConfigEvent.EDIT, param);
}
return result;
};
}
}

60
designer-realize/src/test/java/com/fr/design/mainframe/socketio/DesignerSocketIOTest.java

@ -0,0 +1,60 @@
package com.fr.design.mainframe.socketio;
import com.fr.invoke.Reflect;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import io.socket.client.IO;
import io.socket.client.Socket;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* @author: Maksim
* @Date: Created in 2019/12/9
* @Description:
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({WorkContext.class,DesignerSocketIO.class, IO.class})
public class DesignerSocketIOTest {
@Test
public void close() throws Exception {
this.update();
DesignerSocketIO.close();
DesignerSocketIO.Status status = Reflect.on(DesignerSocketIO.class).field("status").get();
Socket socket = Reflect.on(DesignerSocketIO.class).field("socket").get();
Assert.assertEquals(DesignerSocketIO.Status.Disconnecting,status);
Assert.assertNull(socket);
}
@Test
public void update() throws Exception {
Workspace current = EasyMock.mock(Workspace.class);
EasyMock.expect(current.isLocal()).andReturn(false);
PowerMock.mockStatic(WorkContext.class);
EasyMock.expect(WorkContext.getCurrent()).andReturn(current);
String[] uri = {"http://127.0.0.1:8888/workspace","http://127.0.0.1:9999/workspace"};
PowerMock.mockStaticPartial(DesignerSocketIO.class,"getSocketUri");
PowerMock.expectPrivate(DesignerSocketIO.class,"getSocketUri").andReturn(uri);
EasyMock.replay(current);
PowerMock.replayAll();
DesignerSocketIO.update();
DesignerSocketIO.Status status = Reflect.on(DesignerSocketIO.class).field("status").get();
Socket socket = Reflect.on(DesignerSocketIO.class).field("socket").get();
Assert.assertEquals(DesignerSocketIO.Status.Connected,status);
Assert.assertNotNull(socket);
}
}
Loading…
Cancel
Save