JTable组件中的绘制器和编辑器

本文介绍如何在Java Swing的JTable中自定义颜色单元格的绘制器和编辑器,并展示了如何通过覆盖getColumnClass方法来确保表格列类型的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JTable填充模型有两种方式,一种是构造JTable时指定行数组和列名数组,这种方式数据会以字符串的形式显示在表格中,因为模型得到的所有列的类型都为String。另一种方式是用TableModel填充表格。应该覆盖getColumnClass方法让模型得到每一列的正确类型。此时值为boolean类型的单元格会绘制为JCheckBox,String类型的值会绘制为JLabel(默认绘制器)。如果有其他类型的值,如Color,还是会绘制为JLabel,因为Color没有默认的绘制器。如果想以自己的形式绘制Color,需要定制自己的绘制器。JTable类中有一个Hashtable用来保存所有的类型和绘制器的关联,调用JTable的setDefaultRenderer方法可以将类型和默认绘制器关联。绘制器是一个实现了TableCellRenderer接口的对象,该接口只有一个方法 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)。当单元格需要绘制时就会使用这个方法的返回值绘制单元格。如果想绘制Color类型的数据可以在这个方法中返回一个带颜色的面板。

自定义绘制器代码:

package com.swing.table;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

import com.swing.base.SuperFrame;

/**
 * This program demonstrates how to show a simple table
 * @version 1.11 2007-08-01
 * @author Cay Horstmann
 */
public class TableTest {
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				JFrame frame = new PlanetTableFrame();
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setVisible(true);
			}
		});
	}
}

/**
 * This frame contains a table of planet data.
 */
class PlanetTableFrame extends SuperFrame {
	public PlanetTableFrame() {
		setTitle("TableTest");
		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		TableModel model = new MyTableModel();
		final JTable table = new JTable(model);
		table.setAutoCreateRowSorter(true);// 自动排序
		table.setFillsViewportHeight(true);// 填充视口
		table.setDefaultRenderer(Color.class, new ColorRender());// 设置渲染器
		//table.setDefaultEditor(Color.class, new ColorTableCellEditor());// 设置编辑器
		table.setRowSelectionAllowed(false);

		add(new JScrollPane(table), BorderLayout.CENTER);
		JButton printButton = new JButton("Print");
		printButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				try {
					table.print();
				} catch (java.awt.print.PrinterException e) {
					e.printStackTrace();
				}
			}
		});
		JPanel buttonPanel = new JPanel();
		buttonPanel.add(printButton);
		add(buttonPanel, BorderLayout.SOUTH);
	}

	// 颜色单元格绘制器
	private class ColorRender extends JPanel implements TableCellRenderer {
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
				boolean hasFocus, int row, int column) {
			setBackground((Color) value);
			if (hasFocus)
				setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
			else
				setBorder(null);
			return this;
		}

	}

	// 颜色单元格编辑器
	private class ColorTableCellEditor extends AbstractCellEditor implements TableCellEditor {
		public ColorTableCellEditor() {
			panel = new JPanel();
			chooser = new JColorChooser();
			dialog = JColorChooser.createDialog(null, "Planet Color", false, chooser, new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					stopCellEditing();// 会调用getCellEditorValue方法的值更改模型数据
				}
			}, new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					cancelCellEditing();				}
			});
			dialog.addWindowListener(new WindowAdapter() {
				@Override
				public void windowClosing(WindowEvent e) {
					cancelCellEditing();
				}
			});
		}

		// 编辑单元格时这个组件会暂时取代绘制器
		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
			chooser.setColor((Color) value);
			return panel;
		}

		@Override
		public boolean shouldSelectCell(EventObject anEvent) {
			dialog.setVisible(true);
			return true;
		}

		@Override
		public void cancelCellEditing() {
			dialog.setVisible(false);
			super.cancelCellEditing();
		}

		@Override
		public boolean stopCellEditing() {
			dialog.setVisible(false);
			super.stopCellEditing();
			return true;
		}

		public Color getCellEditorValue() {
			return chooser.getColor();
		}

		@Override
		public boolean isCellEditable(EventObject e) {
			// TODO 自动生成方法存根
			return true;
		}

		private JColorChooser chooser;
		private JDialog dialog;
		private JPanel panel;
	}

	private static final int DEFAULT_WIDTH = 400;
	private static final int DEFAULT_HEIGHT = 200;
}

class MyTableModel extends AbstractTableModel {

	public int getColumnCount() {
		return columnNames.length;
	}

	public int getRowCount() {
		return cells.length;
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		return cells[rowIndex][columnIndex];
	}

	@Override
	public String getColumnName(int column) {
		// TODO 自动生成方法存根
		return columnNames[column];
	}

	@Override
	//如果不覆盖这个方法每列的类型都为String
	public Class<?> getColumnClass(int columnIndex) {
		return cells[0][columnIndex].getClass();
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return true;
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		cells[rowIndex][columnIndex] = aValue;
	}

	private Object[][] cells = { { "Mercury", 2440.0, 0, false, Color.YELLOW },
			{ "Venus", 6052.0, 0, false, Color.YELLOW }, { "Earth", 6378.0, 1, false, Color.BLUE },
			{ "Mars", 3397.0, 2, false, Color.RED }, { "Jupiter", 71492.0, 16, true, Color.ORANGE },
			{ "Saturn", 60268.0, 18, true, Color.ORANGE }, { "Uranus", 25559.0, 17, true, Color.BLUE },
			{ "Neptune", 24766.0, 8, true, Color.BLUE }, { "Pluto", 1137.0, 1, false, Color.BLACK } };

	private String[] columnNames = { "Planet", "Radius", "Moons", "Gaseous", "Color" };

}


 可以看到布尔类型和Color类型的值都使用了绘制器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值