开发IDEA摸鱼插件,展示股票行情和K线!

作者:小傅哥
博客:https://bugstack.cn

沉淀、分享、成长,让自己和他人都能有所收获!

一、前言

没招了,不写点刺激的,你总是不好好看!

以前,我不懂。写的技术就是技术内容,写的场景就是场景分析,但从读者的阅读我发现,大家更喜欢的是技术与场景结合,尤其是用技术结合那些羞羞答答的场景,虽然嘴上都不说。

本章节主要是想给大家介绍关于在 IDEA 插件开发中如何使用工具栏和Tab页,来填充在 IDEA 中底部的窗体,就像 IDEA 中的控制台一样。但就这么写好像是够呛能有人看,因为大家只从技术点来看,很难发现这里面有什么应用场景,即使看了好像也不知道这技术能干啥。

那咋办,整点刺激的吧。大家不是喜欢赔钱炒股吗,那就把股票行情K线展示结合到IDEA插件开发中。可以让学习插件的伙伴,都能在写代码疲惫的时候还能看一眼股票,也许在关键的时候还能提醒你赶紧抛出去!

二、需求目的

安全起见,需要在 IDEA 中以一个比较隐秘的角落,开发股票插件,让炒股的同学可以在紧张编码CRUD之余,不要忘记自己关注的股票购买和抛售。

那么为了解决这个问题,我们需要几个技术点,包括:股票数据接口、查询对象封装、IDEA 底部窗体和工具栏开发、定时任务扫描、Swing UI、股票代码配置和保存、窗体按钮事件监听等。

接下来我们就结合这些技术点,来解决实际的场景问题,看看如何在 IDEA 中开发一个股票插件。

三、案例开发

1. 工程结构

guide-idea-plugin-tab
├── .gradle
└── src
    ├── main
    │   └── java
    │    └── cn.bugstack.guide.idea.plugin 
    │        ├── domain
    │        │ ├── model
    │        │ │ ├── aggregates
    │        │ │ │ └── StockResult.java    
    │        │ │ └── vo  
    │        │ │   ├── Data.java 
    │        │ │   ├── GoPicture.java     
    │        │ │   └── Stock.java       
    │        │ └── service   
    │        │   ├── impl     
    │        │   │ └── StockImpl.java    
    │        │   └── IStock      
    │        ├── factory
    │        │ └── TabFactory.java  
    │        ├── infrastructure
    │        │ ├── DataSetting.java       
    │        │ └── DataState.java     
    │        ├── module
    │        │ ├── RefreshBar.java   
    │        │ ├── SettingBar.java    
    │        │ └── ViewBars.java         
    │        └── ui
    │        │ ├── ConsoleUI.java 
    │        │ ├── ConsoleUI.form
    │        │ ├── GidConfig.java  
    │        │ └── GidConfig.form
    │        └── Config    
    ├── resources
    │   └── META-INF
    │       └── plugin.xml 
    ├── build.gradle  
    └── gradle.properties

公众号:bugstack虫洞栈 回复:idea 即可下载全部 IDEA 插件开发源码

在此 IDEA 插件工程中,主要分为5块区域:

接下来,我们就分别看下每个核心功能点的实现过程,这个过程中你可以提前把代码下载下来,对照着学习会更加容易理解。

  1. 实现 ToolWindowFactory 开发一个底部的窗体,用于承载所需的内容
  2. 左侧是侧边工具栏,配置自选股、刷新股票指数
  3. 右侧是2个 tab 页,分别用于展示股票数据和K线图,这里的数据则需要通过股票接口来提供

2. tab 页窗体

首先这里我们先使用 IDEA 插件开发中,Swing UI 功能,拖拽出2个简单的窗体。有了这样的一个基本结构大家的脑子里应该就可以有画面了。

2.1 自选股配置窗体

public class GidConfig implements Configurable {

    private JPanel mainPanel;
    private JPanel settingPanel;
    private JLabel gidLabel;
    private JTextField gidTextField;

    private ConsoleUI consoleUI;

    public GidConfig(ConsoleUI consoleUI){
        this.consoleUI = consoleUI;
    }

    public JTextField getGidTextField() {
        return gidTextField;
    }

    @Override
    public void apply() throws ConfigurationException {
        List gidList = DataSetting.getInstance().getGids();
        gidList.clear();
        String[] gids = gidTextField.getText().trim().split(",");
        for (String gid : gids) {
            gidList.add(gid.trim());
        }
        // 刷新数据
        consoleUI.addRows(gidList);
    }

}

2.2 股票展示窗体

public class ConsoleUI {

    private JTabbedPane tabbedPane1;
    private JPanel one;
    private JPanel two;
    private JLabel picMin;
    private JTable table;
    private JLabel picDay;

    // 查询数据服务
    private IStock stock = new StockImpl();

    private DefaultTableModel defaultTableModel = new DefaultTableModel(new Object[][]{}, new String[]{"股票", "代码", "最新", "涨跌", "涨幅"});

    public ConsoleUI() {
        // 初始数据
        table.setModel(defaultTableModel);
        addRows(DataSetting.getInstance().getGids());

        // 添加事件
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int row = table.getSelectedRow();
                Object value = table.getValueAt(row, 1);
                GoPicture goPicture = stock.queryGidGoPicture(value.toString());
                try {
                    // 分钟K线
                    picMin.setSize(545, 300);
                    picMin.setIcon(new ImageIcon(new URL(goPicture.getMinurl())));

                    // 当日K线
                    picDay.setSize(545, 300);
                    picDay.setIcon(new ImageIcon(new URL(goPicture.getDayurl())));
                } catch (MalformedURLException m) {
                    m.printStackTrace();
                }
            }
        });
    }

    public JTabbedPane getPanel() {
        return tabbedPane1;
    }

    public void addRows(List gids) {
        // 查询
        List dataList = stock.queryPresetStockData(gids);

        // 清空
        int rowCount = defaultTableModel.getRowCount();
        for (int i = 0; i < rowCount; i++) {
            defaultTableModel.removeRow(0);
        }

        // 添加
        for (Data data : dataList) {
            defaultTableModel.addRow(new String[]{data.getName(), data.getGid(), data.getNowPri(), data.getIncrease(), data.getIncrePer()});
            table.setModel(defaultTableModel);
        }
    }

}

