forked from fanruan/design
Harrison
5 years ago
13 changed files with 574 additions and 42 deletions
@ -0,0 +1,53 @@
|
||||
package com.fr.design.base.clipboard; |
||||
|
||||
import com.fr.design.fun.ClipboardHandlerProvider; |
||||
import com.fr.form.main.ExtraFormClassManager; |
||||
import com.fr.plugin.injectable.PluginModule; |
||||
|
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/14 |
||||
**/ |
||||
@SuppressWarnings({"rawtypes", "unchecked"}) |
||||
public abstract class ClipboardFilter { |
||||
|
||||
public static <T> T cut(T selection) { |
||||
|
||||
Class<?> clazz = selection.getClass(); |
||||
ExtraFormClassManager manager = PluginModule.getAgent(PluginModule.ExtraForm); |
||||
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG); |
||||
for (ClipboardHandlerProvider provider : providers) { |
||||
if (provider.support(clazz)) { |
||||
selection = ((ClipboardHandlerProvider<T>) provider).cut(selection); |
||||
} |
||||
} |
||||
return selection; |
||||
} |
||||
|
||||
public static <T> T copy(T selection) { |
||||
|
||||
Class<?> clazz = selection.getClass(); |
||||
ExtraFormClassManager manager = PluginModule.getAgent(PluginModule.ExtraForm); |
||||
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG); |
||||
for (ClipboardHandlerProvider provider : providers) { |
||||
if (provider.support(clazz)) { |
||||
selection = ((ClipboardHandlerProvider<T>) provider).copy(selection); |
||||
} |
||||
} |
||||
return selection; |
||||
} |
||||
|
||||
public static <T> T paste(T selection) { |
||||
|
||||
Class<?> clazz = selection.getClass(); |
||||
ExtraFormClassManager manager = PluginModule.getAgent(PluginModule.ExtraForm); |
||||
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG); |
||||
for (ClipboardHandlerProvider provider : providers) { |
||||
if (provider.support(clazz)) { |
||||
selection = ((ClipboardHandlerProvider<T>) provider).paste(selection); |
||||
} |
||||
} |
||||
return selection; |
||||
} |
||||
} |
@ -0,0 +1,68 @@
|
||||
package com.fr.design.base.clipboard; |
||||
|
||||
import java.awt.datatransfer.Clipboard; |
||||
import java.awt.datatransfer.ClipboardOwner; |
||||
import java.awt.datatransfer.DataFlavor; |
||||
import java.awt.datatransfer.FlavorListener; |
||||
import java.awt.datatransfer.Transferable; |
||||
import java.awt.datatransfer.UnsupportedFlavorException; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/11 |
||||
**/ |
||||
public class DesignerClipboard extends Clipboard { |
||||
|
||||
private Clipboard clipboard; |
||||
|
||||
public DesignerClipboard(Clipboard clipboard) { |
||||
super(clipboard.getName()); |
||||
this.clipboard = clipboard; |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void setContents(Transferable contents, ClipboardOwner owner) { |
||||
//处理 contents/owner
|
||||
Transferable filtered = ClipboardFilter.copy(contents); |
||||
clipboard.setContents(filtered, owner); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized Transferable getContents(Object requestor) { |
||||
Transferable contents = clipboard.getContents(requestor); |
||||
//处理 contents
|
||||
Transferable filtered = ClipboardFilter.paste(contents); |
||||
return filtered; |
||||
} |
||||
|
||||
@Override |
||||
public DataFlavor[] getAvailableDataFlavors() { |
||||
return clipboard.getAvailableDataFlavors(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isDataFlavorAvailable(DataFlavor flavor) { |
||||
return clipboard.isDataFlavorAvailable(flavor); |
||||
} |
||||
|
||||
@Override |
||||
public Object getData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { |
||||
return clipboard.getData(flavor); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void addFlavorListener(FlavorListener listener) { |
||||
clipboard.addFlavorListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void removeFlavorListener(FlavorListener listener) { |
||||
clipboard.removeFlavorListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized FlavorListener[] getFlavorListeners() { |
||||
return clipboard.getFlavorListeners(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package com.fr.design.fun; |
||||
|
||||
import com.fr.stable.fun.mark.Mutable; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/14 |
||||
**/ |
||||
public interface ClipboardHandlerProvider<T> extends Mutable { |
||||
|
||||
String XML_TAG = "ClipboardHandlerProvider"; |
||||
|
||||
int CURRENT_LEVEL = 1; |
||||
|
||||
/** |
||||
* 剪切 |
||||
* |
||||
* @param selection 选中 |
||||
* @return 处理后的内容 |
||||
*/ |
||||
T cut(T selection); |
||||
|
||||
/** |
||||
* 复制 |
||||
* |
||||
* @param selection 选中 |
||||
* @return 处理后的内容 |
||||
*/ |
||||
T copy(T selection); |
||||
|
||||
/** |
||||
* 粘贴 |
||||
* |
||||
* @param selection 选中 |
||||
* @return 处理后的内容 |
||||
*/ |
||||
T paste(T selection); |
||||
|
||||
/** |
||||
* 支持的类型 |
||||
* |
||||
* @param selection 内容 |
||||
* @return 是否 |
||||
*/ |
||||
boolean support(Object selection); |
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.design.fun.ClipboardHandlerProvider; |
||||
import com.fr.stable.fun.impl.AbstractProvider; |
||||
import com.fr.stable.fun.mark.API; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/14 |
||||
**/ |
||||
@API(level = ClipboardHandlerProvider.CURRENT_LEVEL) |
||||
public abstract class AbstractClipboardHandlerProvider<T> extends AbstractProvider implements ClipboardHandlerProvider<T> { |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return ClipboardHandlerProvider.CURRENT_LEVEL; |
||||
} |
||||
} |
@ -0,0 +1,62 @@
|
||||
package com.fr.design.base.clipboard; |
||||
|
||||
import com.fr.design.fun.ClipboardHandlerProvider; |
||||
import com.fr.form.main.ExtraFormClassManager; |
||||
import com.fr.plugin.injectable.PluginModule; |
||||
import com.fr.stable.fun.mark.Mutable; |
||||
import org.easymock.EasyMock; |
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
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; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
@PrepareForTest(PluginModule.class) |
||||
@RunWith(PowerMockRunner.class) |
||||
public class ClipboardFilterTest { |
||||
|
||||
|
||||
@Before |
||||
public void setUp() throws Exception { |
||||
|
||||
Set<Mutable> providers = new HashSet<>(); |
||||
providers.add(new TestClipboardHandlerProvider<Object>()); |
||||
|
||||
ExtraFormClassManager formClassManager = EasyMock.mock(ExtraFormClassManager.class); |
||||
EasyMock.expect(formClassManager.getArray(ClipboardHandlerProvider.XML_TAG)) |
||||
.andReturn(providers) |
||||
.anyTimes(); |
||||
EasyMock.replay(formClassManager); |
||||
|
||||
PowerMock.mockStatic(PluginModule.class); |
||||
EasyMock.expect(PluginModule.getAgent(PluginModule.ExtraForm)) |
||||
.andReturn(formClassManager) |
||||
.anyTimes(); |
||||
PowerMock.replayAll(); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() throws Exception { |
||||
|
||||
PowerMock.resetAll(); |
||||
} |
||||
|
||||
@Test |
||||
public void testClipboard() { |
||||
|
||||
ClipboardFilter.cut("cut"); |
||||
String paste1 = ClipboardFilter.paste("paste"); |
||||
Assert.assertNull(paste1); |
||||
|
||||
ClipboardFilter.copy("copy"); |
||||
String paste2 = ClipboardFilter.paste("paste"); |
||||
Assert.assertNull(paste2); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,75 @@
|
||||
package com.fr.design.base.clipboard; |
||||
|
||||
import com.fr.design.fun.ClipboardHandlerProvider; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.dnd.ArrayListTransferable; |
||||
import com.fr.form.main.ExtraFormClassManager; |
||||
import com.fr.plugin.injectable.PluginModule; |
||||
import com.fr.stable.fun.mark.Mutable; |
||||
import com.fr.third.guava.collect.Lists; |
||||
import org.easymock.EasyMock; |
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.powermock.api.easymock.PowerMock; |
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.datatransfer.Clipboard; |
||||
import java.awt.datatransfer.DataFlavor; |
||||
import java.awt.datatransfer.Transferable; |
||||
import java.util.ArrayList; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
@PrepareForTest(PluginModule.class) |
||||
@RunWith(PowerMockRunner.class) |
||||
@PowerMockIgnore("javax.swing.*") |
||||
public class DesignerClipboardTest { |
||||
|
||||
@Before |
||||
public void setUp() throws Exception { |
||||
|
||||
Set<Mutable> providers = new HashSet<>(); |
||||
|
||||
ExtraFormClassManager formClassManager = EasyMock.mock(ExtraFormClassManager.class); |
||||
EasyMock.expect(formClassManager.getArray(ClipboardHandlerProvider.XML_TAG)) |
||||
.andReturn(providers) |
||||
.anyTimes(); |
||||
EasyMock.replay(formClassManager); |
||||
|
||||
PowerMock.mockStatic(PluginModule.class); |
||||
EasyMock.expect(PluginModule.getAgent(PluginModule.ExtraForm)) |
||||
.andReturn(formClassManager) |
||||
.anyTimes(); |
||||
PowerMock.replayAll(); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() throws Exception { |
||||
|
||||
PowerMock.resetAll(); |
||||
} |
||||
|
||||
@Test |
||||
public void testClipboard() throws Exception { |
||||
|
||||
JPanel panel = new JPanel(); |
||||
Clipboard clipboard = DesignerContext.getClipboard(panel); |
||||
|
||||
ArrayList<String> transferData = Lists.newArrayList("test", "test2"); |
||||
ArrayListTransferable transferable = new ArrayListTransferable(transferData); |
||||
clipboard.setContents(transferable, null); |
||||
|
||||
Transferable filterTransferable = clipboard.getContents(null); |
||||
DataFlavor[] flavors = transferable.getTransferDataFlavors(); |
||||
ArrayList<String> transferData2 = (ArrayList<String>) filterTransferable.getTransferData(flavors[0]); |
||||
|
||||
Assert.assertEquals(transferData.get(0), transferData2.get(0)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,29 @@
|
||||
package com.fr.design.base.clipboard; |
||||
|
||||
import com.fr.design.fun.impl.AbstractClipboardHandlerProvider; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/15 |
||||
**/ |
||||
class TestClipboardHandlerProvider<T> extends AbstractClipboardHandlerProvider<T> { |
||||
|
||||
@Override |
||||
public T cut(T selection) { |
||||
return selection; |
||||
} |
||||
|
||||
@Override |
||||
public T copy(T selection) { |
||||
return selection; |
||||
} |
||||
|
||||
@Override |
||||
public T paste(T selection) { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public boolean support(Object selection) { |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,22 @@
|
||||
package com.fr.design.fun; |
||||
|
||||
import com.fr.design.designer.beans.events.DesignerEvent; |
||||
import com.fr.stable.fun.mark.Mutable; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/14 |
||||
**/ |
||||
public interface DesignerEditListenerProvider extends Mutable { |
||||
|
||||
String XML_TAG = "DesignerEditListenerProvider"; |
||||
|
||||
int CURRENT_LEVEL = 1; |
||||
|
||||
/** |
||||
* 触发设计器事件 |
||||
* |
||||
* @param evt 事件 |
||||
*/ |
||||
void fireCreatorModified(DesignerEvent evt); |
||||
|
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.design.fun.DesignerEditListenerProvider; |
||||
import com.fr.stable.fun.impl.AbstractProvider; |
||||
import com.fr.stable.fun.mark.API; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/05/14 |
||||
**/ |
||||
@API(level = DesignerEditListenerProvider.CURRENT_LEVEL) |
||||
public abstract class AbstractDesignerEditListenerProvider extends AbstractProvider implements DesignerEditListenerProvider { |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return DesignerEditListenerProvider.CURRENT_LEVEL; |
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
package com.fr.design.designer.beans.models; |
||||
|
||||
import com.fr.design.designer.beans.events.CreatorEventListenerTable; |
||||
import com.fr.design.designer.creator.XCreator; |
||||
import com.fr.design.fun.ClipboardHandlerProvider; |
||||
import com.fr.design.fun.impl.AbstractClipboardHandlerProvider; |
||||
import com.fr.design.mainframe.FormDesigner; |
||||
import com.fr.form.main.ExtraFormClassManager; |
||||
import com.fr.plugin.injectable.PluginModule; |
||||
import com.fr.stable.fun.mark.Mutable; |
||||
import org.easymock.EasyMock; |
||||
import org.easymock.IAnswer; |
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.powermock.api.easymock.PowerMock; |
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
import org.powermock.reflect.Whitebox; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
@PrepareForTest(PluginModule.class) |
||||
@SuppressStaticInitializationFor({"com.fr.design.mainframe.FormDesigner"}) |
||||
@PowerMockIgnore("javax.swing.*") |
||||
@RunWith(PowerMockRunner.class) |
||||
public class SelectionModelTest { |
||||
|
||||
@Before |
||||
public void setUp() throws Exception { |
||||
|
||||
AbstractClipboardHandlerProvider provider = EasyMock.mock(AbstractClipboardHandlerProvider.class); |
||||
EasyMock.expect(provider.cut(EasyMock.anyObject())).andAnswer(new IAnswer<Object>() { |
||||
@Override |
||||
public Object answer() throws Throwable { |
||||
return null; |
||||
} |
||||
}).anyTimes(); |
||||
EasyMock.expect(provider.copy(EasyMock.anyObject())).andAnswer(new IAnswer<Object>() { |
||||
@Override |
||||
public Object answer() throws Throwable { |
||||
return EasyMock.getCurrentArguments()[0]; |
||||
} |
||||
}).anyTimes(); |
||||
EasyMock.expect(provider.support(EasyMock.anyObject())).andReturn(true).anyTimes(); |
||||
EasyMock.expect(provider.paste(EasyMock.anyObject())).andReturn(null).anyTimes(); |
||||
EasyMock.replay(provider); |
||||
|
||||
Set<Mutable> providers = new HashSet<>(); |
||||
providers.add(provider); |
||||
|
||||
ExtraFormClassManager formClassManager = EasyMock.mock(ExtraFormClassManager.class); |
||||
EasyMock.expect(formClassManager.getArray(ClipboardHandlerProvider.XML_TAG)) |
||||
.andReturn(providers) |
||||
.anyTimes(); |
||||
EasyMock.expect(formClassManager.getArray("DesignerEditListenerProvider")) |
||||
.andReturn(new HashSet<Mutable>()) |
||||
.anyTimes(); |
||||
|
||||
|
||||
EasyMock.replay(formClassManager); |
||||
|
||||
PowerMock.mockStatic(PluginModule.class); |
||||
EasyMock.expect(PluginModule.getAgent(PluginModule.ExtraForm)) |
||||
.andReturn(formClassManager) |
||||
.anyTimes(); |
||||
PowerMock.replayAll(); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() throws Exception { |
||||
|
||||
PowerMock.resetAll(); |
||||
} |
||||
|
||||
@Test |
||||
public void testPaste() { |
||||
|
||||
FormDesigner formDesigner = EasyMock.partialMockBuilder(FormDesigner.class).createMock(); |
||||
XCreator xCreator = EasyMock.mock(XCreator.class); |
||||
EasyMock.expect(xCreator.acceptType(EasyMock.anyObject(Class[].class))).andReturn(true).anyTimes(); |
||||
CreatorEventListenerTable table = new CreatorEventListenerTable(); |
||||
Whitebox.setInternalState(formDesigner, "edit", table); |
||||
EasyMock.replay(formDesigner, xCreator); |
||||
|
||||
SelectionModel model = new SelectionModel(formDesigner); |
||||
model.cutSelectedCreator2ClipBoard(); |
||||
boolean paste1 = model.pasteFromClipBoard(); |
||||
Assert.assertFalse(paste1); |
||||
|
||||
model.setSelectedCreator(xCreator); |
||||
model.copySelectedCreator2ClipBoard(); |
||||
boolean paste2 = model.pasteFromClipBoard(); |
||||
Assert.assertFalse(paste2); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue