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("服务地址解析错误!");
}
}
JAVA Swing开发单机版项目的更多相关文章
- java swing 开发 -JTable
最近利用空闲时间自己琢磨了一下java swing 编程,其实在从事javaweb之前我一直向往的就是java swing 开发,不知道为什么可能当时觉得Windows上的exe程序很是神奇,关于wi ...
- ae(ArcEngine) java swing开发入门系列(1):开发环境和代码部署
前言:做ae开发大部分人都是用C#版,很少用到java版,本系列文章主要介绍java版ae开发的入门,对于ae接口的高级应用,可以看C#版相关文章 开发环境软件: Intellij IDEA 2018 ...
- Java Swing客户端小项目
记录一下两个用java swing写的客户端. 项目1: 关键词:swing jtable 代码如下: 1.主类: package com.my.agent.client; import java. ...
- ae(ArcEngine) java swing开发入门系列(2):ae的类型转换和Proxy类说明
做过C#版ae的都知道,操作同一个“对象”,用他的不同功能要转换到相应的接口,但java版有时不能直接做类型转换 例如下图在C#是可以的 但在java不行,这样转会报错,看IFeatureClass的 ...
- Java多线程开发系列之番外篇:事件派发线程---EventDispatchThread
事件派发线程是java Swing开发中重要的知识点,在安卓app开发中,也是非常重要的一点.今天我们在多线程开发中,穿插进来这个线程.分别从线程的来由.原理和使用方法三个方面来学习事件派发线程. 一 ...
- spark之java程序开发
spark之java程序开发 1.Spark中的Java开发的缘由: Spark自身是使用Scala程序开发的,Scala语言是同时具备函数式编程和指令式编程的一种混血语言,而Spark源码是基于Sc ...
- Java 集成开发环境的介绍及下载
集成开发环境(integrated development environment,JDE) 之前成功运行了Java小程序是经历了先在笔记本中编写源代码,然后通过命令行运行打开javac编译源文件, ...
- Java Swing简单的加法器
package test; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class FrameDe ...
- TTMS 一个基于Java Swing的Socket通信的剧院票务管理系统
TTMS (Theater Ticket Management System) 点我进入github TTMS全称剧院票务管理系统,分为客户端和服务器端.服务器端可以接收客户端连接请求,客户端相当于我 ...
随机推荐
- log4j配置详解(非常详细)
Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...
- 搭建企业级全网数据定时备份方案[cron + rsync]
1.1.1. 服务端的配置[192.168.25.141] Rsync的端口是:873 man rsyncd.conf 查看帮助 Rsync是Redhat默认自带的,这里只是做了rsync服务器端的后 ...
- Centos7下Mysql通过.frm和.ibd恢复数据
通过.frm和.ibd文件恢复表结构和数据 这里以hue数据库中的desktop_document2表为例 分成两步骤,先去表结构,再取数据,最好在一个用完就可以删除的数据库中进行 取表结构篇: 1. ...
- C++暑期学习笔记
# C++初步学习笔记 一.命名空间(namespace)相关 1 个人理解: 为了避免整合资源中存在的重名矛盾而采取的区别资源的措施: 2 命名空间的定义: 比如要定义一个命名空间A: namesp ...
- SPL 笔记
PHP SPL是指 standard php library,php标准库. SPL提供了一系列的类和接口,使用这些类和接口,我们可以更加高效.优雅的使用php进行程序设计. 从php5.0开 ...
- 【原创】python __all__ 的用法
1. 写自己的module或者package的时候需要控制向外暴露的名字, 这个很有用, 防止名字污染
- 用python解析word文件(一):paragraph
太长了,我决定还是拆开三篇写. (一)段落篇(paragraph)(本篇) (二)表格篇(table) (三)样式篇(style) 选你所需即可.下面开始正文. 最近公司的项目,需要在页面上显示w ...
- Hadoop学习之路(五)Hadoop集群搭建模式和各模式问题
分布式集群的通用问题 当前的HDFS和YARN都是一主多从的分布式架构,主从节点---管理者和工作者 问题:如果主节点或是管理者宕机了.会出现什么问题? 群龙无首,整个集群不可用.所以在一主多从的架构 ...
- 1.1《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——运行终端
终端是个允许我们运行命令行的程序,运行命令前,先打开它.在MacOS系统上,可以使用macOS应用 Spotlight来打开终端窗口,Spotlight也有其他两种方式触发,一种是键入⌘␣(comma ...
- 原型和原型对象(__proto__和prototype)转
看了之后我总算对原型继承有了更深刻的理解,做爱分享的姑娘,原文链接:理解Javascript 原型 我(个人)不喜欢的,就是讲原型时上来就拿类做比较的,所以我不会这样讲.不过我的确讲过构造器函数,在这 ...