swing获取文本框内容_Swing 使用 JTable详解

步骤1:基本表格步骤2:JScrollPane步骤3:列宽步骤4:TableModel步骤5:进一步理解TableModel步骤6:TableModel 与DAO结合步骤7:TableSelectionModel步骤8:更新Table步骤9:输入项验证步骤10:选中指定行

示例 1 : 基本表格
显示一个Table需要两组数据
1. 一维数组: String[]columnNames 表示表格的标题
2. 二维数组: String[][] heros 表格中的内容
默认情况下,表格的标题是不会显示出来了,除非使用了JScrollPane

b2c44a25c50d2239b7ce60181233a6ec.png

package gui;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JTable;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());// 表格上的titleString[] columnNames = new String[] { "id", "name", "hp", "damage" };// 表格中的内容,是一个二维数组String[][] heros = new String[][] { { "1", "盖伦", "616", "100" },{ "2", "提莫", "512", "102" }, { "3", "奎因", "832", "200" } };JTable t = new JTable(heros, columnNames);f.add(t, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 2 : JScrollPane
JScrollPane: 带滚动条的Panel
把table放进去就可以看到table的title
同样的把textarea放进去,并且textarea内容够长的话,就会看到滚动条

764914cfe3bd46e818542c7e914e5622.png

package gui;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTable;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());String[] columnNames = new String[] { "id", "name", "hp", "damage" };String[][] heros = new String[][] { { "1", "盖伦", "616", "100" },{ "2", "提莫", "512", "102" }, { "3", "奎因", "832", "200" } };JTable t = new JTable(heros, columnNames);// 根据t创建 JScrollPaneJScrollPane sp = new JScrollPane(t);//或则创建一个空的JScrollPane,再通过setViewportView把table放在JScrollPane中// JScrollPane sp = new JScrollPane(t);// sp.setViewportView(t);// 把sp而非JTable加入到JFrame上,f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 3 : 列宽
设置列宽度

88add2badf71a3794798e639260a4870.png

package gui;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTable;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());String[] columnNames = new String[] { "id", "name", "hp", "damage" };String[][] heros = new String[][] { { "1", "盖伦", "616", "100" },{ "2", "提莫", "512", "102" }, { "3", "奎因", "832", "200" } };JTable t = new JTable(heros, columnNames);JScrollPane sp = new JScrollPane(t);// 设置列宽度t.getColumnModel().getColumn(0).setPreferredWidth(10);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 4 : TableModel
首先说下TableModel的设计思想,在Model这种思想的指导下,数据和显示分离开来了。 比如对于JTable而言,有数据部分,也有显示部分(比如列宽等信息)。 数据部分,专门做一个类,叫做TableModel,就用于存放要显示的数据。
使用TableModel的方式存放Table需要显示的数据
HeroTableModel 继承AbstractTableModel ,进而实现了接口TableModel
在HeroTableModel 中提供一个table显示需要的所有信息
1. getRowCount 返回一共有多少行
2. getColumnCount 返回一共有多少列
3. getColumnName 每一列的名字
4. isCellEditable 单元格是否可以修改
5. getValueAt 每一个单元格里的值
当图形界面需要渲染第一个单元格的数据的时候,就会调用方法TabelModel的getValueAt(0,0) ,把返回值拿到并显示

  • HeroTableModel.java
  • TestGUI.java

