⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draw.java

📁 一个简易的java画图软件
💻 JAVA
字号:
package draw;

import java.awt.Color;
import java.awt.Container;
import java.beans.PropertyVetoException;
import java.io.File;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.filechooser.FileFilter;

import draw.figuare.AbstractFiguare;

import app.Application;
import app.action.Actions;

/**
 * 画板,在程序中充当画布View的管理者。<br/> 它从画笔工具PaintPane获得当前用户选中的画笔工具shape,
 * 并更新当前所有画布View的画笔工具。<br/> Draw负责新建、删除、保存画布。<br/> 注:网络的同步是针对一个画布View的,而不是Draw。
 * 
 * @author Thihy
 * 
 */
public class Draw implements InternalFrameListener {
	protected Vector<View> views;// 存储当前所有画布
	protected View currentView;// 必须是VIEWS的一员
	protected JDesktopPane contentPane;// 画板的主容器
	protected JPanel littleMenuPane;// 小型菜单,在菜单栏的右侧显示,当最大化之后会显示出来

	protected Application app; // 所在的主窗口

	protected static int viewNum=0;
	// 一些颜色
	protected Color strokeColor = Color.black;
	protected Color fillColor = Color.white;
	protected int paintTool = AbstractFiguare.ARROW;
	protected JFileChooser fileChooser;
	
	protected AbstractFiguare clip=null;//剪切复制用

	/**
	 * 初始化
	 * 
	 * @param parent
	 *            所在的主窗口
	 */
	public Draw(Application parent) {
		views = new Vector<View>();
		contentPane = new JDesktopPane();
		contentPane.setBackground(Color.lightGray);
		this.app = parent;
		currentView = null;
		littleMenuPane = app.getMenuPane().creatPanel(this);
		fileChooser = creatFileChooser();
		updateActionEnable();
	}

	/**
	 * 获取当前窗口的内容面板。<br/> 不应该向里面添加任何组件,因为它 是有程序Draw来布置View画布的一个 容器。
	 * 
	 * @return 内容面板
	 */
	public Container getContentPane() {
		return contentPane;
	}

	/**
	 * 打开一个文件
	 */
	public void OpenView() {
		int ans = fileChooser.showOpenDialog(app);
		if (ans == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if (file.isFile() && file.canRead()) {
				View view = creatView(file.getName());
				if (view != null) {
					view.load(file);
				} else {
					// do nothing
				}
			}
		}
	}

	/**
	 * 创建并返回一个文件选择器 会建立一个文件过滤器
	 * 
	 * @return 文件选择器
	 */
	private JFileChooser creatFileChooser() {
		JFileChooser filechooser = new JFileChooser();
		filechooser.setAcceptAllFileFilterUsed(true);

		// 文件过滤器
		FileFilter filter = new FileFilter() {

			@Override
			public String getDescription() {
				return "Paint 文件 (*." + Application.viewfileSuffix + ")";
			}

			@Override
			public boolean accept(File f) {
				String fileName = f.getName();
				if (f.isDirectory())
					return true;
				if (fileName.matches(".*\\." + Application.viewfileSuffix)) { // 文件以pnt后缀结束
					return true;
				}
				return false;
			}
		};

		filechooser.setFileFilter(filter);
		filechooser.setFileHidingEnabled(true);
		filechooser.setMultiSelectionEnabled(false);

		return filechooser;
	}

	/**
	 * 返回一个文件选择器
	 * 
	 * @return 文件选择器
	 */
	public JFileChooser getFileChooser() {
		return fileChooser;
	}

	/**
	 * 还原画布
	 */
	public void restoreAllViews() {
		Iterator<View> iter = views.iterator();
		while (iter.hasNext()) {
			View view = iter.next();
			InnerFrame i = (InnerFrame) view.getViewPort();
			try {
				i.setMaximum(false);
			} catch (PropertyVetoException ex) {
				ex.printStackTrace();
			}
			i.showNorthPanel();
		}
		updateActionEnable();
	}

	/**
	 * 新建一个画布,采用默认名称:未标题 - 标号
	 * 
	 * @return 新建的画布
	 */
	public View creatView() {
		return creatView(null);
	}

