关于SWING组件的简单研究
JTable篇(图文混排)
关键字:Java ,SWING,JTable,UI,图文混排,
项目需要用SWING,所以进行了简单的研究。现将成果简单说明,希望能够对各位有所帮助。
MVC模型:
详细使用Java的各位对于MVC模型应该不会陌生。Java的Swing,在设计之初,就全面按照,MVC模型的标准设计自己的组件。Swing的任何一个组件,都可以很方便的应用MVC模型的概念对其进行用户自定义的改造。
JTable 改造后的效果。
1, 每行每个单元格的前景色和背景色都可以变化。
2, 每个单元格都可以插入图片。
如图:

第一步,实现TableCellRenderer
接口javax.swing.table.TableCellRenderer定义了要成为JTable中单元格渲染器的任意对象所需的方法。当JTable每次重绘,都会调用该接口的实例。
其中方法Component getTableCellRendererComponent(JTable table,Object value,Boolean isSelected,Boolean hasFocus,int row,int column)就是绘制每个单元格的函数。
参数:
table - 要求渲染器绘制的 JTable;可以为 null
value - 要呈现的单元格的值。由具体的渲染器解释和绘制该值。例如,如果 value 是字符串 "true",则它可呈现为字符串,或者也可呈现为已选中的复选框。null 是有效值
isSelected - 如果使用选中样式的突出显示来呈现该单元格,则为 true;否则为 false
hasFocus - 如果为 true,则适当地呈现单元格。例如,在单元格上放入特殊的边框,如果可以编辑该单元格,则以彩色呈现它,用于指示正在进行编辑
row - 要绘制的单元格的行索引。绘制头时,row 值是 -1
column - 要绘制的单元格的列索引
我们的重点就是实现这个函数。(稍后看代码)
第二步,创建一个TableModel继承AbstractTableModel
我们为什么要创建一个TableModel呢?因为根据MVC的模型,用户的数据部分是和“实现”“表示”分离的。即,我们想在JTable上表示什么内容,和如何表示这些内容,是和JTable本身无关的,因此我们需要单独保存这些信息。这些信息被保存在MVC模型的M中。JTable的M部分的一个基类就是 javax.swing.table.AbstractTableModel
此抽象类为 MyTableModel 接口中的大多数方法提供默认实现。它负责管理侦听器,并为生成 TableModelEvents 以及将其调度到侦听器提供方便。要创建一个具体的 TableModel 作为 AbstractTableModel 的子类,只需提供对以下三个方法的实现:
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
我们都需要MyTableModel中保存那些信息呢?最主要的就是某行某列的单元格是什么样子,和装载的什么值。
为此我们定义一个类TableCellModel。
publicclass TableCellModel {
/*cell的宽度*/
privateintwidth = 0;
/*cell中的数据,可以使String 或 ImageIcon等等*/
private Object data = null;
/*cell的颜色*/
private Color cellColor = null;
/*cell的背景色*/
private Color cellBackgroundColor = null;
/*首行cell的颜色(用于表格的行交替颜色变化)*/
private Color cellFirstBackgroundColor = null;
/**获得Cell颜色
*
*/
public Color getCellColor() {
returncellColor;
}
/**cell颜色设置
*
*/
publicvoid setCellColor(Color cellColor) {
this.cellColor = cellColor;
}
/**获得Cell的数据
*
*/
public Object getData() {
returndata;
}
/**设置Cell的数据
*
*/
publicvoid setData(Object data) {
this.data = data;
}
/**获得Cell的宽度
*
*/
publicint getWidth() {
returnwidth;
}
/**设置Cell的宽度
*
*/
publicvoid setWidth(int width) {
this.width = width;
}
/**获得Cell的背景色
*
*/
public Color getCellBackgroundColor() {
returncellBackgroundColor;
}
/**设置Cell的背景色
*
*/
publicvoid setCellBackgroundColor(Color cellBackgroundColor) {
this.cellBackgroundColor = cellBackgroundColor;
}
/**获得Cell首行的背景色
*
*/
public Color getCellFirstBackgroundColor() {
returncellFirstBackgroundColor;
}
/**设置Cell的首行背景色
*
*/
publicvoid setCellFirstBackgroundColor(Color cellFirstBackgroundColor) {
this.cellFirstBackgroundColor = cellFirstBackgroundColor;
}
}
TableCellModel将会以List的形式组织好后,赴值给MyTableModle。
MyTableModle的概要代码如下:
publicclassMyTableModel extends AbstractTableModel {
/*行是否能够被选择(代码不详细写了,比较简单)*/
private List canBeSelectedModel= null;
private List tableCellModel = null;
/*行数*/
privateintrowNumber = 0;
/*列数*/
privateintcolNumber = 0;
/*行背景色*/
private Color rowBackgroundColor = null;
/*首行背景色*/
private Color firstRowBackgroundColor = Color.white;
privateintdiv = 1;
/*每个单元格的对齐方式(代码不详细写了,比较简单)*/
private List cellLayout = null;
/*偏移量(没有用到)*/
privateintoffSet = 0;
privateinteditColNo = -1;
/*可编辑的前景色*/
private Color editColForeground = null;
/*可编辑的背景色*/
private Color editColBackground = null;
public Color getEditColBackground() {
returneditColBackground;
}
publicvoid setEditColBackground(Color editColBackground) {
this.editColBackground = editColBackground;
}
public Color getEditColForeground() {
returneditColForeground;
}
publicvoid setEditColForeground(Color editColForeground) {
this.editColForeground = editColForeground;
}
publicint getEditColNo() {
returneditColNo;
}
publicvoid setEditColNo(int editColNo) {
this.editColNo = editColNo;
}
publicvoid setCellLayout(List cellLayout) {
this.cellLayout = cellLayout;
}
publicint getRow() {
returnrowNumber;
}
publicint getRowCount() {
returnrowNumber;
}
publicint getColumnCount() {
return 1;
}
publicint getCol() {
returncolNumber;
}
publicvoid setCol(int col) {
this.colNumber = col;
}
publicvoid setRow(int row) {
this.rowNumber = row;
}
public List getTableCellModel() {
returntableCellModel;
}
publicvoid setTableCellModel(List tableCellModel) {
this.tableCellModel = tableCellModel;
}
public Color getColor(int row, int col) {
if((row+offSet) < rowNumber){
row= row+offSet;
}else{
row = rowNumber-1;
}
List rowData = (List)tableCellModel.get(row);
TableCellModel cellModel = (TableCellModel)rowData.get(col);
return cellModel.getCellColor();
}
public Color getCellBackgroundColor(int row, int col) {
if((row+offSet) < rowNumber){
row= row+offSet;
}else{
row = rowNumber-1;
}
List rowData = (List)tableCellModel.get(row);
TableCellModel cellModel = (TableCellModel)rowData.get(col);
return cellModel.getCellBackgroundColor();
}
public Color getCellFirstBackgroundColor(int row, int col) {
if((row+offSet) < rowNumber){
row= row+offSet;
}else{
row = rowNumber-1;
}
List rowData = (List)tableCellModel.get(row);
TableCellModel cellModel = (TableCellModel)rowData.get(col);
return cellModel.getCellFirstBackgroundColor();
}
publicint getCellLayout(int col) {
return (Integer)cellLayout.get(col);
}
publicint getWidth(int row, int col) {
if((row+offSet) < rowNumber){
row= row+offSet;
}else{
row = rowNumber-1;
}
if(tableCellModel != null){
List rowData = (List)tableCellModel.get(row);
if(rowData.size() <= col){
return 1;
}else{
TableCellModel cellModel = (TableCellModel)rowData.get(col);
return cellModel.getWidth();
}
}
return 1;
}
public Object getValueAt(int row, int col) {
if((row+offSet) < rowNumber){
row= row+offSet;
}else{
row = rowNumber-1;
}
if(tableCellModel != null){
List rowData = (List)tableCellModel.get(row);
if(rowData.size() <= col){
returnnull;
}else{
TableCellModel cellModel = (TableCellModel)rowData.get(col);
return cellModel.getData();
}
}
returnnull;
//return ((TableCellModel)((List)tableCellModel.get(row)).get(col)).getData();
}
public Color getRowBackgroundColor() {
returnrowBackgroundColor;
}
publicvoid setRowBackgroundColor(Color rowBackgroundColor) {
this.rowBackgroundColor = rowBackgroundColor;
}
publicint getOffSet() {
returnoffSet;
}
publicvoid setOffSet(int offSet) {
this.offSet = offSet;
}
public Color getFirstRowBackgroundColor() {
returnfirstRowBackgroundColor;
}
publicvoid setFirstRowBackgroundColor(Color firstRowBackgroundColor) {
this.firstRowBackgroundColor = firstRowBackgroundColor;
}
publicint getDiv() {
returndiv;
}
publicvoid setDiv(int div) {
this.div = div;
}
public List getCanBeSelectedModel() {
returncanBeSelectedModel;
}
publicvoid setCanBeSelectedModel(List canBeSelectedModel) {
this.canBeSelectedModel = canBeSelectedModel;
}
}
下面是最关键的JTableCellRenderer代码
publicclass JTableCellRenderer extends JPanel implements TableCellRenderer{
private JComponent[] component = null;
privatestaticfinallongserialVersionUID = 4814418916385836965L;
/*透明?*/
privatebooleanisOpaque = true;
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
/*透明?*/
isOpaque = table.isOpaque();
/*获得TableModel*/
MyTableModel myTableModel = (MyTableModel)table.getModel();
boolean canSelected = true;
List canSelectedList = myTableModel.getCanBeSelectedModel();
if(canSelectedList != null){
if(row < canSelectedList.size()){
if(!((Boolean)canSelectedList.get(row)).booleanValue()){
canSelected = false;
}
}else{
canSelected = false;
}
}
/*设定用于显示Cell的panel*/
JPanel cellPanel = new JPanel();
/*绘制Cell*/
getCell(table,cellPanel,row,canSelected,isSelected);
int colorChangeFlag = row/myTableModel.getDiv();
/*是否透明*/
if(isOpaque){
if(colorChangeFlag % 2 == 0){
cellPanel.setBackground(myTableModel.getRowBackgroundColor());
}else{
cellPanel.setBackground(myTableModel.getFirstRowBackgroundColor());
}
}
/*设定是否透明 */
cellPanel.setOpaque(isOpaque);
if(isSelected){
cellPanel.setBackground(table.getSelectionBackground());
}
rePaintComponents();
// MainRun.middlePanel.repaint();
return cellPanel;
}
privatevoid getCell(JTable table,JPanel cellPanel,int row,
boolean canSelected,boolean isSelected){
/*设定对齐方式*/
cellPanel.setLayout(new FlowLayout(0,0,0));
/*获得TableModel*/
MyTableModel myTableModel = (MyTableModel)table.getModel();
/*获得列数*/
int col = myTableModel.getCol();
for(int i = 0; i < col ; i++ ){
/*获得某个单元格*/
Object cellObject = myTableModel.getValueAt(row,i);
/**/
JComponent tempLabel = null;
/*String*/
if(cellObject instanceof String){
tempLabel = new JLabel((String)cellObject);
if(canSelected){
Color cellColor = myTableModel.getColor(row,i);
tempLabel.setForeground(cellColor);
}else{
tempLabel.setForeground(Color.gray);
}
if(isSelected){
tempLabel.setForeground(table.getSelectionForeground());
}
/*Icon*/
}elseif(cellObject instanceof ImageIcon){
tempLabel = new JLabel((ImageIcon)cellObject);
/*TextBox*/
}elseif(cellObject instanceof JTextField){
tempLabel = new JTextField();
}else{
tempLabel = new JLabel();
}
if(cellObject instanceof JTextField){
}else{
/*对齐方式*/
switch(myTableModel.getCellLayout(i)){
/*左*/
case 0:
((JLabel)tempLabel).
setHorizontalAlignment(JLabel.LEFT);
break;
/*中*/
case 1:
((JLabel)tempLabel).
setHorizontalAlignment(JLabel.CENTER);
break;
/*右*/
case 2:
((JLabel)tempLabel).
setHorizontalAlignment(JLabel.RIGHT);
break;
}
}
/*宽度设定*/
int width = myTableModel.getWidth(row,i);
/*size设定*/
tempLabel.setPreferredSize
(new Dimension(width,table.getRowHeight()));
/*字体设定*/
tempLabel.setFont(table.getFont());
/*设定是否透明*/
cellPanel.add(tempLabel);
}
}
protectedvoid rePaintComponents(){
if (component != null) {
for (int i = 0; i < component.length; i++) {
if (component[i] != null) {
component[i].repaint();
}
}
}
}
public JComponent[] getComponent() {
returncomponent;
}
publicvoid setComponent(JComponent[] component) {
this.component = component;
}
}
下面看看如何使用
private JPanel makeTable(){
JPanel panel =new JPanel();
panel.setBounds(0, 100, 100, 200);
MyTableModel myTableModel = newMyTableModel();
ArrayList data = new ArrayList();
int rowNumber = 100;
ArrayList cellLayout = new ArrayList();
/*Row*/
for(int row=0;row<rowNumber;row++){
ArrayList dataRowList = new ArrayList();
if(row == 2){
TableCellModel tableCellModel = new TableCellModel();
tableCellModel.setData("bbbb");
tableCellModel.setWidth(50);
tableCellModel.setCellColor(Color.black);
dataRowList.add(0,tableCellModel);
}else{
TableCellModel tableCellModel = new TableCellModel();
tableCellModel.setData("AAA");
tableCellModel.setWidth(50);
tableCellModel.setCellColor(Color.black);
dataRowList.add(0,tableCellModel);
}
TableCellModel tableCellModel1 = new TableCellModel();
tableCellModel1.setData("adfadf"+row);
tableCellModel1.setWidth(70);
tableCellModel1.setCellColor(Color.orange);
if(row > 6 && row <9){