简单"本地图片读取应用":
源代码:


package javaswingexercise;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.net.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

public class EazyApp extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JTree tree;

	private JDesktopPane desktopPane;

	private JLabel iconLabel;

	private JButton pButton;

	private JButton nButton;

	private JScrollPane iconScrollPane;

	private JPanel iconPanel;

	int imgIndex;

	int imgCount;

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		try {
			EazyApp frame = new EazyApp();
			frame.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the frame
	 */
	public EazyApp() {
		super();
		setResizable(false);
		setBounds(0, 0, 1024, 768);
		setExtendedState(EazyApp.MAXIMIZED_BOTH);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		final JSplitPane splitPane = new JSplitPane();
		splitPane.setDividerLocation(220);
		getContentPane().add(splitPane, BorderLayout.CENTER);

		final JScrollPane treeSscrollPane = new JScrollPane();
		splitPane.setLeftComponent(treeSscrollPane);

		DefaultMutableTreeNode root = new DefaultMutableTreeNode("");

		File[] files = File.listRoots();// 遍历系统根目录
		for (int i = 0; i < files.length; i++) {
			File file = files[i];// 获得跟目录对象
			DefaultMutableTreeNode node = null;
			try {
				node = new DefaultMutableTreeNode(file.getCanonicalPath());
			} catch (IOException e) {
				e.printStackTrace();
			}
			File[] files2 = file.listFiles(fileFilter);// 遍历二级子目录
			if (files2 != null) {
				for (int j = 0; j < files2.length; j++) {
					File file2 = files2[j];// 获得二级子目录对象
					if (file2.isDirectory())
						node.add(new DefaultMutableTreeNode(file2.getName()));
					else
						node.add(new DefaultMutableTreeNode(file2.getName(),
								false));
				}
			}
			root.add(node);
		}

		tree = new JTree(root, true);
		tree.setRootVisible(false);
		tree.addTreeWillExpandListener(new TreeWillExpandListener() {
			public void treeWillExpand(TreeExpansionEvent e)
					throws ExpandVetoException {
				TreePath willExpandPath = e.getPath();
				loadChildNode(willExpandPath);// 加载子目录
			}

			public void treeWillCollapse(TreeExpansionEvent e)
					throws ExpandVetoException {
			}
		});
		tree.addTreeSelectionListener(new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				TreePath selectionPath = tree.getSelectionPath();
				loadChildNode(selectionPath);// 加载子目录
				//
				iconPanel.removeAll();
				Object[] nodePath = selectionPath.getPath();
				String selectedDir = nodePath[1].toString().replace("\\", "/");
				for (int i = 2; i < nodePath.length; i++) {
					selectedDir = selectedDir + nodePath[i] + "/";
				}
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath
						.getLastPathComponent();
				if (node.getAllowsChildren()) {
					new LoadIconInThread(selectedDir, node).start();
				} else {
					if (pButton.isEnabled())
						pButton.setEnabled(false);
					if (nButton.isEnabled())
						nButton.setEnabled(false);
					showImgInFrame(selectedDir);
				}
				SwingUtilities.updateComponentTreeUI(iconPanel);
			}
		});
		treeSscrollPane.setViewportView(tree);

		final JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		splitPane.setRightComponent(panel);

		desktopPane = new JDesktopPane();
		JLabel backLabel = new JLabel(); // 创建一个标签组件对象
		try {
			URL resource = new File("D:\\Temp\\mr\\bj.png").toURI().toURL();
			ImageIcon icon = new ImageIcon(resource); // 创建背景图片对象
			backLabel.setIcon(icon); // 令标签组件显示背景图片
			backLabel.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); // 设置组件的显示位置及大小
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} // 获得背景图片的路径
		
		desktopPane.add(backLabel, new Integer(Integer.MIN_VALUE)); // 将标签组件添加到指定索引位置
		panel.add(desktopPane, BorderLayout.CENTER);

		final JPanel operatePanel = new JPanel();
		operatePanel.setLayout(new BorderLayout());
		operatePanel.setPreferredSize(new Dimension(0, 150));
		panel.add(operatePanel, BorderLayout.SOUTH);

		pButton = new JButton();
		pButton.setText("<<");
		pButton.setEnabled(false);
		pButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				imgIndex--;
				JButton button = (JButton) iconPanel.getComponent(imgIndex);
				showImgInFrame(button.getName());
				if (imgIndex == 0)
					pButton.setEnabled(false);
				if (!nButton.isEnabled()) {
					if (imgIndex < imgCount - 1)
						nButton.setEnabled(true);
				}
				button.requestFocus();
			}
		});
		operatePanel.add(pButton, BorderLayout.WEST);

		nButton = new JButton();
		nButton.setText(">>");
		nButton.setEnabled(false);
		nButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				imgIndex++;
				JButton button = (JButton) iconPanel.getComponent(imgIndex);
				showImgInFrame(button.getName());
				if (!pButton.isEnabled()) {
					if (imgIndex > 0)
						pButton.setEnabled(true);
				}
				if (imgIndex == imgCount - 1)
					nButton.setEnabled(false);
				button.requestFocus();
			}
		});
		operatePanel.add(nButton, BorderLayout.EAST);

		iconScrollPane = new JScrollPane();
		iconScrollPane
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
		operatePanel.add(iconScrollPane, BorderLayout.CENTER);

		iconPanel = new JPanel();
		iconScrollPane.setViewportView(iconPanel);
		//
	}

	FileFilter fileFilter = new FileFilter() {
		public boolean accept(File file) {
			if (file.isDirectory())
				return true;
			else {
				String name = file.getName().toUpperCase();
				if (name.endsWith(".JPG"))
					return true;
				else if (name.endsWith(".GIF"))
					return true;
				else
					return false;
			}
		}
	};

	private class PreviewButtonAL implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			showImgInFrame(((JButton) e.getSource()).getName());
		}
	}

	public void showImgInFrame(String imgDir) {
		JInternalFrame frame = desktopPane.getSelectedFrame();
		String imgName = new File(imgDir).getName();
		JInternalFrame[] allFrames = desktopPane.getAllFrames();
		for (int i = 0; i < allFrames.length; i++) {
			JInternalFrame internalFrame = allFrames[i];
			if (internalFrame.getTitle().equals(imgName)) {
				if (internalFrame.isIcon()) {
					try {
						internalFrame.setIcon(false);
					} catch (PropertyVetoException e) {
						e.printStackTrace();
					}
				}
				if (!internalFrame.isSelected()) {
					try {
						internalFrame.setSelected(true);
					} catch (PropertyVetoException e) {
						e.printStackTrace();
					}
				}
				frame = internalFrame;
				break;
			}
		}

		if (frame == null || frame.isIcon()) {
			frame = new JInternalFrame();
			frame.setIconifiable(true);
			frame.setMaximizable(true);
			frame.setBounds(-5, -5, 800, 600);
			desktopPane.add(frame);
			frame.setVisible(true);
			iconLabel = new JLabel();
			frame.getContentPane().add(iconLabel);
		}
		if (!frame.getTitle().equals(imgName)) {
			frame.setTitle(imgName);
			iconLabel.setIcon(new ImageIcon(imgDir));
		}
	}

	public void loadChildNode(TreePath path) {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
				.getLastPathComponent();
		if (node.getAllowsChildren() && node.getChildCount() == 0) {
			StringBuffer dirBuffer = new StringBuffer();
			Object[] nodes = path.getPath();
			for (int i = 0; i < nodes.length; i++) {
				dirBuffer.append(nodes[i]);
				dirBuffer.append("\\");
			}
			File file = new File(dirBuffer.toString());
			File[] files = file.listFiles(fileFilter);
			for (int i = 0; i < files.length; i++) {
				File file2 = files[i];
				if (file2.isDirectory())
					node.add(new DefaultMutableTreeNode(file2.getName()));
				else
					node
							.add(new DefaultMutableTreeNode(file2.getName(),
									false));
			}
		}
	}

	private class LoadIconInThread extends Thread {

		private String selectedDir;

		private DefaultMutableTreeNode node;

		public LoadIconInThread(String selectedDir, DefaultMutableTreeNode node) {
			this.node = node;
			this.selectedDir = selectedDir;
		}

		@Override
		public void run() {
			imgIndex = -1;
			imgCount = 0;
			pButton.setEnabled(false);
			nButton.setEnabled(false);
			int childCount = node.getChildCount();
			for (int i = 0; i < childCount; i++) {
				DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node
						.getChildAt(i);
				if (!childNode.getAllowsChildren()) {
					imgCount++;
					String imgName = childNode.toString();
					MButton button = new MButton();
					button.setText(imgName);
					button.setName(selectedDir + imgName);
					button.setPreferredSize(new Dimension(120, 120));
					button.addActionListener(new PreviewButtonAL());
					iconPanel.add(button);
					iconScrollPane.validate();
					if (!nButton.isEnabled()) {
						if (imgCount > 0)
							nButton.setEnabled(true);
					}
					try {
						Thread.sleep(200);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			System.out.println("文件夹“" + node + "”中的图片加载完毕!");
		}
	}

	private class MButton extends JButton {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		@Override
		protected void paintComponent(Graphics g) {
			int width = getWidth();
			int height = getHeight();
			ImageIcon icon = new ImageIcon(getName());
			g.drawImage(icon.getImage(), 0, 0, width, height - 25, this);
			icon = null;
			g.drawString(getText(), 5, height - 10);
		}

	}

}

运行效果:




感想:
这周主要是学习了高级swing组件-树,然后和之前学的组件,还有IO,一起写了一个很简单的读取本地电脑的程序,在写的过程中里呢,也遇到了几个问题,在我设置背景的时候,使用URL设置绝对路径,和this.getClass().getResource("")是有区别的,一个是在本类的文件路径下,就可以用this.getClass().getResource(""),里面的内容就不能使用绝对路径,刚开始没有弄明白,在这里浪费了比较多的时间,因为前面也没有怎么使用过this.getClass().getResource(""),一般我都是直接用的绝对路径(主要this.getClass().getResource()不用处理异常,绝对路径需要。不知道是不是这样,反正我写的时候,一个要加try catch语句一个不用。),然后这一次想换一下,emmm,然后就有问题了,不过在我百度之后,就明白了这俩个的区别,现在也会用了。然后其他的就是基本操作了,做起来也比较顺利(因为太简单了吧。。。),就这样吧。

区别:

this.getClass().getResource是得到当前对象对应的类文件(.class)所在的目录下的文件。所以通过this.getClass().getResource去获得C盘中的数据是获取不到的。*
像C:\login.wav这样的绝对路劲,你可以这样来获取:

URL url = new File("C:\\login.wav").toURI().toURL();

补充:

这个要看你的Pan这个类编译成的class文件在什么地方。this.getClass().getResource()是相对于Pan.class这个类文件的文件来说的,如果login.wav和Pan.class同一目录下,那么this.getClass().getResource("login.wav")就能获取到,如果login.wav是在Pan.class的下一级目录music下,那么就是

this.getClass().getResource("music/login.wav")

像这样的根据ClassLoader来获取资源的方式,应该不能查找上一级目录。如:
this.getClass().getResource("../aa");这样好像是不行的。所以如果要取相对路径,那么要么就把login.wav和Pan.class文件放在同一目录,要么就把login.wav放在Pan.class的下一级目录。
来源百度

学习总结:

一、简单的树

树状结构是一种常用的信息表现形式,它可以直观的显示出一组信息的层次结构。Swing中的JTree类是用来创建树的,该类的常用构造方法如下:

构造方法 内容
JTree() 创建一个默认的树
JTree(TreeNode node) 根据指定根节点创建树。
JTree(TreeModel newModel) 根据指定树模型创建树.

DefaultMutableTreeNode类 实现了TreeNode接口,用来创建树的节点,DefaultMutableTreeNode类的add()方法为节点添加子节点。
DefaultTreeModel类 实现了TreeModel接口,该类提供了两个构造方法,所以在利用该类创建树模型时,必须指定树的根节点。
构造方法如下:

方法 区别
DefaultTreeModel (TreeNode root)创建一个采用默认方式来判断节点是否为叶子节点的树模型。
DefaultTreeModel (TreeNode root,boolean askAllowsChildren)创建一个采用指定方式来判断节点是否为叶子节点的树模型。

二、处理选中节点事件

树的节点允许被选中和选中状态,通过捕获树节点的选择事件,可以处理相应的操作树的选择模式有三种,通过TreeSelectionModel类的对象可以设置树的选择模式。可以通过JTree类
的getSelctionModel()方法获得TreeSelectionModel类的对象,然后通过TreeSelctionModel类的setSelectionModel(int mode)方法设置选择模式,该方法的入口参数为:

参数|用处
---|:---😐---:
SINGLE_TREE_SELECTION| 只允许选中一个
CONTIGUOUS_TREE_SELECTION | 允许连续选择多个
DISCONTIGUOUS_TREE_SELECTION | 允许随意选中多个

当选中树节点和取消树节点的选中状态时,将发出TreeSelectionEvent事件,通过实现TreeSelectionListener接口可以捕获该事件。TreeSelectionListener接口的具体定义:


Public interface TreeSelectionListener extends EventListener{

     Void valueChanged(TreeSelectionEvent e);

}

当捕获发出的TreeSelectionEvent事件时,Void valueChanged(TreeSelectionEvent e)方法将被触发执行,此时可通过JTree类的getSelectionPaths()方法获得所有 被选中节点的路径,该方法将返回一个TreePath类型的数组;通过getSelectionPath()方法可以获取选中节点中的索引的最小的节点的路径,即TreePath对象,在此之前,可以通过JTree类的isSelectionEmpty()方法查看是否存在被选中的节点,可以通过getSelectionCount()方法可以获取被选中节点的数量。

TreePath类的常用方法:

方法 内容
getPath() 以Object数组的形式返回该路径中所有节点的对象,在数组中的顺序按照从根节点到子节点的顺序。
getLastPathComponent() 获得该路径中最后一个节点的对象。
getParentPath() 获得路径中除了最后一个节点的路径
pathByAddingChild() 获得向路径中添加指定节点后的路径
getPathCount() 获得向路径中包含节点的数量
getPathComponent(int element) 获得路径中指定索引位置的节点对象

三、遍历树节点

DefaultMutableTreeNode类提供了两组相对的遍历方式,如下:

前序遍历和后序遍历是一组相对的遍历方式,方法分别为:preorderEnumeration()和postorderEnumeration()方法,返回的是枚举类型对象。

广度优先遍历和深度优先遍历是一组相对的遍历方式,方法分别为:breadFirstEnumeration()和deptFirstEnumeration()方法,返回的是枚举类型对象。