JAVA Swing開發單機版項目


一、序

  最近公司做的項目里出現了一個新的需求,項目大部分是為金融業定制開發的數據集成平台,包括數據的采集,處理,使用。

  數據的采集方式不固定,有機構化數據,有非結構話數據,還有附件等其它文件形式。

  對於采集端,大部分要求具備硬件服務器架設能力,這時就出現了一個問題,有些采集端是不具備硬件服務器架設能力的,或者主觀上不願意架設,

  要求公司拿出一套可以不假設服務器,而是和中心服務器交互。

  功能精簡為:只保留數據采集,數據結果由中心服務器來提供,客戶端安裝模式。

 

二、解決:

  我們是JAVA,要開發客戶端,那就是AWT、SWING,業內也一直都說是C#更適合開發。

  老板一句話,兩周之內要產品,沒辦法,還是用熟悉的SWING吧。遇到了很多問題,中間很坎坷,在這里記錄一下:

  (1)頁面的設計嵌套時,要整個包裹好再放入另一個容器里,這樣就可以保證樣式

  (2)SWING時間控件的選擇很少,第三方的時間控件又很難滿足具體項目的定制需求

  (3)表格的分頁,表格單元格顯示復選框的感覺很別扭

 

三、重點:

  (1)框架居中:

//第一種居中方式(為空時默認居中)
this.setLocationRelativeTo(null);

//第二種居中方式(獲取屏幕來居中)
int width = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int height = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
this.setBounds((int)(width/2-500/2), (int)(height/2-350/2), 500, 350);
//this.setUndecorated(true);
this.setResizable(false);

  (2)分割框的分割比重

//第一種設置方式,不具有強制性,有可能設置失敗
panel_split.setResizeWeight(0.6);

//第二種設置方式,可以指定分割框所占的比重
panel_split.addComponentListener(new ComponentAdapter() {  
        @Override  
        public void componentResized(ComponentEvent e) {  
               panel_split.setDividerLocation(1.0 / 4.0);  
         }  
}); 
panel_split.setOrientation(JSplitPane.VERTICAL_SPLIT);        

  (3)表格插入圖片的時候顯示字符串

//其中6、7均為格式需要轉換為圖片的列位置
table = new JTable(model){
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Class getColumnClass(int column) {
        if (column==6 && model.getDataVector().size()>0) {
            return getValueAt(0, 6).getClass();
        } else if(column==7 && model.getDataVector().size()>0) {
            return getValueAt(0, 7).getClass();
        } else {
            return getValueAt(0, 0).getClass();
        }
    }
};

//圖片數據列的插入
row.addElement(new ImageIcon(this.getClass().getClassLoader().getResource("reload.png")));

//普通字串數據列的插入
row.add(data.get("FILE_ID")==null?new String(""):data.get("FILE_ID"));

  (4)分頁對象