	/**
	 * 创建一个新的画布, 并将此画布设置为正在使用的画布
	 */
	public View creatView(String name) {
		++viewNum;
		if(name==null)
			name="未标题 - " + (viewNum);
		View newView = new View(name, this, viewNum);

		JInternalFrame viewPort = newView.getViewPort();
		if (viewPort == null) {
			if (Application.DEBUG > 0) {
				System.out.println("在Draw调用View:名称(" + newView.getName() + "),"
						+ "ID(" + viewNum + ")的getViewPort时发生了意外:返回了一个NULL指针");
			}
			return null;
		}
		contentPane.add(viewPort, 0);// 在内容面板中显示。
		/*
		 * 每次向下向右移动20px 如果到达边界,则停止移动 注意:缩小主窗口后再放大,可能位置不连贯。
		 */
		int px = Math.min(20 * viewNum, contentPane.getWidth() - viewPort.getWidth()
				- 1);
		int py = Math.min(20 * viewNum, contentPane.getHeight()
				- viewPort.getHeight() - 1);
		px = Math.max(px, 0);
		py = Math.max(py, 0);
		viewPort.setLocation(px, py);

		try {
			if (currentView != null) {
				JInternalFrame currentViewPort = currentView.getViewPort();
				if (currentViewPort.isMaximum() && !currentViewPort.isIcon()) {
					viewPort.setMaximum(true);
				}
			} else {
				viewPort.setMaximum(true);
			}
		} catch (PropertyVetoException e) {
			if (Application.DEBUG > 7)
				e.printStackTrace();
		}

		views.add(newView);
		setCurrentView(viewNum);

		newView.setStrokeColor(strokeColor);
		newView.setFillColor(fillColor);
		newView.setPaintTool(paintTool);

		updateActionEnable();
		return newView;
	}

	// 获取小型菜单栏,由InnerFrame调用
	public JPanel getLittleMenuPane() {
		return littleMenuPane;
	}

	/**
	 * 设置当前用户选择的图形。 通过其ID指定,这些ID在AbstractFiguare类中定义
	 * 
	 * @param figuareID
	 *            图形的ID。
	 */
	public void setPaintTool(int figuareID) {
		paintTool = figuareID;
		int size = views.size();
		for (int i = 0; i < size; ++i) {
			views.elementAt(i).setPaintTool(figuareID);
		}
	}

	/**
	 * 设置当前选中图形的线形颜色
	 * 
	 * @param color
	 *            线形颜色
	 */
	public void setStrokeColor(Color color) {
		strokeColor = color;
		int size = views.size();
		for (int i = 0; i < size; ++i) {
			views.elementAt(i).setStrokeColor(color);
		}
	}

	/**
	 * 设置当前选中图形的填充颜色
	 * 
	 * @param color
	 *            线形颜色
	 */
	public void setFillColor(Color color) {
		fillColor = color;
		int size = views.size();
		for (int i = 0; i < size; ++i) {
			views.elementAt(i).setFillColor(color);
		}
	}

	/**
	 * 剪切当前窗口中的当前图形
	 */
	public void cutCurrentFiguare() {
		if(currentView==null)return;
		AbstractFiguare tClip;
		if((tClip=currentView.getCanvas().cutFiguare())!=null){
			clip=tClip;
		}
	}
	/**
	 * 复制当前窗口中的当前图形
	 */
	public void copyCurrentFiguare() {
		if(currentView==null)return;
		AbstractFiguare tClip;
		if((tClip=currentView.getCanvas().copyFiguare())!=null){
			clip=tClip;
		}
	}
	/**
	 * 剪切当前窗口中的当前图形
	 */
	public void pasteCurrentFiguare() {
		if(currentView==null||clip==null)return;
		AbstractFiguare tClip;
		currentView.getCanvas().pasteFiguare((AbstractFiguare)clip.clone());
	}
	/**
	 * 获取指定ID的画布
	 * 
	 * @param id
	 *            指定的ID
	 * @return 指定ID的画布
	 */
	private View getViewWithId(int id) {
		int size = views.size();
		View newCurrentView = null;
		for (int i = 0; i < size; ++i) {
			if (views.elementAt(i).viewId == id) {
				newCurrentView = views.elementAt(i);
				break;
			}
		}
		return newCurrentView;
	}

	/**
	 * 设置当前画布为指定Id的画布
	 */
	public void setCurrentView(int id) {
		View newCurrentView = getViewWithId(id);
		int size = views.size();
		if (newCurrentView == null)
			return;
		for (int i = 0; i < size; ++i) {
			if (views.elementAt(i).viewId == id) {
				newCurrentView = views.elementAt(i);
				break;
			}
		}

		if (newCurrentView == null)
			return;

		if (currentView == newCurrentView)
			return;
		if (currentView != null) {
			// 将旧的使用画布置于后面
			currentView.getViewPort().moveToBack();
		}
		currentView = newCurrentView;
		// 将当前画布提前
		currentView.getViewPort().moveToFront();
		updateActionEnable();
	}

