一、序

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

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

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

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

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

二、解决:

  我们是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. spring boot(9)-mybatis关联映射

    一对多 查询type表的某一条数据,并且要同时查出所有typeid与之配置的user,最终要得到一个以下类型的Type对象 public class Type { String id; String ...

  2. windows下查看端口占用以及进程名称

    http://www.cnblogs.com/rollenholt/archive/2012/08/17/2644657.html

  3. linux/OSX中“DD”命令制作ISO镜像操作系统安装U盘

    linux或者OS X系统中,使用“dd”命令可以直接在终端命令行模式下,制作ISO镜像的系统安装盘. 一.linux系统以centOS7为例. sudo dd if=镜像路径 of=USB设备路径 ...

  4. iOS设计模式 - 享元

    iOS设计模式 - 享元 原理图 说明 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分 ...

  5. Celery学习---Celery 分布式队列介绍及安装

    Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, ...

  6. Spring 源代码阅读之声明式事务

    事务控制流程 例如对如下代码进行事务控制 class service1{ method1(){ method2(); } } class service2{ method2(); } 原理:建立一个m ...

  7. JAVA 泛型通配符 ? EXTENDS SUPER 的用法

    1. <? extends Hero> ArrayList heroList<? extends Hero> 表示这是一个Hero泛型或者其子类泛型heroList 的泛型可能 ...

  8. 1101: [POI2007]Zap

    Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d.作为FGD的同 ...

  9. linux centos 7.5下 源码编译安装 lua环境

    lua 5.3.5 下载安装时发现缺少库 readline 需要添加依赖 yum search readline 看有哪些包 安装带有 devel 字样的 安装无 devel 的非开发包,通常不会自动 ...

  10. 解决osx下 ssh: connect to host localhost port 22: Connection refused

    解决办法: 终端下执行:sudo  systmesetup -setremotelogin on