//分頁對象
package com.dis.view;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public abstract class SubPageBar extends JPanel implements ItemListener, ActionListener {
    
    private int allCount, fromRec, endRec, pageSize, pageIndex, pageCount;
    private JLabel allCountLab, curCountLab, pageIndexLab;
    @SuppressWarnings("rawtypes")
    private JComboBox eachCom;
    // 首頁
    private JButton firstPageButton;
    // 前一頁
    private JButton latePageButton;
    // 下一頁
    private JButton nextPageButton;
    // 末頁
    private JButton lastPageButton;

    public SubPageBar(int recNums) {
        this.allCount = recNums;
        initUI();
        updateData();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void initUI() {
        // comboBox
        eachCom = new JComboBox(new String[] { "10", "20", "50" });
        // label
        curCountLab = new JLabel();
        allCountLab = new JLabel();
        pageIndexLab = new JLabel();
        // button
        firstPageButton = new JButton("首頁");
        latePageButton = new JButton("上一頁");
        nextPageButton = new JButton("下一頁");
        lastPageButton = new JButton("末頁");
        // listener
        eachCom.addItemListener(this);
        firstPageButton.addActionListener(this);
        nextPageButton.addActionListener(this);

        latePageButton.addActionListener(this);
        lastPageButton.addActionListener(this);

        this.setLayout(new FlowLayout(FlowLayout.RIGHT));
        this.add(curCountLab);
        this.add(allCountLab);
        this.add(new JLabel("每頁"));
        this.add(eachCom);
        this.add(new JLabel("條"));
        this.add(firstPageButton);
        this.add(latePageButton);
        this.add(pageIndexLab);
        this.add(nextPageButton);
        this.add(lastPageButton);
    }

    /**
     * @Description: (更新分頁欄的值)
     */
    private void updateData() {
        // 必須知道的參數值:allCount pageIndex pageSize
        pageSize = Integer.valueOf(eachCom.getSelectedItem().toString());
        fromRec = pageIndex * pageSize + 1;
        if (0 == allCount) {
            fromRec = 0;
        }
        endRec = (pageIndex + 1) * pageSize;
        if (endRec > allCount) {
            endRec = allCount;
        }
        pageSize = (0 == pageSize) ? 1 : pageSize;
        pageCount = allCount / pageSize - ((0 == allCount % pageSize && 0 != allCount) ? 1 : 0);
//        curCountLab.setText("第 " + fromRec + "~" + endRec + " 條");
        allCountLab.setText("【共有 " + allCount + " 條】 ");
        pageIndexLab.setText(" 【第 " + (pageIndex) + "/" + (pageCount + 1) + " 頁】 ");
        firstPageButton.setEnabled(pageIndex > 0);
        latePageButton.setEnabled(pageCount > 0 && pageIndex > 0);
        nextPageButton.setEnabled(pageIndex < pageCount);
        lastPageButton.setEnabled(pageCount > 0 && pageIndex < pageCount);
    }

    /**
     * @Description: 有新數據載入時,需要重載
     */
    public void fresh(int recNums) {
        this.allCount = recNums;
        updateData();
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        // 這邊之所以要加上這個判斷,是因為“選中”和“取消選中”都會觸發ItemEvent.
        if (e.getStateChange() == ItemEvent.SELECTED) {
            pageIndex = 0;
            pageSize = Integer.valueOf(eachCom.getSelectedItem().toString());
            updateData();
            onPageSizeChange(pageSize);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == firstPageButton) {
            pageIndex = 1;
            onClickPreButton(pageIndex);
        } else if (e.getSource() == latePageButton) {
            pageIndex--;
            onClickPreButton(pageIndex);
        } else if (e.getSource() == nextPageButton) {
            pageIndex++;
            onClickNextButton(pageIndex);
        } else if (e.getSource() == lastPageButton) {
            pageIndex = pageCount;
            onClickNextButton(pageIndex);
        }
        updateData();
    }
    
    public int getPageIndex() {
        return (pageIndex>0) ? pageIndex : 1;
    }
    
    public void updatePageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
        updateData();
    }
    
    public int getPageSize() {
        return pageSize;
    }

    public abstract void onPageSizeChange(int newPageSize);

    public abstract void onClickPreButton(int pageIndex);

    public abstract void onClickNextButton(int pageIndex);
    
}

