基本思路,左侧一个JTree,右侧一个JTable,JTable的第一列为Filename。使用TableCellRenderer重绘Filename列,使得此列由一个JLable与一个JTextFiled组成。
代码运行的第一个界面,显示正常,达到预期效果,如图:
可当点击左侧树节点,进入其它文件夹(其实就是改变了JTable的数据)后,Filename就显示不出来了,如图:
有没有好心人帮忙分析下怎么回事啊?代码随后附上ps:如果不加TableCellRenderer的话,展开/收缩左侧树是没问题的。
ps2:我就20分了,千万别嫌少,不够的话您说,俺去打工挣……
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;public class MainFrame extends JFrame { DefaultTableModel ttm=null;
JTable tt=new JTable(ttm);
public static void main(String[] args) {
MainFrame mf = new MainFrame();
} public MainFrame() {
GUIInit();
} private void GUIInit() {
this.setVisible(true);
this.setTitle("explorer");
this.setSize(new Dimension(Toolkit.getDefaultToolkit()
.getScreenSize()));
this.getContentPane().setLayout(new BorderLayout());
this.setBackground(Color.lightGray); //初始化左侧目录导航树
initLeftTree();
jScrollPaneLeft.setPreferredSize(new Dimension(400, 400));
jScrollPaneLeft.getViewport().add(jTree, null); //初始化右侧显示table
ttm=new FileDeafaultTableModel("");
jScrollPaneRight.getViewport().add(tt,null);
tt.setModel(ttm);
tt.setShowGrid(false);
tt.setBackground(Color.lightGray); tt.getModel().addTableModelListener(new TableModelListener(){
public void tableChanged(TableModelEvent e) {
System.out.println("tableChanged");
}
}); //给右侧table的第一列添加TableCellRenderer。如果将此行注释,JTable显示无异常。
initializeFilenameColumn(); jSplitPane.add(jScrollPaneLeft, JSplitPane.TOP);
jSplitPane.add(jScrollPaneRight, JSplitPane.BOTTOM);
jSplitPane.setDividerLocation(200);
jSplitPane.setDividerSize(3);
jSplitPane.setOneTouchExpandable(true);
this.getContentPane().add(jSplitPane, BorderLayout.NORTH);
jl=new JLabel("NOTE:");
this.getContentPane().add(jl, BorderLayout.SOUTH);
addMenuBar();
this.pack();
this.show();
} private TableCellRenderer render = new FilenameRenderer();
private void initializeFilenameColumn(){
TableColumn filenameColumn=tt.getColumn("FILENAME");
filenameColumn.setCellRenderer(render);
Dimension ps=((JPanel)render).getPreferredSize();
tt.setRowHeight(ps.height);
} private void initLeftTree() {
root = new FileMutableTreeNode("");
root.expands(root);
treeModel = new DefaultTreeModel(root);
jTree = new JTree(treeModel);
registerTreeListener();
} /**
* 左侧导航树的鼠标事件
* 当双击树上某节点(其实就是某个目录)时,右侧的表格会显示此目录下的文件
*/
private void registerTreeListener() {
jTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeCollapsed(TreeExpansionEvent tee) {
TreePath treePath = tee.getPath();
FileMutableTreeNode fileNode = (FileMutableTreeNode) treePath.getLastPathComponent();
tt.removeAll();
((FileDeafaultTableModel)tt.getModel()).changeData(fileNode.filepath);
} public void treeExpanded(TreeExpansionEvent tee) {
TreePath treePath = tee.getPath();
FileMutableTreeNode fileNode = (FileMutableTreeNode) treePath
.getLastPathComponent();
DefaultTreeModel model = (DefaultTreeModel) jTree.getModel(); jl.setText("explore...");
if (!fileNode.isExplore()) {
fileNode.expands(fileNode);
model.nodeStructureChanged(fileNode);
new UpdateStatus(fileNode.filepath).start();
} tt.removeAll();
((FileDeafaultTableModel)tt.getModel()).changeData(fileNode.filepath);
//下面这几句加不加效果都一样
// initializeFilenameColumn();
// tt.getColumn("FILENAME").setCellRenderer(new FilenameRenderer());
// tt.repaint();
} class UpdateStatus extends Thread{
private String text;
public UpdateStatus(String text){
this.text=text;
}
public void run(){
try{
Thread.sleep(300);
}catch(Exception e){
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
jl.setText(text);
}
});
}
} });
} /**
* 获取某目录下的子目录和文件
* @param filePath
* @return
*/
private ArrayList getSystemDriverList(String filePath) {
File[] drivers = new File[] {};
int driversNum = 0;
if (filePath == "") {
drivers = File.listRoots();
} else {
drivers = (new File(filePath)).listFiles();
} try{
driversNum = drivers.length;
}catch (Exception e){
System.out.println("Can't access");
}
ArrayList al = new ArrayList(driversNum);
for (int i = 0; i < driversNum; i++) {
if(!drivers[i].isDirectory()) continue;
FileMutableTreeNode tempNode=new FileMutableTreeNode(drivers[i]);
al.add(tempNode );
}
return al;
} /**
* 菜单栏,基本未实现
*/
private void addMenuBar() {
exitItem.setEnabled(true);
fileMenu.add(exitItem);
fileMenu.setEnabled(true);
menuBar.add(fileMenu);
this.setJMenuBar(menuBar);
}
/**
*自己的 TableCellRenderer,基本思路是重绘右侧table的第一列(即FILENAME列)
*由一个JLabel和一个JTextField组成
*/
class FilenameRenderer extends JPanel implements TableCellRenderer{
private JTextField jtf=new JTextField();
private JLabel jl =new JLabel("ICON");
private Component glue = Box.createHorizontalGlue();
int i=0;
private Color unselectedForeground;
private Color unselectedBackground; String temp;
public FilenameRenderer(){
// super(); jtf.setBorder(BorderFactory.createEtchedBorder());
jl.setBorder(BorderFactory.createEtchedBorder());
jtf.setOpaque(true);
jl.setOpaque(true);
jl.setHorizontalAlignment(JLabel.LEFT);
jtf.setHorizontalAlignment(JLabel.CENTER);
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
this.add(jl,BorderLayout.WEST);
this.add(jtf,BorderLayout.CENTER);
// jl.setIcon(new Icon();
} public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelect,
boolean hasFocus,int row,int col){
setOpaque(false);
jtf.setVisible(true);
jl.setVisible(true);
jtf.setOpaque(true);
jl.setOpaque(true); temp=(String)table.getValueAt(row,col);
setFont(table.getFont()); jtf.setText((String)table.getValueAt(row,col)); Component c[]=this.getComponents();
setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, table.getBackground()));
for (int k=0;k<c.length;k++){
if (c[k] instanceof JLabel){
((JLabel)c[k]).setHorizontalAlignment(SwingConstants.LEFT);
((JLabel)c[k]).setAlignmentX((float)0.0);
((JLabel)c[k]).setOpaque(true);
((JLabel)c[k]).setForeground(Color.DARK_GRAY);
System.out.println("isLabel == "+((JLabel)c[k]).getText());
}
if (c[k] instanceof JTextField){
((JTextField)c[k]).setHorizontalAlignment(SwingConstants.LEFT);
((JTextField)c[k]).setAlignmentX((float)0.0);
((JTextField)c[k]).setOpaque(false);
((JTextField)c[k]).setForeground(Color.DARK_GRAY);
System.out.println("isTextField == "+((JTextField)c[k]).getText());
table.setValueAt(((JTextField)c[k]).getText(),row,col);
}
}
add(glue);
add(jl);
add(jtf);
// SwingUtilities.updateComponentTreeUI(this);
// super.updateUI();
// this.updateUI();
// super.show();
// this.show();
return this;
}
protected void setValue(Object value){
jtf.setText(value.toString());
}
} /**
* 左侧导航树树节点
*/
class FileMutableTreeNode extends DefaultMutableTreeNode {
private String filepath; private String filename; private File currentFile; private FileMutableTreeNode currentNode; boolean isExplore = false; public FileMutableTreeNode(String filepath) {
this.filepath = filepath;
}
public boolean isLeaf() {
if (filepath == "") {
return false;
} else {
return (!(new File(filepath)).isDirectory());
}
}
/**
*
*/
public void expands(FileMutableTreeNode currentNode) {
if (currentNode == null) {
System.out.println("currentFile==null return");
return;
} else {
this.currentNode = currentNode;
} if (!isExplore) {
ArrayList al = getSystemDriverList(currentNode.filepath);
for (int i = 0; i < al.size(); i++) {
currentNode.add((FileMutableTreeNode) al.get(i));
}
isExplore = true;
}
} public FileMutableTreeNode(File file) {
this.filename = file.toString();
this.filepath = file.getPath();
this.currentFile = file;
} /**
* @return
*/
public boolean isExplore() {
return isExplore;
} public String toString() {
if (filename == null) {
return "comp";
} else {
int index=filename.lastIndexOf("\\");
return (index!=-1&&index !=filename.length()-1)?filename.substring(index+1):filename;
}
}
} /**
* 右侧table模型
*/
class FileDeafaultTableModel extends DefaultTableModel implements TableModelListener{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 3258415023478355249L;
String filePath;
File[] files;
Object[][] data;
String[] columnName;
public FileDeafaultTableModel(String filePath){
this.filePath=filePath;
initT();
} private void initT(){
if(filePath==""||filePath==null){
files=File.listRoots();
}else {
files=new File(filePath).listFiles();
}
columnName= new String[]{"FILENAME", "ISDIRECTORY", "LAST MODIFY DATE",};
data=new Object[files.length][columnName.length];
for (int i=0;i<files.length;i++){
if(files[i].getName().equalsIgnoreCase("")){
data[i][0]=files[i].toString();
}else{
data[i][0]=files[i].getName();
}
data[i][1]=String.valueOf(files[i].isDirectory());
data[i][2]=new Date(files[i].lastModified());
}
} public Object getValueAt(int row,int col){
return data[row][col];
}
public int getRowCount(){
if(data==null){
return 0;
}else{
return data.length;
}
}
public int getColumnCount(){
if(data==null){
return 0;
}else{
return columnName.length;
}
}
public String getColumnName(int col){
return columnName[col];
}
public Class getColumnClass(int col){
return data[0][col].getClass();
}
public void setValueAt(Object value,int row,int col){
data[row][col]=value;
}
public boolean isCellEditable(int row,int col){
Class cls=getColumnClass(col);
String name=getColumnName(col);
return name=="FILENAME";
}
public void changeData(String filePath){
this.filePath=filePath;
initT();
} public void tableChanged(TableModelEvent e) {
System.out.println("tableChanged2");
}
}
/**
* 抽象状态树根结点
*/
protected FileMutableTreeNode root;// = new DefaultMutableTreeNode("root"); /**
* 抽象状态树模型
*/
protected DefaultTreeModel treeModel;// = new DefaultTreeModel(root); /**
* 抽象状态树
*/
protected JTree jTree;// = new JTree(treeModel); private JMenuBar menuBar = new JMenuBar(); private JMenu fileMenu = new JMenu("File"); private JMenuItem exitItem = new JMenuItem("Exit"); private JSplitPane jSplitPane = new JSplitPane(); private JScrollPane jScrollPaneLeft = new JScrollPane(); private JScrollPane jScrollPaneRight = new JScrollPane(); private JLabel jl=new JLabel(); private JPanel jp=new JPanel(); private DefaultTableModel fileTableModel;//=new DefaultTableModel();
private JTable fileTable=new JTable();
private ArrayList tableFileList=new ArrayList();
}
我怀疑是图像绘制的问题
Java(TM) SE Runtime Environment (build 1.7.0-ea-b17)
Java HotSpot(TM) Client VM (build 1.7.0-ea-b17, mixed mode, sharing)