环境:eclipse
jdk版本:1.8+
ps:如果您想读懂这篇博客,并有所收获的话,最好是有swing开发的基础知识
这篇文章适合刚刚学完Java swing而又没有实战经验的人
SwingDemo.java
public class SwingDemo {
public static void CreateGUI() {
JFrame frame = new MyFrame("demo");
frame.setSize(new Dimension(500,300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
CreateGUI();
}
});
}
}
MyFrame.java(框架的搭建)
public class MyFrame extends JFrame{
JPanel root = null;
JTable table = null;
DefaultTableModel model = new DefaultTableModel();
JTextField SearchField = new JTextField();
JButton btn_add;
JButton btn_delete;
JButton btn_edit;
List<student> temp_stu;
public MyFrame(String title) {
super(title);
//设置顶层容器
root = new JPanel();
setContentPane(root);
root.setLayout(new BorderLayout());
//初始化按钮
initToolBar();
//初始化主界面
initTable();
try {
loadData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void initTable() {
table = new JTable(model) {
//直接重写其中的方法,使其不可edit
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JScrollPane scrollPane = new JScrollPane(table);
root.add(scrollPane,BorderLayout.CENTER);
//对table做一些设置
table.setRowHeight(30);
table.setFillsViewportHeight(true);
table.setRowSelectionAllowed(true);
//列设置
model.addColumn ("学号");
model.addColumn ("姓名");
model.addColumn ("性别");
model.addColumn ("出生日期");
model.addColumn ("手机号");
table.getColumnModel().getColumn(2).setCellRenderer(new GenderColumnRender());
table.getColumnModel().getColumn(0).setCellRenderer(new IDColumnRender());
}
public void initToolBar() {
JToolBar toolBar = new JToolBar();
root.add(toolBar,BorderLayout.PAGE_START);
btn_add = createToolButton("添加","ic_add.png");
toolBar.add(btn_add);
btn_add.addActionListener((e)-> {
//add
Dialog_new dia_new = new Dialog_new(this);
if (dia_new.exec()) {
student s = dia_new.getStudent();
addTableRow(s);
try {
saveData();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
btn_delete = createToolButton("删除", "ic_delete.png");
toolBar.add(btn_delete);
btn_delete.addActionListener((e)-> {
//delete
try {
onDelete();
} catch (Exception e1) {
e1.printStackTrace();
}
});
btn_edit = createToolButton("编辑", "ic_edit.png");
toolBar.add(btn_edit);
btn_edit.addActionListener((e)-> {
onEdit();
});
toolBar.addSeparator(new Dimension(40,10));
toolBar.add(new JLabel("查询 "));
toolBar.add(SearchField);
SearchField.setMaximumSize(new Dimension(120,25));
SearchField.addActionListener((e)->{
onSearch();
});
}
public void onSearch() {
String search = SearchField.getText().trim();
//如果输入框是空的,那就恢复数据
if (search.isEmpty()) {
//清空removeAll();
model.setRowCount(0);
//回复数据
for (student s:temp_stu) {
addTableRow(s);
}
btn_add.setEnabled(true);
btn_delete.setEnabled(true);
btn_edit.setEnabled(true);
return;
}
//备份数据放进一个list
temp_stu = new ArrayList<>();
int count = model.getRowCount();
for(int i = 0;i < count;i++) {
temp_stu.add(getTableRow(i));
}
//清空model
table.removeAll();
model.setRowCount(0);
//查找
int list_length = temp_stu.size();
for (int i = 0;i<list_length;i++) {
if (temp_stu.get(i).getName().indexOf(search) >= 0) {
//如果查到了值
addTableRow(temp_stu.get(i));
}
}
//把其他的按钮禁用
btn_add.setEnabled(false);
btn_delete.setEnabled(false);
btn_edit.setEnabled(false);
}
public void onDelete() throws Exception {
int[] rows = table.getSelectedRows();
if (rows.length == 0) return;
int select = JOptionPane.showConfirmDialog(this, "是否确定删除?","确定",JOptionPane.YES_NO_OPTION);
//0是确定按钮
//删除的时候一定要从后往前删,不然长度发生变化,会删错东西
if (select == 0) {
for (int i = rows.length - 1;i >= 0;i--) {
model.removeRow(rows[i]);
}
}
//保存数据
saveData();
}
public void saveData() throws Exception {
File file = new File("students.json");
int count = model.getRowCount();
JSONArray array = new JSONArray();
for (int i = 0;i<count;i++) {
JSONObject o = new JSONObject();
o.put("id", model.getValueAt(i, 0));
o.put("name", model.getValueAt(i, 1));
o.put("gender", model.getValueAt(i,2));
o.put("birthday", model.getValueAt(i, 3));
o.put("phone_number", model.getValueAt(i, 4));
array.put(o);
}
AfJSON.toFile(array, file, "UTF-8");
}
//读取文件数据并显示
public void loadData() throws Exception {
File file = new File("students.json");
if (!file.exists()) {
//创建文件
file.createNewFile();
return;
}
if (file.length() == 0) {
return;
}
table.removeAll();
JSONArray array = (JSONArray)AfJSON.fromFile(file, "UTF-8");
for(int i = 0;i<array.length();i++) {
String id = array.getJSONObject(i).getString("id");
String name = array.getJSONObject(i).getString("name");
String phone_number = array.getJSONObject(i).getString("phone_number");
String birthday = array.getJSONObject(i).getString("birthday");
boolean gender = array.getJSONObject(i).getBoolean("gender");
addTableRow(new student(id,name,phone_number,gender,birthday));
}
}
public JButton createToolButton(String text,String imgName) {
//加载图片资源
String ImgPath = "/icons/" + imgName;
URL url = getClass().getResource(ImgPath);
JButton btn = new JButton(text);
btn.setIcon(new ImageIcon(url));
btn.setToolTipText(text);
btn.setFocusPainted(false);
return btn;
}
public void addTableRow(student s) {
Vector<Object> rowData = new Vector<>();
rowData.add(s.getId());
rowData.add(s.getName());
rowData.add(s.getGender());
rowData.add(s.getBirthday());
rowData.add(s.getPhone_number());
model.addRow(rowData);
}
public void onEdit() {
int[] rows = table.getSelectedRows();
if (rows.length == 0) return;
int row = rows[0];//只编辑选中的所有行的第一行
student s = getTableRow(row);
Dialog_edit dia_edit = new Dialog_edit(this);
dia_edit.setStudent(s);
if (dia_edit.exec()) {
student res = dia_edit.getStudent();
setTableRow(row,res);
try {
saveData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//返回当前row的student
public student getTableRow(int row) {
String id = (String)model.getValueAt(row, 0);
String name = (String)model.getValueAt(row, 1);
boolean gender = (boolean)model.getValueAt(row, 2);
String birthday = (String)model.getValueAt(row, 3);
String phone_number = (String)model.getValueAt(row, 4);
student s = new student(id,name,phone_number,gender,birthday);
return s;
}
//设置指定行的数据
public void setTableRow(int row,student s) {
model.setValueAt(s.getId(), row, 0);
model.setValueAt(s.getName(), row, 1);
model.setValueAt(s.getGender(), row, 2);
model.setValueAt(s.getBirthday(), row, 3);
model.setValueAt(s.getPhone_number(), row, 4);
}
}
上面的AfJSON是自定义的一个工具类,可以将数据通过JASONObject和JASONArray保存起来并写入文件中,AfJASON定义了几个方法,方便我们对文件进行操作
同样的AfRowLayout和AfColumnLayout都是自定义的布局类,可以方便我们对竖直和水平的控件进行布局,其中定义的方法padding可以设置控件四周的留白,初始化方法传入的参数可以让控件之间相隔一段距离。
这里我们是将数据保存在JSON中(轻量级),也可以换成数据库
IDColunmRender.java(对表格中ID列进行特殊的绘制)
public class IDColumnRender extends JCheckBox implements TableCellRenderer{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
this.setSelected(isSelected);
this.setText((String)value);
// 背景设置
this.setOpaque(true);
if (isSelected) {
this.setBackground(table.getSelectionBackground());
this.setForeground(table.getSelectionForeground());
} else {
this.setBackground(table.getBackground());
this.setForeground(table.getForeground());
}
return this;
}
}
GenderColumnRender.java(对表格中的Gender性别列进行特殊绘制)
public class GenderColumnRender extends JLabel implements TableCellRenderer{
public GenderColumnRender() {
//设置cell的格式
this.setHorizontalAlignment(SwingConstants.CENTER);
this.setFont(this.getFont().deriveFont(Font.PLAIN));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Boolean gender = (boolean)value;
if (gender != null && gender == 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());
}
if (hasFocus) {
this.setBorder(BorderFactory.createLineBorder(Color.blue));
}
else {
this.setBorder(null);
}
return this;
}
}
Dialog_new.java(点击添加按钮时弹出的对话框)
public class Dialog_new extends JDialog{
/*
* 控件的声明
*/
public JTextField tf_id = new JTextField(20);
public JTextField tf_name = new JTextField(20);
public JTextField tf_birthday = new JTextField(20);
public JTextField tf_phone_number = new JTextField(20);
public JButton btn_ok = new JButton("确定");
public JComboBox<String> cb_gender = new JComboBox<>();
public Boolean retValue = false; //表示可以返回,
public Dialog_new(JFrame owner) {
super(owner,"添加",true);
//设置大小
this.setSize(new Dimension(300,300));
//设置父容器
AfPanel root = new AfPanel();
this.setContentPane(root);
root.padding(10);
root.setLayout(new AfColumnLayout());
//设置主面板
AfPanel main = new AfPanel();
root.add(main,"1w");
main.setLayout(new AfColumnLayout(10));
main.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
main.padding(10);
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("学号"),"50px");
row.add(tf_id,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("姓名"),"50px");
row.add(tf_name,"1w");
}
if (true) {
cb_gender.addItem("女");
cb_gender.addItem("男");
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("性别"),"50px");
row.add(cb_gender,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("生日"),"50px");
row.add(tf_birthday,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("手机号"),"50px");
row.add(tf_phone_number,"1w");
}
if (true) {
AfPanel buttom = new AfPanel();
buttom.setLayout(new AfRowLayout());
main.add(buttom,"1w");
JLabel label = new JLabel();
buttom.add(label,"1w"); //占位
buttom.add(btn_ok,"auto");
}
btn_ok.addActionListener((e)->{
if (check_Value()) {
retValue = true;
this.setVisible(false);
}
});
}
//显示的方法
public boolean exec() {
Rectangle frameRect = this.getParent().getBounds();
int width = this.getWidth();
int height = this.getHeight();
int x = frameRect.x + (frameRect.width - width) / 2;
int y = frameRect.y + (frameRect.height - height) / 2;
this.setBounds(new Rectangle(x,y,width,height));
this.setVisible(true);
return retValue;
}
public Boolean check_Value() {
student s = getStudent();
if (s.getName().isEmpty()) {
JOptionPane.showMessageDialog(this,"姓名不能为空!");
return false;
}
if (s.getId().isEmpty()) {
JOptionPane.showMessageDialog(this, "学号不能为空!");
return false;
}
return true;
}
public student getStudent() {
String id = tf_id.getText().trim();
String name = tf_name.getText().trim();
String birthday = tf_birthday.getText().trim();
String phone_number = tf_phone_number.getText().trim();
Boolean gender = cb_gender.getSelectedIndex() == 1;
student s = new student(id,name,phone_number,gender,birthday);
return s;
}
}
Dialog_exit.java(点击编辑弹出的对话框)
public class Dialog_edit extends JDialog{
/*
* 控件的声明
*/
public JTextField tf_id = new JTextField(20);
public JTextField tf_name = new JTextField(20);
public JTextField tf_birthday = new JTextField(20);
public JTextField tf_phone_number = new JTextField(20);
public JButton btn_ok = new JButton("确定");
public JComboBox<String> cb_gender = new JComboBox<>();
public Boolean retValue = false; //表示可以返回,
public Dialog_edit(JFrame owner) {
super(owner,"添加",true);
//设置大小
this.setSize(new Dimension(300,300));
//设置父容器
AfPanel root = new AfPanel();
this.setContentPane(root);
root.padding(10);
root.setLayout(new AfColumnLayout());
//设置主面板
AfPanel main = new AfPanel();
root.add(main,"1w");
main.setLayout(new AfColumnLayout(10));
main.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
main.padding(10);
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("学号"),"50px");
row.add(tf_id,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("姓名"),"50px");
row.add(tf_name,"1w");
}
if (true) {
cb_gender.addItem("女");
cb_gender.addItem("男");
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("性别"),"50px");
row.add(cb_gender,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("生日"),"50px");
row.add(tf_birthday,"1w");
}
if (true) {
AfPanel row = new AfPanel();
main.add(row,"1w");
row.setLayout(new AfRowLayout(10));
row.add(new JLabel("手机号"),"50px");
row.add(tf_phone_number,"1w");
}
if (true) {
AfPanel buttom = new AfPanel();
buttom.setLayout(new AfRowLayout());
main.add(buttom,"1w");
JLabel label = new JLabel();
buttom.add(label,"1w"); //占位
buttom.add(btn_ok,"auto");
}
btn_ok.addActionListener((e)->{
if (check_Value()) {
retValue = true;
this.setVisible(false);
}
});
}
//显示的方法
public boolean exec() {
Rectangle frameRect = this.getParent().getBounds();
int width = this.getWidth();
int height = this.getHeight();
int x = frameRect.x + (frameRect.width - width) / 2;
int y = frameRect.y + (frameRect.height - height) / 2;
this.setBounds(new Rectangle(x,y,width,height));
this.setVisible(true);
return retValue;
}
public Boolean check_Value() {
student s = getStudent();
if (s.getName().isEmpty()) {
JOptionPane.showMessageDialog(this,"姓名不能为空!");
return false;
}
if (s.getId().isEmpty()) {
JOptionPane.showMessageDialog(this, "学号不能为空!");
return false;
}
return true;
}
public student getStudent() {
String id = tf_id.getText().trim();
String name = tf_name.getText().trim();
String birthday = tf_birthday.getText().trim();
String phone_number = tf_phone_number.getText().trim();
Boolean gender = cb_gender.getSelectedIndex() == 1;
student s = new student(id,name,phone_number,gender,birthday);
return s;
}
public void setStudent(student s) {
tf_id.setText(s.getId());
tf_name.setText(s.getName());
tf_birthday.setText(s.getBirthday());
tf_phone_number.setText(s.getPhone_number());
cb_gender.setSelectedIndex(s.getGender()?1:0);
}
}