	/**
	 * 获取当前画布
	 */
	public View getCurrentView() {
		return currentView;
	}

	/**
	 * 关闭当前正在使用的画布
	 */
	public boolean closeCurrentView() {
		if (currentView == null)
			return false;
		if (currentView.close()) {// 如果当前画布成功关闭
			views.remove(currentView);
			// 设置当前使用画布
			if (views.size() > 0) {
				currentView = views.lastElement();
				currentView.getViewPort().moveToFront();
			} else {
				currentView = null;
			}
			updateActionEnable();// 更新所有的Action
			return true;
		}
		updateActionEnable();// 更新所有的Action
		return false;
	}

	/**
	 * 更新所有的Action 主要是激活或禁用一些菜单项等
	 */
	public void updateActionEnable() {
		boolean existView = (views.size() > 0), hasCurrentView = (currentView != null);
		Actions.saveAction.setEnabled(existView && hasCurrentView);
		Actions.saveAsAction.setEnabled(existView && hasCurrentView);
		Actions.geneteImageAction.setEnabled(existView && hasCurrentView);
		Actions.closeAction.setEnabled(existView && hasCurrentView);
		Actions.closeAllAction.setEnabled(existView);
		if (currentView != null) {
			Actions.becomeServerAction.setEnabled(!currentView.IsConnected());
			Actions.unConnectServerAction.setEnabled(currentView.IsConnected());
		}
		// 最大化画布之后显示小型菜单栏,且主窗口的标题设置为当前画布的标题
		if (currentView != null && currentView.getViewPort().isMaximum()) {
			littleMenuPane.setVisible(true);
			app.setTitle(currentView.getViewPort().getTitle() + " - "
					+ Application.APPNAME);
		} else {
			littleMenuPane.setVisible(false);
			app.setTitle(Application.APPNAME);
		}
	}

	/**
	 * 关闭所有的画布
	 */
	public boolean closeAllViews() {
		while (views.size() > 0) {
			View view = views.lastElement();
			if (view.close()) {
				views.remove(view);
			} else {
				return false;
			}
		}
		return true;
	}

	/**
	 * 保存当前正在使用的画布
	 */
	public void saveCurrentView() {
		if (currentView != null)
			currentView.save();
	}

	public void saveCurrentViewAs() {

		if (currentView != null)
			currentView.saveAs();
	}

	/**
	 * 保存所有的画布
	 */
	public void saveAllView() {
		for (View view : views) {
			view.save();
		}
	}

	/**
	 * 获取当前窗口中的所有画布
	 * 
	 * @return 所有画布的向量表
	 */
	public Vector<View> getViews() {
		return views;
	}

	/**
	 * 新建一个服务器
	 */
	public void newServer() {
		currentView=creatView();
		if (currentView==null ||  !becomeServer()) {// 成为服务器失败
			// 删除这个画布
			closeCurrentView();
		}
	}

	/**
	 * 将当前画布设置为服务器
	 * 
	 * @return 成功成为服务器则返回真
	 */
	public boolean becomeServer() {
		if (currentView == null)
			return false;
		if (currentView.creatServer()) {
			updateActionEnable();
			return true;
		}
		return false;
	}

	/**
	 * 新建一个客户端
	 */
	public void newClient() {
		currentView=creatView(); 
		if (currentView==null || !currentView.creatClient()) {// 成为客户端失败
			// 删除这个画布
			updateActionEnable();
			closeCurrentView();
		}
	}

	/**
	 * 断开连接
	 */
	public void unConnectServer() {
		if (currentView == null)
			return;
		currentView.unConnectServer();
	}

	// --------------------------------------------------------
	// 以下是内部框架的监听器,主要用于关闭
	@Override
	public void internalFrameActivated(InternalFrameEvent e) {
		int id = (Integer) e.getInternalFrame().getClientProperty("ID");
		setCurrentView(id);
	}

	@Override
	public void internalFrameClosed(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameClosing(InternalFrameEvent e) {
		int id = (Integer) e.getInternalFrame().getClientProperty("ID");
		if (getViewWithId(id) != null) {
			View view = getViewWithId(id) ;
			if (view.close()) {
				views.remove(view);
			} 
			updateActionEnable();
		}
	}

	@Override
	public void internalFrameDeactivated(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameDeiconified(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameIconified(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameOpened(InternalFrameEvent e) {
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -