Java表格模型事件示例

本文介绍了一个使用Java Swing实现的表格模型事件示例。通过监听表格模型事件,可以捕获到表格数据变化的情况,例如插入、删除和更新操作。此外,还展示了如何设置表格的选择模式,并实现了类似Excel中的多列选择功能。

package com.han;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import java.util.Vector;

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 javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

/**
 * 表格模型事件示例
 * <p>
 * <li>A component generally gains the focus when the user clicks it, 
 * or when the user tabs between components, or otherwise interacts 
 * with a component. A component can also be given the focus programmatically,
 * such as when its containing frame or dialog-box is made visible. 
 * The snippet of the codes below shows how to give a particular component  
 * the focus every time the window gains the focus.
 * 
 * @author HAN
 * 
 */
public class TableModelEvent_1 extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8581492063632813033L;

	public TableModelEvent_1() {
		// TODO Auto-generated constructor stub
		final Container container = getContentPane();
		Vector<String> tableColumnNames = new Vector<String>();
		tableColumnNames.add("A");
		tableColumnNames.add("B");
		Vector<Vector<String>> tableValues = new Vector<Vector<String>>();
		for (int i = 1; i < 5; i++) {
			Vector<String> vector = new Vector<String>();
			vector.add("A" + i);
			vector.add("B" + i);
			tableValues.add(vector);
		}
		final DefaultTableModel defaultTableModel = new DefaultTableModel(
				tableValues, tableColumnNames);
		final JTable table = new JTable(defaultTableModel);
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setViewportView(table);
		container.add(scrollPane, BorderLayout.CENTER);
		JPanel panel = new JPanel();
		container.add(panel, BorderLayout.SOUTH);
		JLabel labelA = new JLabel("A: ");
		final JTextField textFieldA = new JTextField(15);
		JLabel labelB = new JLabel("B: ");
		final JTextField textFieldB = new JTextField(15);
		JButton buttonAdd = new JButton("添加");
		JButton buttonDel = new JButton("删除");
		JButton buttonDeselected = new JButton("取消选择");
		panel.add(labelA);
		panel.add(textFieldA);
		panel.add(labelB);
		panel.add(textFieldB);
		panel.add(buttonAdd);
		panel.add(buttonDel);
		panel.add(buttonDeselected);
		buttonAdd.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int[] selectedRows = table.getSelectedRows(); // table
																// 默认情况容许多行选择
				Vector<String> rowData = new Vector<String>();
				rowData.add(textFieldA.getText());
				rowData.add(textFieldB.getText());
				if (selectedRows.length == 0) {
					defaultTableModel.addRow(rowData);
					textFieldA.setText(null);
					textFieldB.setText(null);
				} else if (selectedRows.length == 1) {
//					System.out.println(selectedRows[0]);
					defaultTableModel.insertRow(selectedRows[0] + 1, rowData);
					textFieldA.setText(null);
					textFieldB.setText(null);
				} else {
					JOptionPane.showMessageDialog(container,
							"Your operation is forbidden", "Warning",
							JOptionPane.WARNING_MESSAGE);
				}
			}

		});
		buttonDel.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int[] selectedRows = table.getSelectedRows(); // table
																// 默认情况容许多行选择
				for (int i = 0; i < selectedRows.length; i++) {
//					System.out.println(selectedRows[i]);
					defaultTableModel.removeRow(selectedRows[i] - i);
				}
			}

		});
		buttonDeselected.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				table.clearSelection();
			}

		});
		scrollPane.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
//				 System.out.println("here");
				if (e.getClickCount() == 1
						&& e.getButton() == MouseEvent.BUTTON1) {
					table.clearSelection();
				}
			}
		});
		
		// make the text field focused every time the window is activated
		addWindowFocusListener(new WindowAdapter() {

			@Override
			public void windowGainedFocus(WindowEvent e) {
				// TODO Auto-generated method stub
				textFieldA.requestFocus(); 
			}
			
		});

		// **************************************************************
		// This is a standard snippet to realize the desired column selection as in
		// Excel
		// **************************************************************

		// row selection mode
		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		// column selection mode
		TableColumnModel tableColumnModel = table.getColumnModel();
		tableColumnModel.getSelectionModel().setSelectionMode(
				ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		// allow the column selection (the row selection is allowed by default)
		table.setColumnSelectionAllowed(true);
		final JTableHeader tableHeader = table.getTableHeader();
		tableHeader.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				// Extended modifiers represent the state of all modal keys,
				// such as ALT, CTRL, META.
				if (e.getClickCount() == 1
						&& e.getButton() == MouseEvent.BUTTON1) {
					// Point point = new Point(e.getX(), e.getY());
					Point point = new Point(e.getPoint());
					int columnNum = tableHeader.columnAtPoint(point);
					// System.out.println(columnNum);
					int[] selectedColumns = table.getSelectedColumns();
					if (selectedColumns.length != 0) {
						// System.out.println("here1");
						// System.out.println(InputEvent.getModifiersExText(e.getModifiersEx()));
						if (e.getModifiersEx() == (InputEvent.CTRL_DOWN_MASK)) {
//							System.out.println("ctrl");
							if (Arrays.binarySearch(selectedColumns, columnNum) >= 0) {
								table.removeColumnSelectionInterval(columnNum,
										columnNum);
							} else {
								table.addColumnSelectionInterval(columnNum,
										columnNum);
							}
						} else if (e.getModifiersEx() == (InputEvent.SHIFT_DOWN_MASK)) {
							// System.out.println("shift");
							table.setColumnSelectionInterval(
									selectedColumns[0], columnNum);
						} else {
							table.setColumnSelectionInterval(columnNum,
									columnNum);
						}
					} else {
						// System.out.println("here2");
						table.setColumnSelectionInterval(columnNum, columnNum);
					}
					table.setRowSelectionInterval(0, table.getRowCount() - 1);
				}
			}
		});
		
		defaultTableModel.addTableModelListener(new TableModelListener() {

			@Override
			public void tableChanged(TableModelEvent e) {
				// TODO Auto-generated method stub
				int type = e.getType();
				int firstRow = e.getFirstRow();
//				int lastRow = e.getLastRow(); // the last row seems to be always equal to the first row
				int column = e.getColumn();
				switch (type) {
				case TableModelEvent.DELETE:
					System.out.print("此次事件由 删除 行触发:");
					System.out.println("此次删除的是第 " + firstRow + " 行");
					break;
				case TableModelEvent.INSERT:
					System.out.print("此次事件由 插入 行触发:");
					System.out.println("此次插入的是第 " + firstRow + " 行");
					break;
				case TableModelEvent.UPDATE:
					System.out.print("此次事件由 更新 行触发:");
					System.out.println("此次更新的是第 " + firstRow + " 行第 " + column + " 列");
					break;
				default:
					System.out.println("此次事件由 其他原因 触发");
				}
			}

		});
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TableModelEvent_1 frame = new TableModelEvent_1();
		frame.setTitle("表格模型事件示例");
		frame.pack(); //Realize the components.
//		frame.setBounds(100, 100, 600, 300);
//		textFieldA.requestFocus();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true); //Display the window.
	}

}


使用 AbstractTableModel 构建Table 在表格中添加JButton按钮,之前在网上找了2天没有找到好用的程序,最终终于找到一个好用的例子。 不要使,我退你们分。。 sing the Swing JTable class can quickly become a sticky business when you want to customize it to your specific needs. First you must become familiar with how the JTable class is organized. Individual cells are rendered by TableCellRenderer implementations. The table contents are represented by an implementation of the TableModel interface. By default, JTable uses DefaultTableCellRenderer to draw its cells. DefaultTableCellRenderer recognizes a few primitive types, rendering them as strings, and can even display Boolean types as checkboxes. But it defaults to displaying the value returned by toString() for types it does not specifically handle. You have to provide your own TableCellRenderer implementation if you want to display buttons in a JTable. The TableCellRenderer interface contains only one method, getTableCellRendererComponent(...), which returns a java.awt.Component that knows how to draw the contents of a specific cell. Usually, getTableCellRendererComponent() will return the same component for every cell of a column, to avoid the unnecessary use of extra memory. But when the contents of a cell is itself a component, it is all right to return that component as the renderer. Therefore, the first step towards having JButtons display correctly in a JTable is to create a TableCellRenderer implementation that returns the JButton contained in the cell being rendered. In the accompanying code listing, JTableButtonRenderer demonstrates how to do this. Even after creating a custom TableCellRenderer, you're still not done. The TableModel associated with a given JTable does not only keep track of the contents of each cell, but it also keeps track of the class of data stored in each column. DefaultTableModel is designed to work with DefaultTableCellRenderer and will return java.lang.String.class for columns containing data types that it does not specifically handle. The exact method that does this is getColumnClass(int column). Your second step is to create a TableModel implementation that returns JButton.class for cells that contain JButtons. JTableButtonModel shows one way to do this. It just returns the result of getClass() for each piece of cell data. At this point, you're almost done, but not quite. What's the use of putting a JButton in a JTable if you can't press the darn thing? By default, JTable will not forward mouse events to components contained in its cells. If you want to be able to press the buttons you add to JTable, you have to create your own MouseListener that forwards events to the JButton cells. JTableButtonMouseListener demonstrates how you could do this.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值