//分頁對象集成
table_col_name = new Vector<>();
        table_col_name.add("編號");
        table_col_name.add("文件名");
        table_col_name.add("機構名");
        table_col_name.add("流程名");
        table_col_name.add("當前狀態");
        table_col_name.add("變更時間");
        table_col_name.add("操作");
        table_col_name.add("重置");
        Vector<Vector<Object>> rowData = new Vector<Vector<Object>>();
        DefaultTableModel model = new DefaultTableModel(rowData, table_col_name);
        
        table = new JTable(model){
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public Class getColumnClass(int column) {
                if (column==6 && model.getDataVector().size()>0) {
                    return getValueAt(0, 6).getClass();
                } else if(column==7 && model.getDataVector().size()>0) {
                        return getValueAt(0, 7).getClass();
                } else {
                    return getValueAt(0, 0).getClass();
                }
            }
        };
        table.getTableHeader().setReorderingAllowed(false);// 限制整列拖動
        table.setEnabled(false);
        table.addMouseListener(tableListener);
        table_bar = new SubPageBar(0) {
            @Override
            public void onPageSizeChange(int newPageSize) {
                initTable();
            }

            @Override
            public void onClickPreButton(int pageIndex) {
                this.updatePageIndex(pageIndex--);
                initTable();
            }

            @Override
            public void onClickNextButton(int pageIndex) {
                this.updatePageIndex(pageIndex++);
                initTable();
            }
        };
        JPanel panel_table = new JPanel(new BorderLayout());
        JScrollPane scrollPanel_table = new JScrollPane();
        scrollPanel_table.setBorder(border);
        scrollPanel_table.setViewportView(table);
        panel_table.add(scrollPanel_table, BorderLayout.CENTER);
        panel_table.add(table_bar, BorderLayout.SOUTH);
        scrollPanel_bottom.setViewportView(panel_table);

//表格數據加載
//初始化表格
    @SuppressWarnings("unchecked")
    public void initTable() {
        HashMap<String,String> params = this.getParams();
        params.put("page", table_bar.getPageIndex()+"");
        params.put("rows", table_bar.getPageSize()+"");
        if (params.get("cycleType")=="-1") {
            params.remove("cycleType");
        }
        try {
            //請求數據
//            String resultStr = HttpRequest.sendGetRequest(PropertyUtil.readKeyValue(PropertyUtil.CONFIG_FILE_PATH, PropertyUtil.API_GETALLFILE), params,"UTF-8");
            String resultStr = HttpRequest.sendGetRequest(Sysconfig.getSysInstance().getProperty(PropertyUtil.API_GETALLFILE), params,"UTF-8");
            Page resultPage = GsonUtil.GsonToBean(resultStr, Page.class);
            //解析數據
            int totalCount = resultPage.getTotal();
            List<Map<String,String>> fileList = (List<Map<String, String>>) resultPage.getRows();
            //渲染表格
            table_bar.fresh(totalCount);
            DefaultTableModel model = (DefaultTableModel) table.getModel();
            model.getDataVector().clear();
            Vector<Vector<Object>> vData = model.getDataVector();
            if(null != fileList && fileList.size() > 0 && totalCount > 0) {
                Page page = null;
                page = new Page(totalCount);
                page.setPageSize(table_bar.getPageSize());
                page.setPageNow(pageNow);
                for (Map<String, String> data : fileList) {
                    Vector<Object> row = new Vector<Object>();
                    row.add(data.get("FILE_ID")==null?new String(""):data.get("FILE_ID"));
                    row.add(data.get("FILE_NAME")==null?new String(""):data.get("FILE_NAME"));
                    row.add(data.get("BANK_NAME")==null?new String(""):data.get("BANK_NAME"));
                    row.add(data.get("PROCESS_NAME")==null?new String(""):data.get("PROCESS_NAME"));
                    row.add(data.get("NODE_DESC")==null?new String(""):data.get("NODE_DESC"));
                    row.add(data.get("UPDATE_TIME")==null?new String(""): this.parseDate(data.get("UPDATE_TIME")));
                    row.addElement(new ImageIcon(this.getClass().getClassLoader().getResource("look.png")));
                    row.addElement(new ImageIcon(this.getClass().getClassLoader().getResource("reload.png")));
                    row.add(data.get("F_PNODE_STATE")==null?new String(""):data.get("F_PNODE_STATE"));
                    vData.add(row);
                }
            }
            table.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(new JCheckBox()));
            model.fireTableCellUpdated(0, 7);
            model.fireTableDataChanged();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "服務地址解析錯誤!");
            e.printStackTrace();
            log.error("服務地址解析錯誤!");
        }
    }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM