基础数据流与对象流分别保存对象
一:前几天在考虑如何使用基础数据流来保存画图板中的数据; 分析: 1,截取图片之后根据图片的大小的创建二维数组,将颜色点保存在数组二维数组中; 2,在paint()方法中将保存在二维数组中的颜色点遍历出来,并绘制 3,如何将绘制的图形保存到文件中 保存; 创建文件输出流:FileOutputStream fos = new FileOutputStream(file); 创建基础数据流:DataOutputStream dos = new DataOutputStream(fos); 再判断监听器中是否存在 if(lis !=null){ int colors[][] = lis.colors; 再判断是否有颜色 if(colors !=null){ dos.wirteInt(lis.colors.lenght); dos.wirteInt(lis.colors[0].lenght); for (int i = 0; i < lis.colors.length; i++) { for (int j = 0; j < lis.colors[i].length; j++) { //将创建出来的颜色保存到创建的二维数组中 int color = lis.colors[i][j]; dos.wirteInt(color); } } } } 打开: FileInputStream fis = new FileInputStream(file); DataInputStream dis = new DataInputStream(fis); // 读取高度和t宽度 int height = dis.readInt(); int width = dis.readInt(); // 定义数组来存放读取的数据 lis.colors = new int[height][width]; for (int i = 0; i < lis.colors.length; i++) { for (int j = 0; j < lis.colors[i].length; j++) { lis.colors[i][j] = dis.readInt(); } } }} 文件的保存与打开 和将截取的图片保存与paint 二者的写法相似
代码如下:
package com.iteye.com; /** *界面的主类,监听器.文件 */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JRadioButton; /** * 画图板的界面类 * * @author * */ public class DrawUI extends JFrame { String path = "F:\\abc\\a.img"; JPanel center; // 单选按钮组 ButtonGroup group = new ButtonGroup(); DrawListener lis; public static void main(String args[]) { DrawUI du = new DrawUI(); du.initUI(); } /** * 初始化窗体的方法 */ public void initUI() { this.setTitle("画图板"); this.setSize(600, 400); // 设置点击关闭按钮的时候退出程序 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体的布局为边框布局 BorderLayout layout = new BorderLayout(); this.setLayout(layout); JMenuBar bar = createJMenuBar(); this.setJMenuBar(bar); JPanel left = this.cerateLeft(); JPanel center = this.createCenter(); JPanel bottom = this.createBottom(); this.add(left, BorderLayout.WEST); this.add(center, BorderLayout.CENTER); this.add(bottom, BorderLayout.SOUTH); this.setVisible(true); // 创建监听器对象 lis = new DrawListener(group); // 给center加上监听器 center.addMouseListener(lis); } /** * 创建菜单条的方法 * * @return */ public JMenuBar createJMenuBar() { JMenuBar bar = new JMenuBar(); JMenu menu = new JMenu("文件"); JMenuItem saveItem = new JMenuItem("保存"); saveItem.setActionCommand("save"); JMenuItem openItem = new JMenuItem("打开"); openItem.setActionCommand("open"); menu.add(saveItem); menu.add(openItem); bar.add(menu); // 给菜单选项添加动作监听器 ActionListener alis = new MyListener(); saveItem.addActionListener(alis); openItem.addActionListener(alis); return bar; } public JPanel cerateLeft() { // 创建三个JPanel JPanel left = new JPanel(); // 设置背景颜色 left.setBackground(new Color(215, 215, 215)); // 设置大小 Dimension dim = new Dimension(80, 100); left.setPreferredSize(dim); // 在左边添加形状选择按钮 String[] items = { "直线", "矩形", "椭圆" }; String[] commands = { "line", "rect", "oval" }; for (int i = 0; i < items.length; i++) { JRadioButton btn = new JRadioButton(items[i]); // 设置按钮的动作命令 btn.setActionCommand(commands[i]); // 分为同一个组 group.add(btn); if (i == 0) {// 设置第一个被选中 btn.setSelected(true); } left.add(btn); } return left; } public JPanel createCenter() { // center需要在改变的时候重新绘制数据,所以要创建MyPanel类的对象 center = new MyPanel(); center.setBackground(Color.WHITE); return center; } public JPanel createBottom() { JPanel bottom = new JPanel(); bottom.setBackground(new Color(215, 215, 215)); bottom.setPreferredSize(new Dimension(100, 80)); return bottom; } // 内部类 class MyPanel extends JPanel { // 重写绘制JPanel的方法 // JPanel发生改变的时候,此方法会自动调用 // 在这个时候可以将需要的数据重新绘制在JPanel上 public void paint(Graphics g) { super.paint(g); // 如果监听器存在,就获得保存图像数据的二维数组 if (lis != null) { int[][] colors = lis.colors; // 如果二维数组存在,证明至少绘制过一次图像 if (colors != null) { // 遍历二维数组 for (int i = 0; i < colors.length; i++) { for (int j = 0; j < colors[i].length; j++) { // 得到点的颜色 Color c = new Color(colors[i][j]); // 绘制一个点 g.setColor(c); g.drawLine(j, i, j, i); } } } } } } // 动作监听器 class MyListener implements ActionListener { public void actionPerformed(ActionEvent e) { // 获得动作命令 String command = e.getActionCommand(); System.out.println(command); if (command.equals("save")) { try { // 将内存中的形状队列保存到文件中 File file = new File(path); FileOutputStream fos = new FileOutputStream(file); DataOutputStream dos = new DataOutputStream(fos); if (lis != null) { int[][] colors = lis.colors; // 如果二维数组存在,证明至少绘制过一次图像 if (colors != null) { // 先写出二维数组的大小 dos.writeInt(lis.colors.length);// 高度 dos.writeInt(lis.colors[0].length);// 宽度 for (int i = 0; i < lis.colors.length; i++) { for (int j = 0; j < lis.colors[i].length; j++) { int color = lis.colors[i][j]; dos.writeInt(color); } } dos.flush(); fos.close(); } } } catch (Exception ef) { ef.printStackTrace(); } } if (command.equals("open")) { try { // 建立文件输入流 File file = new File(path); FileInputStream fis = new FileInputStream(file); DataInputStream dis = new DataInputStream(fis); // 读取高度和t宽度 int height = dis.readInt(); int width = dis.readInt(); // 定义数组来存放读取的数据 lis.colors = new int[height][width]; for (int i = 0; i < lis.colors.length; i++) { for (int j = 0; j < lis.colors[i].length; j++) { lis.colors[i][j] = dis.readInt(); } } fis.close(); //刷新界面,将数据绘制在界面上 center.repaint(); } catch (Exception ef) { ef.printStackTrace(); } } } } }
package com.iteye.com; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import javax.swing.ButtonGroup; import javax.swing.JPanel; /** * 画图板的监听器,继承了鼠标适配器抽象类 * 鼠标适配器抽象类实现了MouseLIstener,MouseMotionListener,MouseWheelListener 只需要重写要是用到的方法 * * @autho */ public class DrawListener extends MouseAdapter { private int x1, y1, x2, y2; private Color c = Color.RED; private Graphics g; private ButtonGroup group; private String command;// 动作命令,作为要绘制的形状类型 line直线 rect矩形 oval椭圆 JPanel center; int[][] colors; public DrawListener(ButtonGroup group) { this.group = group; } /** * MouseEvent :鼠标事件对象,可以得到触发事件的对象 */ public void mousePressed(MouseEvent e) { // 获得事件源对象:鼠标在那个组件上触发事件,这个对象必须要是添加了监听器的 // 在本例中是给Center添加的监听器,事件源一定是Center center = (JPanel) e.getSource(); // 只需要绘制在center上,所以需要从Center上取画布 // 获得center组件在屏幕上占据的区域 g = center.getGraphics(); // 获得要绘制的形状 // 得到按钮组中被选中的按钮的动作命令 command = group.getSelection().getActionCommand(); x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); if (command.equals("line")) { // 画直线 g.drawLine(x1, y1, x2, y2); } else if (command.equals("rect")) { // 画矩形 g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2)); } else if (command.equals("oval")) { // 绘制椭圆 g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2)); } // 绘制完一个图形,就截取一次屏幕 try { Robot robot = new Robot(); // 定义要截取的矩形区域, // 由于要把center中的数据全部保存, // 所以矩形区域就是center在屏幕上占据的区域 // 获得center左上角的点相对于屏幕的坐标 Point point = center.getLocationOnScreen(); // 获得center的宽度和高度 Dimension dim = center.getSize(); Rectangle rect = new Rectangle(point, dim); // 调用截取屏幕的方法 BufferedImage img = robot.createScreenCapture(rect); // System.out.println("left-top:"+point.x+" "+point.y); // System.out.println("dimension:"+dim.width+" "+dim.height); // 根据图像大小定义一个二维数组,用来保存图像中的点 // 图像坐标和数组下标要注意区分 colors = new int[img.getHeight()][img.getWidth()]; // 每种颜色都是有ARGB四个子节组成,每种颜色都可以用int表示 for (int i = 0; i < colors.length; i++) { for (int j = 0; j < colors[i].length; j++) { // 将图像每个坐标点的颜色放到数组对应的下标位置 colors[i][j] = img.getRGB(j, i); } } } catch (Exception ef) { ef.printStackTrace(); } } }
二: 对象流保存(在JAVASE里面写过,就不再贴出来了) 分析 1,将绘制的图形的基本属性定义成一个抽象类,每个图形都去继承它 2,使用队列来保存绘制的图像 3,在paint方法中遍历队列,将遍历出来的队列个数绘制出来(此处是绘制,不是添加到队列中 很容易搞错的); 4,对象流的打开与保存 打开; 先读取个数; 遍历个数并转换成对象,再添加到队列中 保存: 先写图形的个数 遍历队列中的个数--->将个数写出去
相关推荐
而保存和打开文件功能则需要处理文件输入输出流,如FileInputStream和FileOutputStream,以及序列化技术,将画布的状态持久化到磁盘。 此外,为了提高用户体验,开发者可能还实现了平移、缩放等视图操作。这需要...
这个“java画图板”程序是作者初次尝试制作的一个应用程序,它允许用户进行基本的绘图操作,如绘制线条、形状,并且支持文件的保存、打开和新建。以下是关于这个程序和其涉及的Java知识点的详细说明: 1. **Swing库...
【简易画图板VC++课程设计】是一门实践性强、注重动手能力的计算机科学课程,旨在让学生通过实际操作,掌握VC++编程环境下的图形用户界面(GUI)开发技能。在这个项目中,学生需要构建一个类似Windows自带的"画图...
7. **撤销/重做功能**:高级的画图板通常会提供撤销和重做功能,这需要理解如何保存和恢复绘图历史。 8. **保存和加载图片**:应用应能保存用户的绘图为常见的图像格式(如BMP、JPEG或PNG),并能加载这些文件进行...
3. **图形用户界面(GUI)**:为了提供用户友好的交互体验,这个项目使用了Java的GUI组件,如`JFrame`,`JPanel`等,构建了聊天窗口和画图板界面。`Swing`或`JavaFX`是Java中的主要GUI库,它们提供了丰富的组件和...
4. **文件I/O操作**:项目提到可以保存和读取绘图文件,这涉及到Java的文件输入/输出流。使用File类创建文件对象,然后通过FileInputStream和FileOutputStream进行读写操作。对于图像数据,可能采用序列化...
在给定的压缩包子文件的文件名称列表"画图板实现保存和读取"中,我们可以推测这是一个关于图形界面应用程序的例子,可能涉及保存和加载用户在画板上绘制的内容。在Java中,这通常涉及到序列化对象(如图形对象)到...
图形对象的信息(如位置、大小、颜色等)可以被转换为数据流,然后写入文件。在需要时,这些数据可以从文件中读取,恢复到画板上。这种机制确保了用户的工作不会丢失,并且方便了图形的共享和复用。 在实现过程中,...
设计中可能包含以下类:主窗口类(用于承载绘图区域和工具栏)、绘图工具类(用于实现各种绘图动作)、颜色选择类(处理颜色选择)、文件操作类(负责保存和加载图形数据)等。 2.3 流程图 流程图将展示用户如何...
在保存和加载图形时,我们需要正确地处理文件流,确保数据的完整性和正确性。 9. **错误处理**:良好的错误处理是任何应用程序的关键。通过使用`try-catch`块,我们可以捕获可能出现的异常,如文件不存在或无法访问...
标题中的“vb实时接收数据并绘图的程序源码”是指使用Visual Basic(VB)编程语言编写的程序,该程序能够实时地从某种数据源获取数据,并将这些数据以图形的形式展示出来。在实际应用中,这样的功能可能用于监控系统...
本案例中的描述提及了"实现画图板等功能",这可能涉及到图形用户界面(GUI)编程。下面将详细讲解与C++上机实习相关的知识点,以及可能在"Draw"这个子文件中涉及的内容。 1. **C++基础语法**:这是所有C++编程的...
7. **文件操作**:保存和加载用户的文本和图形数据,可能需要实现自定义的文件格式或支持通用格式如 RTF、SVG 等。 8. **调试与测试**:进行充分的单元测试和集成测试,确保程序的稳定性和性能。 9. **异常处理**...
3. **CView 类**:这是显示数据和处理用户输入的视图类。在画板程序中,你需要派生一个新的CView子类,并重写OnDraw函数来实现绘图逻辑。在这个函数中,你可以使用CDC对象进行实际的绘图操作,如画线、填充颜色等。 ...
第九章“画图板保存的实现”展示了如何通过文件输入输出流将画板内容保存至文件,并对画板数据进行保存,这也是对IO知识的实际应用。 第十章“五子棋开发”则是一个更加复杂的项目,分为多个部分,包括开发思路分析...
4. 文件操作:如果报告包含保存和加载绘图的功能,那么可以学习如何实现文件I/O,如使用fstream或二进制流进行数据存储。 5. 错误处理和调试:了解如何在代码中添加错误检查,以及使用调试工具如Visual Studio的调试...
在实际的"WebApplication1"项目中,你可能需要根据具体需求,比如来自数据库的数据、用户输入等,动态生成文字和图片。结合ASP.NET的Page生命周期和事件处理,可以创建一个交互式的网页服务,允许用户上传图片、输入...
12. Flash动画制作:在Flash中,插入关键帧和空白关键帧分别对应F6和F7快捷键,新建、打开和保存文档的快捷键是Ctrl+N、Ctrl+O和Ctrl+S。绘制椭圆时按住Shift键可绘制正圆。创建传统补间动画需要元件或组合位图。...