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

📄 view.java

📁 一个简易的java画图软件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package draw;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.Border;
import javax.swing.filechooser.FileFilter;

import svg.SVGGen;

import app.Application;
import app.action.DelAction;
import app.action.MoveAction;
import app.action.RotateAction;
import app.pane.ChatFrame;
import app.pane.EdgedBorder;

import net.NetMessage;
import net.PaintClient;
import net.PaintServer;

import draw.figuare.AbstractFiguare;

/**
 * 画布 <br/> 为绘图的主体
 * 
 * @author Thihy
 * 
 */
public class View {
	protected Draw draw;// 所在的主框架
	protected JInternalFrame viewPort; // 附着体
	private PaintCanvas canvas;// 画布实体
	protected JPanel chatPane;// 聊天面板
	protected ChatFrame chatFrame;// 聊天框架

	// 一些常量,用于属性更改监听器
	public static final String VIEW_KIND_PROPERTY = "view.kind";
	public static final String CANVAS_CHANGED_PROPERTY = "view.canvas.changed";
	public static final String HAS_SAVED = "view.saved";

	// 唯一指定的ID
	public int viewId;

	// 用于聊天的服务端和客户端,一次只能使用一个
	protected PaintServer server;
	protected PaintClient client;

	// 记录是否需要保存文档
	private boolean needSave;

	// 属性更改监听器
	protected ViewPropertyListener propertyListener = new ViewPropertyListener();

	// 当前文件保存的位置。
	protected File viewFile;

	/**
	 * 画布的名称。<br/> 显示在内部窗口JInternalFrame的标题栏上。 初始时如果未指定显示“untitled - ”+标号(从1开始)。
	 * 这是由此类自身维护的,不提供setName接口。 修改只能通过保存操作或者初始时设定(如打开文档,新建文档时)。
	 * 为了方便,初始时可能会要求获得文件的存储地址。 目前可能提供的文件存储格式为:svg。
	 */
	private String name;
	/**
	 * 样式,分为服务器和客户端两种
	 */
	private String viewKind;

	public View(String name, Draw controlDraw, int id) {
		this.name = name;
		this.viewId = id;
		this.draw = controlDraw;
		this.viewPort = createViewPort();
		this.server = null;
		this.client = null;
		this.needSave = false;
		this.viewFile = null;
		viewKind = "";
	}

	/**
	 * 创建内部框架
	 * 
	 * @return 内部框架
	 */
	protected JInternalFrame createViewPort() {
		viewPort = new InnerFrame(draw);

		regKeyAction(viewPort);

		// 获取标题文本,也即View的名称
		String title = this.name;
		if (title == null) {
			title = ""; // 如果为null时,什么也不显示。
		}
		viewPort.setTitle(title);

		viewPort.addInternalFrameListener(this.draw);
		viewPort.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		viewPort.putClientProperty("ID", viewId);// 用来唯一表示这个IFRAME
		viewPort.putClientProperty(VIEW_KIND_PROPERTY, "");
		viewPort.addPropertyChangeListener(propertyListener);

		// 出示时不指定显示位置,而是由控制器Draw来控制显示位置。

		/*
		 * 用户可以直接关闭这个面板。 但是会调用一些处理程序, 如判断当前文档是否已经经过更改, 若如此,会询问是否保存文档。
		 */
		viewPort.setClosable(true);
		viewPort.setResizable(true); // 可以调整大小
		viewPort.setMaximizable(true); // 可以最大化
		viewPort.setIconifiable(true); // 可以最小化
		viewPort.setVisible(true);

		// 绘出画板
		drawPaintPad(viewPort);
		viewPort.setSize(400, 400);
		return viewPort;
	}

	/**
	 * 绘制内部框架
	 * 
	 * @param iframe
	 *            内部框架
	 */
	private void drawPaintPad(JInternalFrame iframe) {
		iframe.setBackground(Color.lightGray);// TEMP View内部面板采用BorderLayout
		JPanel p = (JPanel) iframe.getContentPane();
		p.setLayout(new BorderLayout());

		canvas = new PaintCanvas(this);
		p.add(canvas);

		canvas.setPreferredSize(new Dimension(450, 500));
		canvas.addPropertyChangeListener(propertyListener);

		Border bd = new EdgedBorder(UIManager.getColor("control"));
		canvas.setBackground(Color.white);
		canvas.setBorder(bd);
		canvas.setVisible(true);

		chatFrame = new ChatFrame(this, true);
		chatPane = chatFrame.getChatPane();
		chatPane.setVisible(false);
		p.add(chatPane, BorderLayout.EAST);
	}

	/**
	 * 注册键盘
	 * 
	 * @param comp
	 *            待注册组件
	 */
	private void regKeyAction(JComponent comp) {
		comp.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
				MoveAction.East.ID);
		comp.getActionMap().put(MoveAction.East.ID, new MoveAction.East(this));

