在IDEA插件开发中,Anaction是一个很重要的接口,一般在设计上也不应该与其他组件耦合在一起。因此,一个action往往是可以独立存在于任意地方的。那么问题就来了,一个action在运行时如何获取当前相关的组件呢?
AnAction是基于事件驱动设计的,因此在运行的时候,有一个AnActionEvent的实例才触发。AnActionEvent中有两个方法:
T getRequiredData(DataKey key)
T getData(DataKey key)
这个两个方法会去调用当前事件触发点所在组件及其所有父组件上DataProvider的getData方法。
先看看DataProvider接口的申明
public interface DataProvider{
Object getData(@NotNull @NonNls String dataId);
}
我们只需要定义一个DataKey, 然后实现DataProvider接口即可实现组件与行为的解耦。
实例
-
先创建一个组件,定义一个DataKey并实现DataProvider:
public class TestPanel extends JPanel implement DataProvider { public static final DataKey
TEST_KEY = DataKey.create("test_key"); public void sayHello() { // do something } public Object getData(@NotNull @NonNls String dataId) { if(TEST_KEY.is(dataId)){ return this; } return null; } } -
创建一个AnAction,并获取组件:
public class TestAction extends AnAction { public void update(@NotNull final AnActionEvent e) { TestPanel panel = e.getData(TEST_KEY); e.getPresentation().setEnabled(Objects.nonNull(panel)); super.update(e); } public void actionPerformed(AnActionEvent e) { TestPanel panel = e.getRequiredData(TEST_KEY); panel.sayHello(); // do something } }
注意: Action中是有可能拿不到组件的,因为getData主要是获取当前事件触发的组件以及其父组件中DataProvider.getData方法实现的。其子组件,兄弟组件中的组件则无法直接获取到,需要在当前组件树上通过getData方法获取。
One Comment