一、序

  最近公司做的项目里出现了一个新的需求,项目大部分是为金融业定制开发的数据集成平台,包括数据的采集,处理,使用。

  数据的采集方式不固定,有机构化数据,有非结构话数据,还有附件等其它文件形式。

  对于采集端,大部分要求具备硬件服务器架设能力,这时就出现了一个问题,有些采集端是不具备硬件服务器架设能力的,或者主观上不愿意架设,

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

  功能精简为:只保留数据采集,数据结果由中心服务器来提供,客户端安装模式。

二、解决:

  我们是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("服务地址解析错误!");
}
}

JAVA Swing开发单机版项目的更多相关文章

  1. java swing 开发 -JTable

    最近利用空闲时间自己琢磨了一下java swing 编程,其实在从事javaweb之前我一直向往的就是java swing 开发,不知道为什么可能当时觉得Windows上的exe程序很是神奇,关于wi ...

  2. ae(ArcEngine) java swing开发入门系列(1):开发环境和代码部署

    前言:做ae开发大部分人都是用C#版,很少用到java版,本系列文章主要介绍java版ae开发的入门,对于ae接口的高级应用,可以看C#版相关文章 开发环境软件: Intellij IDEA 2018 ...

  3. Java Swing客户端小项目

    记录一下两个用java swing写的客户端. 项目1: 关键词:swing  jtable 代码如下: 1.主类: package com.my.agent.client; import java. ...

  4. ae(ArcEngine) java swing开发入门系列(2):ae的类型转换和Proxy类说明

    做过C#版ae的都知道,操作同一个“对象”,用他的不同功能要转换到相应的接口,但java版有时不能直接做类型转换 例如下图在C#是可以的 但在java不行,这样转会报错,看IFeatureClass的 ...

  5. Java多线程开发系列之番外篇:事件派发线程---EventDispatchThread

    事件派发线程是java Swing开发中重要的知识点,在安卓app开发中,也是非常重要的一点.今天我们在多线程开发中,穿插进来这个线程.分别从线程的来由.原理和使用方法三个方面来学习事件派发线程. 一 ...

  6. spark之java程序开发

    spark之java程序开发 1.Spark中的Java开发的缘由: Spark自身是使用Scala程序开发的,Scala语言是同时具备函数式编程和指令式编程的一种混血语言,而Spark源码是基于Sc ...

  7. Java 集成开发环境的介绍及下载

    集成开发环境(integrated development environment,JDE) 之前成功运行了Java小程序是经历了先在笔记本中编写源代码,然后通过命令行运行打开javac编译源文件, ...

  8. Java Swing简单的加法器

    package test; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class FrameDe ...

  9. TTMS 一个基于Java Swing的Socket通信的剧院票务管理系统

    TTMS (Theater Ticket Management System) 点我进入github TTMS全称剧院票务管理系统,分为客户端和服务器端.服务器端可以接收客户端连接请求,客户端相当于我 ...

随机推荐

  1. 如何在 Azure 中均衡 Linux 虚拟机负载以创建高可用性应用程序

    负载均衡通过将传入请求分布到多个虚拟机来提供更高级别的可用性. 本教程介绍了 Azure 负载均衡器的不同组件,这些组件用于分发流量和提供高可用性. 你将学习如何执行以下操作: 创建 Azure 负载 ...

  2. Azure 镜像市场虚拟机映像制作指南

    本指南为 Azure 镜像市场(以下简称 Azure 镜像市场)独立软件供应商介绍制作虚拟机映像并上传到Azure的主要过程. 制作虚拟机映像有两种方式.一种是直接在Azure上申请相应的操作系统虚拟 ...

  3. [C# | WinCE | Solution] 在 WinCE 上访问 SSL 加密后的 WCF SOAP 服务接口出现“未能与远程服务器建立信任关系”

    Scenario: 服务器的 SOAP 使用了 GeoTrust 签名的 EV 证书,WinCE调用时出现“未能与远程服务器建立信任关系”的错误.原因是该 WinCE 设备信任的证书包括 Global ...

  4. 静态代码分析工具sonarqube+sonar-runner的安装配置及使用

    配置成功后的代码分析页面: 可以看到对复杂度.语法使用.重复度等等都做了分析,具体到了每一个方法和每一句代码. 四种使用方式: sonarqube + sonar-runner sonarqube + ...

  5. Redis学习---Redis操作之List

    List操作,redis中的List在在内存中按照一个name对应一个List来存储 lpush(name,values) --> 实际上是左添加 # 在name对应的list中添加元素,每个新 ...

  6. libc.so.6: cannot open shared object file: No such file or diretory

    环境 centos6.6. 由于误操作 删除了 rm -f /lib64/libc.so.6 导致其他命令不能使用 解决方法: /sbin/sln /lib64/libc-

  7. PFC电源设计与电感设计计算学习笔记

    PFC电源设计与电感设计计算 更新于2018-11-30 课程概览 常见PFC电路和特点1 常见PFC电路和特点1 CRM PFC电路设计计算 CCM PFC电路设计计算 CCM Interleave ...

  8. AltiumDesigner元器件搜索中英文对照

    个人常用 扬声器 spearker 计量表(电流表,电压表) meter 变压器 Trans CT 肖特基二极管 D Schotty 额外补充 英文名称       中文释义 2N3904  NPN型 ...

  9. print(n) 和 while/for 并列的时候, print()只会打印出最后一个结果

    n=0while n <10: n+=1print(n) # print(n)放在while的外面和while并列的时候, 只会打印出最后一个结果 n=0while n <10: n+=1 ...

  10. SAP CX Upscale Commerce : SAP全新推出的电商云平台

    大家好,我是Andy Chen,是SAP成都研究院年轻的SAP CX Upscale Commerce (后面将会以Upscale简称)开发团队的一名产品经理.CX的全称是Customer Exper ...