整理前八节:
上所有代码
一、图标:
二、jar文件
需要json处理jar包,可以联系我发给你
或者
https://github.com/stleary/JSON-java 下载
三、代码
APPDemo:
package swing03;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class APPDemo
{
private static void createGUI()
{
// JFrame指一个窗口,构造方法的参数为窗口标题
JFrame frame = new MyFrame("信息列表");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口的其他参数,如窗口大小
frame.setSize(600, 300);
// 显示窗口
frame.setVisible(true);
}
public static void main(String[] args)
{
//设置界面样式 Look And Feel
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run()
{
createGUI();
}
});
}
}
EditStudentDialog:
package swing03;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import js.swing.JsColumnLayout;
import js.swing.JsPanel;
import js.swing.JsRowLayout;
public class EditStudentDialog extends JDialog
{
public JTextField idField=new JTextField(20); //学号
public JTextField nameField=new JTextField(20); //姓名
public JComboBox<String> sexField=new JComboBox<>(); //下拉框
public JTextField phoneField=new JTextField(20); //手机号
public JTextField birthField=new JTextField(20); //生日(暂用文本来表示)
JButton okButton=new JButton("确定");
//默认是取消
private boolean retValue=false;
public EditStudentDialog(JFrame owner)
{
super(owner,"编辑学生信息",true);
this.setSize(300, 300);
//设置一个容器
JsPanel root=new JsPanel();
this.setContentPane(root);
this.setLayout(new JsColumnLayout(10));
root.padding(10);
//中间面板
JsPanel main=new JsPanel();
root.add(main, "1w");//占据中间区域
main.setLayout(new JsColumnLayout(10));
main.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
if(true)
{
JsPanel row=new JsPanel();
main.add(row,"24px");
row.setLayout(new JsRowLayout(10));
row.add(new JLabel("学号"), "50px");
row.add(idField, "1w");
}
if(true)
{
JsPanel row=new JsPanel();
main.add(row,"24px");
row.setLayout(new JsRowLayout(10));
row.add(new JLabel("姓名"), "50px");
row.add(nameField, "1w");
}
if(true)
{
JsPanel row=new JsPanel();
sexField.addItem("男");
sexField.addItem("女");
main.add(row,"24px");
row.setLayout(new JsRowLayout(10));
row.add(new JLabel("性别"), "50px");
row.add(sexField, "1w");
}
if(true)
{
JsPanel row=new JsPanel();
main.add(row,"24px");
row.setLayout(new JsRowLayout(10));
row.add(new JLabel("生日"), "50px");
row.add(birthField, "1w");
}
if(true)
{
JsPanel row=new JsPanel();
main.add(row,"24px");
row.setLayout(new JsRowLayout(10));
row.add(new JLabel("手机号"), "50px");
row.add(phoneField, "1w");
}
// if(true)
// {
// JsPanel row=new JsPanel();
// main.add(row,"24px");
// row.setLayout(new JsRowLayout(10));
// row.add(new JLabel("生日"), "50px");
// row.add(birthField, "1w");
// }
//底下
JsPanel button=new JsPanel();
root.add(button, "30px"); //底部区域30px
button.setLayout(new JsRowLayout(10));
button.add(new JLabel(),"1w"); //占位
button.add(okButton, "auto"); //按钮靠右显示
//lamada表达式
okButton.addActionListener((e)->{
if(checkValid())
{
retValue=true; //设置对话框的返回值
setVisible(false);//MyDialog.this.setVisible(false)
}
});
}
//返回值为true:表明用户点击了"确定"
//返回值为false:表示用户×掉了窗口,或者点了取消
public boolean exec()
{
//相对owner居中显示
Rectangle frmRect=this.getOwner().getBounds();
int width=this.getWidth();
int height=this.getHeight();
int x=frmRect.x+(frmRect.width-width)/2;
int y=frmRect.y+(frmRect.height-height)/2;
this.setBounds(x, y, width, height);
//显示窗口(阻塞,直到对话框窗口关闭)
this.setVisible(true);
return retValue;
}
//检查输入有效性
public boolean checkValid()
{
Student v=getValue();
if(v.id.isEmpty())
{
JOptionPane.showMessageDialog(this, "学号不能为空");
return false;
}
if(v.name.isEmpty())
{
JOptionPane.showMessageDialog(this, "姓名不得为空!");
return false;
}
return true;
}
//设置初始值
public void setValue(Student v)
{
idField.setEditable(false);
idField.setText(v.id);
nameField.setText(v.name);
//System.out.println(v.sex);
sexField.setSelectedIndex(v.sex? 0:1); //条件表达式
birthField.setText(v.birthday);
phoneField.setText(v.cellphone);
}
//获取用户的输入
public Student getValue()
{
Student v=new Student();
v.id=idField.getText().trim();
v.name=nameField.getText().trim();
v.sex=sexField.getSelectedIndex()==0;
v.cellphone=phoneField.getText().trim();
v.birthday=birthField.getText().trim();
return v;
}
}
IDColumnRenderer:
package swing03;
import java.awt.Component;
import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
//此处用于选中状态(JCheckBox)
public class IDColumnRenderer extends JCheckBox implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column)
{
//JCheckBox默认选中状态
this.setSelected(isSelected);
//学号信息
if(value!=null)
{
this.setText(value.toString());
}
//背景
this.setOpaque(true);//保持可以进行面板绘制
if(isSelected)
{
this.setBackground(table.getSelectionBackground());
this.setForeground(table.getSelectionForeground());
}
else
{
this.setBackground(table.getBackground());
this.setForeground(table.getForeground());
}
return this;
}
}
JsJSON:
package swing03;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.json.JSONArray;
import org.json.JSONObject;
public class JsJSON
{
// json: 可以是JSONObject 或 JSONArray
// encoding: "UTF-8", "GBK"
public static void toFile(Object json, File file, String encoding) throws Exception
{
String jsonstr = null;
if(json instanceof JSONObject)
jsonstr = ((JSONObject)json).toString(2);
else if(json instanceof JSONArray)
jsonstr = ((JSONArray)json).toString(2);
else
throw new Exception("Must be org.json.JSONObject or org.json.JSONArray");
// 存入文件
OutputStream outputStream = new FileOutputStream(file);
try {
// UTF-8写入BOM头部
encoding=encoding.toUpperCase();
if(encoding.equals("UTF-8"))
{
byte[] bom = { (byte)0xEF, (byte)0xBB,(byte) 0xBF };
outputStream.write(bom);
}
byte[] data = jsonstr.getBytes(encoding);
outputStream.write(data);
}finally {
// 确保文件被关闭
try { outputStream.close();} catch(Exception e) {}
}
}
public static Object fromFile(File file, String encoding) throws Exception
{
InputStream inputStream = new FileInputStream(file);
try {
int fileSize = (int)file.length();
byte[] data = new byte[fileSize];
int n = inputStream.read(data);
int offset = 0;
encoding=encoding.toUpperCase();
if(n > 3 && encoding.equals("UTF-8"))
{
if(data[0] == (byte)0xEF && data[1]==(byte)0xBB && data[2] == (byte)0xBF)
offset = 3; // 前3个字节是BOM
}
String jsonstr = new String(data, offset, n-offset, encoding);
// 找第一个非空白字符, 从而判断它是JSONObject 还是JSONArray
char firstChar = ' ';
for(int i=0; i<jsonstr.length(); i++)
{
firstChar = jsonstr.charAt(i);
if(firstChar != ' ' && firstChar != '\t' && firstChar != '\n' && firstChar != '\r')
break;
}
// 如果以{开头,则转成JSONObject; 如果以[开头,则转成 JSONArray
if(jsonstr.startsWith("{") )
{
return new JSONObject( jsonstr );
}
else if(jsonstr.startsWith("[") )
{
return new JSONArray ( jsonstr);
}
else
{
throw new Exception("JSON must begin with { or [ !");
}
}finally {
try {inputStream.close();} catch(Exception e) {}
}
}
//
// 在JSONObject里已经有了现成的方法, 以opt开头的方法都是带默认值的
// JSONObject.optInt()
// JSONObject.optLong()
// JSONObject.optString()
// JSONObject.optBoolean()
// ... 注 :以下方法重复,不需要了 ... 带缺省值得get方法
// 相当于 JSONObject.optInt()
public static int getInt (JSONObject json, String key, int defValue)
{
try {
return json.getInt(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optLong()
public static long getLong (JSONObject json, String key, long defValue)
{
try {
return json.getLong(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optString()
public static String getString (JSONObject json, String key, String defValue)
{
try {
return json.getString(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optBoolean()
public static boolean getBoolean (JSONObject json, String key, boolean defValue)
{
try {
return json.getBoolean(key);
}catch(Exception e)
{
return defValue;
}
}
}
MyFrame:
package swing03;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.json.JSONArray;
import org.json.JSONObject;
public class MyFrame extends JFrame
{
JPanel root = new JPanel();
JTable table = null;
// dataList: 维护所有记录 , tableModel: 要显示出来的记录
List<Student> dataList = new ArrayList<>();
DefaultTableModel tableModel = new DefaultTableModel();
JButton addButton,deleteButton,editButton,searchButton,noticeButton;
JTextField searchField = new JTextField();
public MyFrame(String title)
{
super(title);
// Content Pane
this.setContentPane(root);
root.setLayout(new BorderLayout());
// 表格初始化
initTable();
// 初始化工具栏
initToolBar();
// 加载文件
loadData();
}
private void initTable()
{
// 创建 JTable,直接重写 isCellEditable(),设为不可编辑
table = new JTable(tableModel){
@Override
public boolean isCellEditable(int row, int column)
{
return false;
}
};
JScrollPane scrollPane = new JScrollPane(table);
root.add(scrollPane, BorderLayout.CENTER);
// 添加到主界面
table.setFillsViewportHeight(true);
table.setRowSelectionAllowed(true); // 整行选择
table.setRowHeight(30);
// 列设置:添加5列
tableModel.addColumn ("学号");
tableModel.addColumn ("姓名");
tableModel.addColumn ("性别");
tableModel.addColumn ("出生日期");
tableModel.addColumn ("手机号");
// 列设置:自定义绘制
table.getColumnModel().getColumn(2).setCellRenderer(new SexColumnRenderer());
table.getColumnModel().getColumn(0).setCellRenderer(new IDColumnRenderer());
table.getColumnModel().getColumn(0).setPreferredWidth(110); // 该列的宽度
}
private void initToolBar()
{
JToolBar toolBar = new JToolBar();
root.add(toolBar, BorderLayout.PAGE_START);
toolBar.setFloatable(false);
// 按钮
addButton = createToolButton("添加", "ic_add.png" );
toolBar.add(addButton);
addButton.addActionListener( (e)->{
onAdd();
});
// 按钮
deleteButton = createToolButton("删除", "ic_delete.png" );
toolBar.add(deleteButton);
deleteButton.addActionListener( (e)->{
onDelete();
});
// 按钮
editButton = createToolButton("编辑", "ic_edit.png" );
toolBar.add(editButton);
editButton.addActionListener( (e)->{
onEdit();
});
// 查询
toolBar.addSeparator(new Dimension(40,10));
//toolBar.add( new JLabel("查询") );
searchButton=createToolButton("查询","ic_search.png");
toolBar.add( searchField );
toolBar.add(searchButton);
toolBar.addSeparator(new Dimension(60,10));
searchField.setMaximumSize(new Dimension(120,30));
searchField.addActionListener( (e)->{
// 按回车时触发事件
onSearch();
});
searchButton.addActionListener( (e)->{
// 按回车时触发事件
onSearch();
});
// 加油,未来,不负青春不负卿按钮
noticeButton = createToolButton("滴水穿石", "ic_notice.png" );
toolBar.add(noticeButton);
noticeButton.addActionListener( (e)->{
onGoGO();
});
}
protected JButton createToolButton(String text, String icon)
{
// 图标
String imagePath = "/icons/" + icon;
URL imageURL = getClass().getResource(imagePath);
// 创建按钮
JButton button = new JButton(text);
//button.setActionCommand(action);
button.setToolTipText(text);
button.setIcon(new ImageIcon(imageURL));
button.setFocusPainted(false);
return button;
}
private void addTableRow(Student item)
{
// java.util.Vector 是个范型 ,表示数组
Vector<Object> rowData = new Vector<>();
rowData.add(item.id);
rowData.add(item.name);
rowData.add(item.sex);
rowData.add(item.birthday);
rowData.add(item.cellphone);
tableModel.addRow( rowData ); // 添加一行
}
// 获取 表格控件中的一条记录的值
private Student getTableRow(int row)
{
Student s = new Student();
s.id = (String) tableModel.getValueAt(row, 0);
s.name = (String) tableModel.getValueAt(row, 1);
s.sex = (Boolean) tableModel.getValueAt(row, 2);
s.birthday = (String) tableModel.getValueAt(row, 3);
s.cellphone = (String) tableModel.getValueAt(row, 4);
return s;
}
// 设置 表格控件中的一条记录的值
private void setTableRow(Student v, int row)
{
tableModel.setValueAt(v.id, row, 0);
tableModel.setValueAt(v.name, row, 1);
tableModel.setValueAt(v.sex, row, 2);
tableModel.setValueAt(v.birthday, row, 3);
tableModel.setValueAt(v.cellphone, row, 4);
}
// 向dataList添加一条记录
private void addToDataList(Student s)
{
dataList.add(s);
}
// 修改一条记录
private void updateToDataList(String id, Student s)
{
for(int i=0;i<dataList.size();i++)
{
Student item = dataList.get(i);
if(item.id.equals(id))
{
dataList.set(i, s);
}
}
}
// 从dataList中删除一条记录
private void removeFromDataList(String id)
{
Iterator<Student> iter = dataList.iterator();
while(iter.hasNext())
{
Student s = iter.next();
if(s.id.equals( id))
{
iter.remove();
break;
}
}
}
// 点'添加' 按钮
private void onAdd()
{
EditStudentDialog dlg = new EditStudentDialog(this);
if( dlg.exec() )
{
Student stu = dlg.getValue();
addToDataList (stu); // 添加到 dataList
addTableRow( stu); // 添加到 tableModel
saveData(); // 保存到文件
}
}
// 点 '删除' 按钮
private void onDelete()
{
// 获取选中的行的索引
int[] rows = table.getSelectedRows();
if(rows.length == 0)return;
// 弹出对话框确认
int select = JOptionPane.showConfirmDialog(this, "是否确认删除?", "确认", JOptionPane.YES_NO_OPTION);
if(select != 0) return; // 0号按钮是'确定'按钮
// 技巧:从后往前删除
for(int i= rows.length-1; i>=0; i--)
{
int row = rows[i];
// 按学号,从dataList中删除该条记录
String id = (String)tableModel.getValueAt(row, 0);
removeFromDataList(id);
// 从tableModel中删除该条记录
tableModel.removeRow( row);
}
saveData(); // 保存到文件
}
// 点 '编辑' 按钮
private void onEdit()
{
// 获取选中的行的索引
int[] rows = table.getSelectedRows();
if(rows.length == 0)return;
// 取得选中的行
int row = rows[0]; // 只编辑选中的第一行
Student s = getTableRow( row );
// 弹出编辑对话框
EditStudentDialog dlg = new EditStudentDialog(this);
// 设置初始值
dlg.setValue( s );
if( dlg.exec() )
{
Student stu = dlg.getValue();
// 更新到 Model
setTableRow (stu, row );
// 更新到dataList
updateToDataList(stu.id, stu);
saveData(); // 保存到文件
}
}
private void onSearch()
{
// 获取用户输入的过滤条件
String filter = searchField.getText().trim();
if(filter.length() == 0) // 过滤条件为空
{
// 恢复原始数据
tableModel.setRowCount(0);// 清空
for(Student s : dataList)
{
addTableRow(s);
}
this.addButton.setEnabled(true);
return;
}
// 把符合条件的记录显示在表格里
tableModel.setRowCount(0);//清空
for(Student s : dataList)
{
if(s.name.indexOf(filter)>=0)
{
addTableRow(s);
}
}
// 把其他操作按钮禁用
this.addButton.setEnabled(false);
}
//加油,久森
private void onGoGO()
{
JOptionPane.showMessageDialog(this, "将一付好牌打好没有什么了不起,能将一付坏牌打好的人才值得钦佩。");
}
// 保存数据
private void saveData()
{
// 构造一个 JSON 数组
JSONArray array = new JSONArray();
for(int i=0; i<dataList.size(); i++)
{
Student s = dataList.get(i);
JSONObject j1 = new JSONObject();
j1.put("id", s.id);
j1.put("name", s.name);
j1.put("sex", s.sex);
j1.put("birthday", s.birthday);
j1.put("cellphone", s.cellphone);
array.put( j1 );
}
// 将JSON对象保存到文件
File file = new File("students.json");
try
{
JsJSON.toFile(array, file, "UTF-8");
} catch (Exception e)
{
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
}
}
private void loadData()
{
// 加载数据
File file = new File("students.json");
if(!file.exists()) return;
JSONArray array = null;
try
{
array = (JSONArray) JsJSON.fromFile(file, "UTF-8");
} catch (Exception e)
{
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
return;
}
// 显示到表格
dataList.clear();
tableModel.setRowCount(0); // 清空
for(int i=0; i<array.length(); i++)
{
JSONObject j1 = array.getJSONObject(i);
Student s = new Student();
s.id = j1.getString("id");
s.name = j1.getString("name");
s.sex = j1.getBoolean("sex");
s.cellphone = j1.getString("cellphone");
s.birthday = j1.getString("birthday");
addToDataList( s);
addTableRow( s);
}
}
}
SexColumnRenderer:
package swing03;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;
public class SexColumnRenderer extends JLabel implements TableCellRenderer
{
public SexColumnRenderer()
{
this.setHorizontalAlignment(SwingConstants.CENTER);
this.setFont(this.getFont().deriveFont(Font.PLAIN));
this.setBackground(new Color(0,0,0,0));
}
//设置颜色...以及...男-女
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
boolean sex=(boolean)value;
if(sex==true)
this.setText("男");
else
this.setText("女");
//背景
this.setOpaque(true);
if(isSelected)
{
this.setBackground(table.getSelectionBackground());
this.setForeground(table.getSelectionForeground());
}
else
{
this.setBackground(table.getBackground());
this.setForeground(table.getForeground());
}
return this;
}
}
Student:
package swing03;
/*
* 表格里得数据
*/
public class Student
{
public String id;
public String name;
public boolean sex;
public String birthday;
public String cellphone;
}
加油到最后一刻!
师傅:发哥