3. 股票框体设置

在开发完 UI 窗体后,我们还需要使用一个 SimpleToolWindowPanel 的继承实现类,承载工具栏和页面的设置。

3.1 设置-工具栏

cn.bugstack.guide.idea.plugin.module.SettingBar

public class SettingBar extends DumbAwareAction {

    private ViewBars panel;

    public SettingBar(ViewBars panel) {
        super("配置股票", "Click to setting", IconLoader.getIcon("/icons/config.svg"));
        this.panel = panel;
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        ShowSettingsUtil.getInstance().editConfigurable(panel.getProject(), new GidConfig(panel.getConsoleUI()));
    }

}

3.2 刷新-工具栏

cn.bugstack.guide.idea.plugin.module.RefreshBar

public class RefreshBar extends DumbAwareAction {

    private ViewBars panel;

    public RefreshBar(ViewBars panel) {
        super("刷新指数", "Click to refresh", IconLoader.getIcon("/icons/refresh.svg"));
        this.panel = panel;
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        panel.getConsoleUI().addRows(DataSetting.getInstance().getGids());
    }

}

3.3 窗体填充面板

cn.bugstack.guide.idea.plugin.module.ViewBars

public class ViewBars extends SimpleToolWindowPanel {

    private Project project;
    private ConsoleUI consoleUI;

    public ViewBars(Project project) {
        super(false, true);
        this.project = project;
        consoleUI = new ConsoleUI();

        // 设置窗体侧边栏按钮
        DefaultActionGroup group = new DefaultActionGroup();
        group.add(new SettingBar(this));
        group.add(new RefreshBar(this));

        ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("bar", group, false);
        toolbar.setTargetComponent(this);
        setToolbar(toolbar.getComponent());

        // 添加
        JBSplitter splitter = new JBSplitter(false);
        splitter.setSplitterProportionKey("main.splitter.key");
        splitter.setFirstComponent(consoleUI.getPanel());
        splitter.setProportion(0.3f);
        setContent(splitter);
    }

    public Project getProject() {
        return project;
    }

    public ConsoleUI getConsoleUI() {
        return consoleUI;
    }
}

4. 填充主面板到IDEA工具栏

4.1 窗体工厂

cn.bugstack.guide.idea.plugin.factory.TabFactory

public class TabFactory implements ToolWindowFactory {

    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        // 窗体
        ViewBars viewPanel = new ViewBars(project);
        // 获取内容工厂的实例
        ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
        // 获取 ToolWindow 显示的内容
        Content content = contentFactory.createContent(viewPanel, "股票", false);
        // 设置 ToolWindow 显示的内容
        toolWindow.getContentManager().addContent(content, 0);

        // 定时任务,自动刷新股票
        /* 因每日查询次数限制,这里就不开定时任务了,用户可以自行申请 https://dashboard.juhe.cn/home
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                viewPanel.getConsoleUI().addRows(DataSetting.getInstance().getGids());
            }
        }, 3000, 2000);*/
    }

}

4.2 配置窗体

plugin.xml


    
    
        
        

    


5. 数据持久化配置

5.1 对象数据

cn.bugstack.guide.idea.plugin.infrastructure.DataState

public class DataState {

    private List gids = new ArrayList<>();

    public List getGids() {
        return gids;
    }

    public void setGids(List gids) {
        this.gids = gids;
    }

}

5.2 持久数据

cn.bugstack.guide.idea.plugin.infrastructure.DataSetting

@State(name = "DataSetting",storages = @Storage("plugin.xml"))
public class DataSetting implements PersistentStateComponent {

    private DataState state = new DataState();

    public static DataSetting getInstance() {
        return ServiceManager.getService(DataSetting.class);
    }

    @Nullable
    @Override
    public DataState getState() {
        return state;
    }

    @Override
    public void loadState(@NotNull DataState state) {
        this.state = state;
    }

     public List getGids(){
        return state.getGids();
     }

}

5.3 plugin.xml 配置


    
    

6. 股票接口

6.1 技术调研

6.2 服务封装

有了股票的查询接口,接下来就可以对数据做一个查询和对象转换了。

cn.bugstack.guide.idea.plugin.domain.service.impl.StockImpl

public class StockImpl implements IStock {

    // 自行申请,股票API,替换key即可【一天可免费调用100次】:https://dashboard.juhe.cn/home/
    private final String key = "4bc57728***********f0595";

    @Override
    public List queryPresetStockData(List gids) {
        List dataList = new ArrayList<>();
        for (String gid : gids) {
            StockResult stockResult = JSON.parseObject(HttpUtil.get("http://web.juhe.cn:8080/finance/stock/hs?gid=" + gid + "&key=" + key), StockResult.class);
            Stock[] stocks = stockResult.getResult();
            for (Stock stock : stocks) {
                dataList.add(stock.getData());
            }
        }
        return dataList;
    }

}

四、测试验证

运行效果 - 激动人心的时刻到了,再也不用担心写代码影响看股票了哦

1. 配置股票

2. 自选股指数

3. K线

五、总结

展开阅读全文

页面更新:2024-05-16

标签:插件   窗体   工具栏   股票代码   股票行情   接口   对象   股票   摸鱼   内容   数据   技术

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top