		comp.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
				MoveAction.North.ID);
		comp.getActionMap()
				.put(MoveAction.North.ID, new MoveAction.North(this));

		comp.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
				MoveAction.South.ID);
		comp.getActionMap()
				.put(MoveAction.South.ID, new MoveAction.South(this));

		comp.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
				MoveAction.West.ID);
		comp.getActionMap().put(MoveAction.West.ID, new MoveAction.West(this));

		comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), DelAction.ID);
		comp.getActionMap().put(DelAction.ID, new DelAction(this));

		comp.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0),
				RotateAction.Right.ID);
		comp.getActionMap().put(RotateAction.Right.ID,
				new RotateAction.Right(this));

		comp
				.getInputMap()
				.put(
						KeyStroke.getKeyStroke(KeyEvent.VK_R,
								InputEvent.SHIFT_DOWN_MASK), RotateAction.Left.ID);
		comp.getActionMap().put(RotateAction.Left.ID,
				new RotateAction.Left(this));

	}

	/**
	 * 获取聊天面板
	 */
	public JPanel getChatPane() {
		return chatPane;
	}

	/**
	 * 获取聊天框架
	 */
	public ChatFrame getChatFrame() {
		return chatFrame;
	}

	/**
	 * 获取当前窗口的视窗。<br/> 不应该向里面添加任何组件,因为它 是有程序Draw来布置View画布的一个 容器。 <br/>
	 * 只运行同一个包或其子类访问。
	 * 
	 * @return 当前窗口的视窗
	 */
	public JInternalFrame getViewPort() {
		return viewPort;
	}

	/**
	 * 设置当前画布所在的画板
	 * 
	 * @param newDraw
	 *            画板
	 */
	public void setDraw(Draw newDraw) {
		this.draw = newDraw;
	}

	/**
	 * 获取当前画布的名称
	 * 
	 * @return 画布的名称
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * 获取网络名称,如果是客户端,由服务器指定
	 * 
	 * @return 网络名称
	 */
	public String getNetName() {
		if (client != null) {
			return client.getNetName() + "-";
		}
		return "Server-";
	}

	/**
	 * 设置工具,由工具的唯一ID来指定
	 * 
	 * @param figuareID
	 *            工具的唯一ID
	 */
	protected void setPaintTool(int figuareID) {
		getCanvas().setShape(figuareID);
	}

	/**
	 * 设置线形颜色
	 * 
	 * @param color
	 *            线形颜色
	 */
	public void setStrokeColor(Color color) {
		getCanvas().setStrokeColor(color);
	}

	/**
	 * 设置填充颜色
	 * 
	 * @param color
	 *            填充颜色
	 */
	public void setFillColor(Color color) {
		getCanvas().setFillColor(color);
	}

	/**
	 * 获取所有的图形
	 * 
	 * @return 所有的图形
	 */
	public Vector<AbstractFiguare> getFiguares() {
		return getCanvas().getFiguares();
	}

	/**
	 * 获取Canvas
	 * 
	 * @return Canvas
	 */
	public PaintCanvas getCanvas() {
		return canvas;
	}

	/**
	 * 关闭窗口
	 * 
	 * @return 成功关闭返回真
	 */
	public boolean close() {
		if (IsConnected()) {
			int ans = JOptionPane.showOptionDialog(null,
					name + "文件连接到网络,确定关闭?", "警告", JOptionPane.YES_NO_OPTION,
					JOptionPane.WARNING_MESSAGE, null, new String[] { "关闭",
							"不关闭" }, "关闭");

			switch (ans) {
			case JOptionPane.YES_OPTION:// 关闭
				unConnectServer();
				break;
			case JOptionPane.NO_OPTION:// 不关闭
				return false;
			default:
				return false;
			}
		}

		if (needSave) {
			int ans = JOptionPane.showOptionDialog(null, name + "文件已经更改,是否保存?",
					"警告", JOptionPane.YES_NO_CANCEL_OPTION,
					JOptionPane.WARNING_MESSAGE, null, new String[] { "保存",
							"不保存", "取消关闭" }, "保存");

			switch (ans) {
			case JOptionPane.YES_OPTION:// 保存
				save();
				break;
			case JOptionPane.NO_OPTION:// 不保存
				break;
			case JOptionPane.CANCEL_OPTION:// 取消关闭
				return false;
			default:
				return false;
			}
		}
		viewPort.dispose();
		canvas.setVisible(false);
		canvas = null;
		return true;
	}

	protected void save() {
		if (viewFile == null || !(viewFile.isFile() && viewFile.canWrite())) {
			saveAs();
			return;
		}
		savingView();
	}

	protected void saveAs() {
		JFileChooser filechooser = draw.getFileChooser();
		int ans = filechooser.showSaveDialog(draw.app);
		if (ans == JFileChooser.APPROVE_OPTION) {
			viewFile = filechooser.getSelectedFile();
			String name = viewFile.getName();
			String path = viewFile.getAbsolutePath();
			path = path.substring(0, path.lastIndexOf(File.separatorChar));
			name = name.trim();
			if (name.matches("\".+\"")) { // 文件名两边有“”, 则不指定后缀
				name = name.replaceFirst("\"(.+)\"", "$1");
				viewFile = new File(path + File.separatorChar + name);
			} else if (!name.matches(".+\\.{1}[A-Za-z0-9]*")) {// 没有指定后缀时指定后缀
				name = name + "." + Application.viewfileSuffix;
				viewFile = new File(path + File.separatorChar + name);
			}
			try {
				viewFile.createNewFile();
			} catch (IOException e) {
				if (Application.DEBUG > 0)
					e.printStackTrace();
				return;
			}
			savingView();
		}
	}

	public void saveAsSvg() {
		SVGGen svg = new SVGGen();
		File file;

		JFileChooser filechooser = new JFileChooser();
		filechooser.setAcceptAllFileFilterUsed(true);

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

			@Override
			public String getDescription() {
				return "Svg 文件 (*.svg)";
			}

			@Override
			public boolean accept(File f) {
				String fileName = f.getName();
				if (f.isDirectory())
					return true;

⌨️ 快捷键说明

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