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全称剧院票务管理系统,分为客户端和服务器端.服务器端可以接收客户端连接请求,客户端相当于我 ...
随机推荐
- Eigen学习
Eigen 是一个基于C++的线性代数库,其中实现大量常用的线性代数算法,包括常规矩阵计算,矩阵变换,矩阵分解,矩阵块操作.Eigen 广泛地应用在开源项目中,例如OpenCV,PCL(Point C ...
- [翻译] USING GIT IN XCODE [3] 在XCODE中使用GIT[3]
USING GIT IN XCODE MAKING AND COMMITTING CHANGES Once you have a working copy of your project, it’s ...
- magento2 重置后台密码
项目根目录:运行如下命令 bin/magento admin:user:create --admin-user="admin" --admin-password="123 ...
- 【Excel】单元格的下拉框是怎么做的?
如果我们希望将产品这一列的每个单元格都能选择 左侧的产品就好了,就像这样 这里使用的是"验证数据有效性"功能 在这里: 点击F,选择F列后,打开“数据验证”,如图,选择序列,选择来 ...
- September 29th 2017 Week 39th Friday
Human life is ephemera, which makes it precious. 生命短暂,所以珍贵. Don't waste time on praying to the God. ...
- ZT 安卓手机的安全性 prepare for Q
如何增强安卓手机的安全性?安卓的安全性太低了!!! 众所周知,安卓手机是非常容易破解的,刷过机的人都知道,不管你之前在手机怎么设置密码,只要进入recovery清空使用记录,手机就会恢复出厂设置,到时 ...
- session过期,拦截ajax请求并跳转登录页面
1.方法一 :1.1使用filter 和ajaxsetup 对ajax进行拦截并跳转登录页面 public void doFilter(ServletRequest request, ServletR ...
- 【FLEX教程】#008 开发中的问题笔记(慢更…)
在这里记录一下个人在FLEX开发中遇到的一些问题.方便一些遇到同样问题的朋友们,能够快速的解决这些问题. 这篇笔记我会慢慢的更新,(PS:有遇到问题就往上面更….) 2015年1月4日 12:53:5 ...
- Android混合式开发(Hybrid)
安卓混合式开发(Hybrid) 1 环境搭建 1.1 首先,下载 Android Studio (Intellij Idea) 下载地址:http://www.android-studio.org/ ...
- virtualbox+vagrant学习-2(command cli)-16-vagrant snapshot命令
Snapshot快照 这是用于管理客户机器快照的命令.快照记录客户计算机的时间点状态.然后可以快速恢复到此环境.这可以让你进行试验和尝试,并迅速恢复到以前的状态. 快照并不是每个provider都支持 ...