package gui;import javax.swing.table.AbstractTableModel;public class HeroTableModel extends AbstractTableModel {String[] columnNames = new String[] { "id", "name", "hp", "damage" };String[][] heros = new String[][] { { "1", "盖伦", "616", "100" },{ "2", "提莫", "512", "102" }, { "3", "奎因", "832", "200" } };// 返回一共有多少行public int getRowCount() {// TODO Auto-generated method stubreturn heros.length;}// 返回一共有多少列public int getColumnCount() {// TODO Auto-generated method stubreturn columnNames.length;}// 获取每一列的名称public String getColumnName(int columnIndex) {// TODO Auto-generated method stubreturn columnNames[columnIndex];}// 单元格是否可以修改public boolean isCellEditable(int rowIndex, int columnIndex) {return false;}// 每一个单元格里的值public Object getValueAt(int rowIndex, int columnIndex) {// TODO Auto-generated method stubreturn heros[rowIndex][columnIndex];}}package gui;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTable;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());//创建一个TableModelHeroTableModel htm= new HeroTableModel();//根据 TableModel来创建 TableJTable t = new JTable(htm);JScrollPane sp = new JScrollPane(t);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 5 : 进一步理解TableModel
在使用TableModel之前,是使用String[] columnNames =。。。String[][] heros = 。。。JTable t = new JTable(heros, columnNames);
这样的风格创建一个JTable的
所以实际上调用的是如下的构造方法:JTable(Object[][] rowData, Object[] columnNames)
如图所示,在JTable的的源代码中,它就会根据rowData和columnNames去创建一个TableModel对象

4b6033ac618471c5cb39ba9b0b9df45e.png

示例 6 : TableModel 与DAO结合
通过TableModel与DAO结合显示数据库中Hero信息。
DAO使用HeroDAO
在TableModel中,使用从DAO返回的List作为TableModel的数据
只需要修改HeroTableModel,无需修改TestGUI。 这正好演绎了Model设计思想中的数据分离的好处,当只需要数据发生变化的时候,修改Model即可,界面GUI部分,不需要做任何改动

c5c235e27ed627ef96687647579f7f63.png

package gui;import java.util.List;import javax.swing.table.AbstractTableModel;import jdbc.HeroDAO;import charactor.Hero;public class HeroTableModel extends AbstractTableModel {String[] columnNames = new String[] { "id", "name", "hp", "damage" };// 使用从DAO返回的List作为TableModel的数据public List<Hero> heros = new HeroDAO().list();// heros.size返回一共有多少行public int getRowCount() {// TODO Auto-generated method stubreturn heros.size();}public int getColumnCount() {// TODO Auto-generated method stubreturn columnNames.length;}public String getColumnName(int columnIndex) {// TODO Auto-generated method stubreturn columnNames[columnIndex];}public boolean isCellEditable(int rowIndex, int columnIndex) {return false;}// 先通过heros.get(rowIndex)获取行对应的Hero对象// 然后根据columnIndex返回对应的属性public Object getValueAt(int rowIndex, int columnIndex) {Hero h = heros.get(rowIndex);if (0 == columnIndex)return h.id;if (1 == columnIndex)return h.name;if (2 == columnIndex)return h.hp;if (3 == columnIndex)return h.damage;return null;}}示例 7 : TableSelectionModel
通过table可以获取一个 TableSelectionModel,专门用于监听jtable选中项的变化

c56f7a79c8202c597f1c40c3e3c10ba7.png

package gui;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import charactor.Hero;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());final HeroTableModel htm = new HeroTableModel();final JTable t = new JTable(htm);// 准备一个Panel上面放一个Label用于显示哪条被选中了JPanel p = new JPanel();final JLabel l = new JLabel("暂时未选中条目");p.add(l);JScrollPane sp = new JScrollPane(t);// 使用selection监听器来监听table的哪个条目被选中t.getSelectionModel().addListSelectionListener(new ListSelectionListener() {// 当选择了某一行的时候触发该事件public void valueChanged(ListSelectionEvent e) {// 获取哪一行被选中了int row = t.getSelectedRow();// 根据选中的行,到HeroTableModel中获取对应的对象Hero h = htm.heros.get(row);// 更新标签内容l.setText("当前选中的英雄是: " + h.name);}});f.add(p, BorderLayout.NORTH);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 8 : 更新Table
以新增数据到数据库中,然后更新Table为例

0643afa75043190734c5a88492ac48cd.png

package gui;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.JTextField;import jdbc.HeroDAO;import charactor.Hero;public class TestGUI {public static void main(String[] args) {JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());final HeroTableModel htm = new HeroTableModel();final JTable t = new JTable(htm);// 增加 一个 panel用于放置名称,血量输入框和增加 按钮JPanel p = new JPanel();final JLabel lName = new JLabel("名称");final JTextField tfName = new JTextField("");final JLabel lHp = new JLabel("血量");final JTextField tfHp = new JTextField("");JButton bAdd = new JButton("增加");tfName.setPreferredSize(new Dimension(80, 30));tfHp.setPreferredSize(new Dimension(80, 30));p.add(lName);p.add(tfName);p.add(lHp);p.add(tfHp);p.add(bAdd);// 为增加按钮添加监听bAdd.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {HeroDAO dao = new HeroDAO();// 根据输入框数据创建一个Hero对象Hero h = new Hero();h.name = tfName.getText();h.hp = Integer.parseInt(tfHp.getText());// 通过dao把该对象加入到数据库dao.add(h);// 通过dao更新tablemodel中的数据htm.heros = dao.list();// 调用JTable的updateUI,刷新界面。// 刷新界面的时候,会到tablemodel中去取最新的数据// 就能看到新加进去的数据了t.updateUI();}});JScrollPane sp = new JScrollPane(t);f.add(p, BorderLayout.NORTH);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 9 : 输入项验证
如果用户输入的名称为空,或者血量不是小数,在提交数据的时候都会报错。“感觉上” 界面就卡住了。 这是不友好的人机交互行为。
所以需要加上输入项的验证,如果输入的数据不合格,应该弹出对话框提示用户具体原因。

51b944c94ddd416065a7be8aac8cc5a5.png

package gui;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;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 jdbc.HeroDAO;import charactor.Hero;public class TestGUI {public static void main(String[] args) {final JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());final HeroTableModel htm = new HeroTableModel();final JTable t = new JTable(htm);JPanel p = new JPanel();final JLabel lName = new JLabel("名称");final JTextField tfName = new JTextField("");final JLabel lHp = new JLabel("血量");final JTextField tfHp = new JTextField("");JButton bAdd = new JButton("增加");tfName.setPreferredSize(new Dimension(80, 30));tfHp.setPreferredSize(new Dimension(80, 30));p.add(lName);p.add(tfName);p.add(lHp);p.add(tfHp);p.add(bAdd);bAdd.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {HeroDAO dao = new HeroDAO();Hero h = new Hero();String name = tfName.getText();// 通过name长度判断 名称是否为空if (name.length() == 0) {// 弹出对话框提示用户JOptionPane.showMessageDialog(f, "名称不能为空");// 名称输入框获取焦点tfName.grabFocus();return;}String hp = tfHp.getText().trim();try {// 把hp转换为浮点型,如果出现异常NumberFormatException表示不是浮点型格式Float.parseFloat(hp);} catch (NumberFormatException e1) {JOptionPane.showMessageDialog(f, "血量只能是小数 ");tfHp.grabFocus();return;}h.name = name;h.hp = Float.parseFloat(hp);dao.add(h);htm.heros = dao.list();t.updateUI();}});JScrollPane sp = new JScrollPane(t);f.add(p, BorderLayout.NORTH);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}示例 10 : 选中指定行
1. table初始化后,应该默认选中第一行
2. 增加数据后,也应该选中新增的这一条

7aaac6ca191199037651d4aa8417b97f.png

package gui;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;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.ListSelectionModel;import jdbc.HeroDAO;import charactor.Hero;public class TestGUI {public static void main(String[] args) {final JFrame f = new JFrame("LoL");f.setSize(400, 300);f.setLocation(200, 200);f.setLayout(new BorderLayout());final HeroTableModel htm = new HeroTableModel();final JTable t = new JTable(htm);// 设置选择模式为 只能选中一行t.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 选中第一行 (基本0)t.getSelectionModel().setSelectionInterval(0, 0);JPanel p = new JPanel();final JLabel lName = new JLabel("名称");final JTextField tfName = new JTextField("");final JLabel lHp = new JLabel("血量");final JTextField tfHp = new JTextField("");JButton bAdd = new JButton("增加");tfName.setPreferredSize(new Dimension(80, 30));tfHp.setPreferredSize(new Dimension(80, 30));p.add(lName);p.add(tfName);p.add(lHp);p.add(tfHp);p.add(bAdd);bAdd.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {HeroDAO dao = new HeroDAO();Hero h = new Hero();String name = tfName.getText();if (name.length() == 0) {JOptionPane.showMessageDialog(f, "名称不能为空");tfName.grabFocus();return;}String hp = tfHp.getText().trim();try {Float.parseFloat(hp);} catch (NumberFormatException e1) {JOptionPane.showMessageDialog(f, "血量只能是小数 ");tfHp.grabFocus();return;}h.name = name;h.hp = Float.parseFloat(hp);dao.add(h);htm.heros = dao.list();t.updateUI();// 选中 第一行 ,因为 DAO是按照 ID倒排序查询,所以第一行就是新加入的数据t.getSelectionModel().setSelectionInterval(0, 0);}});JScrollPane sp = new JScrollPane(t);f.add(p, BorderLayout.NORTH);f.add(sp, BorderLayout.CENTER);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);}}
更多内容,点击了解: https://how2j.cn/k/gui/gui-table/410.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值