OpenMap教程–第1部分

介绍

本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。

OpenMap的开发人员指南是非常有用的文档,描述了OpenMap的体系结构,但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用,但还不够。

OpenMap是用Swing编写的。 在撰写本文时,最新版本是5.1.12。 您可以从GitHub下载源代码和可执行jar。 将其复制/解压缩/克隆到目录后,可以通过运行适用于您平台的相关脚本( openmap.batopenmap )或双击lib/openmap.jar来执行它。 您应该看到一个完整的GIS应用程序,如图1所示。在本系列文章的最后,我们将尝试构建一个类似的应用程序。 OpenMap源代码还包含一些有关如何使用OpenMap的示例。 在本教程中,我们将基于com.bbn.openmap.app.example.SimpleMap 。 在第二个教程中,我们将使用com.bbn.openmap.app.example.SimpleMap2代码。 以后的教程将基于其他示例。

在本系列教程中,我们将使用最新的NetBeans IDE 8.1创建我们的应用程序。

教程1 –构建基本的地图应用程序

创建一个JFrame应用程序

在第一个教程中,我们将构建一个包含映射的基本JFrame应用程序(参见图2)。 通过执行以下步骤,打开NetBeans并创建一个新的Java应用程序:

  1. 打开菜单File→New Project,然后选择CategoryJavaProjectJava Application (图3)。 单击下一步
  2. 在下一步中,提供名称和位置。 确保对库使用专用文件夹,并且不要选择主类(图4)。 点击完成
  3. 创建新项目后,通过右键单击Source Packages并从弹出菜单中选择New→Java Package ,创建一个名为openmap的新软件包。
  4. 右键单击“ 库”文件夹,然后从弹出菜单中选择“ 添加JAR /文件夹 ”操作。 导航到OpenMap安装的lib文件夹,然后选择openmap.jar 。 您可以使用相对路径,也可以将其更好地复制到Libraries文件夹中(图5)。 单击“ 打开”关闭对话框!

    图1:OpenMap GIS应用程序窗口

    图1:OpenMap GIS应用程序窗口

  5. 您还需要复制地图文件。 最常见的格式是.shp (ESRI Shape)。 通过在NetBeans中选择“ 文件”窗口,右键单击OpenMap1项目,然后从弹出菜单中选择“ 新建”→“文件夹” ,创建一个新的文件夹层次结构resources/map 。 输入名称resources ,然后单击确定 。 右键单击resources文件夹,然后重复该过程以在其中创建地图文件夹。 将share/data/shape文件夹从您的OpenMap安装复制到map文件夹
  6. 右键单击openmap包,然后从弹出菜单中选择New→JFrame Form ,以创建新的JFrame表单。 给它起一个名字,例如MapFrame ,然后单击Finish

    基本的OpenMap Swing应用程序

    基本的OpenMap Swing应用程序

  7. 单击Source按钮以查看生成的代码(请参见清单1)。
  8. 添加行super("Simple Map"); 在构造函数中设置窗口标题。
  9. 构造函数初始化JFrame 。 到目前为止,没有添加任何内容。 由于它是一个GUI应用程序,因此需要在EDT线程中运行,这就是NetBeans在main()方法中为我们编写的内容。
  10. 单击返回到“ 设计”按钮以查看空白表格。

我们可以将OpenMap JavaBeans添加到面板中。 要做到这一点:

  1. 右键单击调色板,然后选择“ 调色板管理器”
  2. 单击“ 新建类别”,然后输入OpenMap作为类别名称。 单击单击从JAR添加按钮,导航到openmap.jar 选择显示所有JavaBeans单选按钮并选择所有可用组件。 单击下一步。
  3. 选择OpenMap调色板类别,然后单击Finish 。 新的调色板类别已添加到“调色板”中。

    3:创建一个新的Java应用程序

    3:创建一个新的Java应用程序

添加地图

  1. 找到MapBean并将其拖动到MapFrame
  2. 在NetBeans的Navigator窗口中,右键单击mapBean1 ,选择Change Variable Name并将其设置为mapBean
  3. 在“ 导航器”窗口中,右键单击JFrame并将其布局更改为BorderLayout
  4. 结果代码如清单2所示。

    F图4:提供项目名称和位置

    F图4:提供项目名称和位置


图5:将openmap.jar添加到您的Libraries文件夹

图5:将openmap.jar添加到您的Libraries文件夹

com.bbn.openmap.MapBean组件是OpenMap工具包中的主要地图窗口组件。 MapBean派生自java.awt.Container类。 因为它是Swing组件,所以可以像其他任何用户界面组件一样将其添加到Java窗口层次结构中。

为了在MapBean创建地图,需要将Layers (com.bbn.openmap.Layer)添加到MapBean 。 图层派生自java.awt.Component ,它们是可以添加到MapBean的唯一组件。 因为LayersMapBean容器中包含的Components ,所以Layers在地图上的呈现由Java组件呈现机制控制。 该机制控制分层组件如何在彼此之上绘制。 为了确保按照正确的顺序将每个组件绘制到窗口中, Component类包括一个方法,该方法允许其告知渲染机制它想被绘制。 此功能允许Layers彼此独立工作,并让MapBean避免知道图层上正在发生的事情。

清单1:基本的Swing应用程序

public class MapFrame extends javax.swing.JFrame {/** Creates new form MapFrame */public MapFrame() {super("Simple Map");initComponents();}@SuppressWarnings("unchecked")// <editor-fold defaultstate="collapsed" desc="Generated Code">                          private void initComponents() {// Content suppressed}  /*** @param args the command line arguments*/public static void main(String args[]) {/* Create and display the form */java.awt.EventQueue.invokeLater(new Runnable() {@Overridepublic void run() {new MapFrame().setVisible(true);}});}
}

清单2:添加一个MapBean

@SuppressWarnings("unchecked")// <editor-fold defaultstate="collapsed" desc="Generated Code">                          private void initComponents() {mapBean = new com.bbn.openmap.MapBean();setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);getContentPane().add(mapBean, java.awt.BorderLayout.CENTER);pack();}

清单3:将ShapeLayer添加到MapBean

/*** Create a ShapeLayer to show world political boundaries. Set the properties of the layer. This assumes that* the datafiles {@code dcwpo-browse.shp} and {@code dcwpo-browse.ssx} are in a path specified in the CLASSPATH variable.* These files are distributed with OpenMap and reside in the toplevel "share" subdirectory.*/
private void initMap() {Properties shapeLayerProps = new Properties();shapeLayerProps.put("prettyName", "Political Solid");shapeLayerProps.put("lineColor", "000000");shapeLayerProps.put("fillColor", "BDDE83");shapeLayerProps.put("shapeFile", "resources/map/shape/dcwpo-browse.shp");shapeLayerProps.put("spatialIndex", "resources/map/shape/dcwpo-browse.ssx");ShapeLayer shapeLayer = new ShapeLayer();shapeLayer.setProperties(shapeLayerProps);// Add the political layer to the mapmapBean.add(shapeLayer);
}

OpenMap应用程序中的图层可以使用来自许多来源的数据:

  • 通过计算
  • 来自本地硬盘驱动器的数据文件。
  • 来自URL的数据文件。
  • 来自jar文件中包含的数据文件。
  • 使用从数据库(JDBC)检索的信息。
  • 使用从地图服务器接收的信息(图像或地图对象)。
  1. 清单3显示了在initComponents()之后在MapFrame的构造函数中添加的新方法initMap() ,该方法显示了如何向ShapeLayer添加MapBean ,以呈现从shape (.shp)文件检索的政治边界图。 右键单击MapFrame类,然后选择Run File 。 您应该看到图2的窗口。做得好。

    OpenMap应用程序配置有openmap.properties file 。 该文件的内容指定创建哪些组件并将其添加到应用程序框架(包括层)中。 只需使用文本编辑器修改o penmap.properties文件,即可配置应用程序而无需重新编译。 只需将上述属性文件添加进去,就可以将已经了解框架的组件添加到应用程序中。 为使用属性编写的组件将获得其设置,以便正确初始化自己。 例如,依赖于数据文件或服务器位置的层通常具有允许在运行时设置这些位置的属性。 此属性文件通常位于应用程序文件夹中,或者位于用户的主文件夹中。 在后一种情况下,每个用户都可以根据自己的需求自定义应用程序。

    让我们将形状图层的属性移动到属性文件,然后从那里读取它们。

  1. 右键单击OpenMap项目,然后从弹出菜单中选择“ 新建”→“属性文件 ”。 给它命名属性,然后单击Finish
  2. 您可以在Projects窗口这个文件,显示文件窗口中单击和双击它在NetBeans编辑器中打开它。
  3. 粘贴清单4的内容。
  4. 注释掉在initMap()方法中设置形状层属性的行,并将其替换为清单5的代码。
  5. 再次运行该应用程序以查看完全相同的窗口(图2)。 清单4:openmap.properties
    prettyName=Political Solid
    lineColor=000000
    fillColor=BDDE83
    shapeFile=resources/map/shape/dcwpo-browse.shp
    spatialIndex=resources/map/shape/dcwpo-browse.ssx

    OpenMap提供了一个特殊的类来处理属性。 com.bbn.openmap.PropertyHandler是使用openmap.properties文件配置应用程序的组件。 可以知道在Java类路径和应用程序用户的主目录中,从哪个文件读取属性或将其留给自己来查找openmap.properties文件。

    清单5:initMap()的内容

    InputStream is = null;try {is = new FileInputStream("openmap.properties");shapeLayerProps.load(is);} catch (FileNotFoundException ex) {Logger.getLogger(OpenMap.class.getName()).log(Level.SEVERE, null, ex);} catch (IOException ex) {Logger.getLogger(OpenMap.class.getName()).log(Level.SEVERE, null, ex);} finally {if (is != null) {try {is.close();} catch (IOException ex) {Logger.getLogger(OpenMap.class.getName()).log(Level.SEVERE, null, ex);}}}
  1. 清单6显示了更新后的initMap()您不再需要Properties实例。 只需确保您告诉PropertyHandler.Builder()在本地目录(也称为./openmap.properties)中使用openmap.properties ,否则它可能会从用户的主目录或另一个位置中选取一个。 当然, PropertyHandler可以做的比这更多,我们将在以后的教程中看到。 清单6:使用PropertyHandler的initMap()内容
    private void initMap() {PropertyHandler propertyHandler = null;try {propertyHandler = new PropertyHandler.Builder().setPropertiesFile("./openmap.properties").build();} catch (IOException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}ShapeLayer shapeLayer = new ShapeLayer();if (propertyHandler != null) {shapeLayer.setProperties(propertyHandler.getProperties());}// Add the political layer to the mapmapBean.add(shapeLayer);
    }

并发呢?

剩下的唯一障碍是我们将地图文件加载到EDT线程中。 如果我们需要加载一个大地图,这将延迟等待加载大地图的应用程序的启动。 我们需要将此任务委托给另一个线程。

有(至少)四种方法可以执行此操作:

  • javax.swing.SwingWorker
  • com.bbn.openmap.util.SwingWorker
  • java.awt.SecondaryLoop
  • java.util.concurrent.CompletableFuture

让我们开始看看它们中的每一个。

javax.swing.SwingWorker

传统方法是使用SwingWorker来完成脏工作(清单7)。 通用类SwingWorker提供了两种参数化类型。 第一个参数化类型( ShapeLayer )是doInBackground()get()方法的返回类型。 后台任务完成时, get()可访问doInBackground()返回的对象。 第二个参数化类型适用于定期发布的值。 当长时间运行的任务发布部分结果时,这很有用。 在这里,我们使用Void ,因为我们不发布部分结果。 doInBackground()的代码在后台线程中执行。 在这里,我们使用PropertyHandler读取属性,并创建并返回ShapeLayer

要启动后台线程,我们调用SwingWorker's execute()方法。 这样可以安排线程执行并立即返回。 后台任务完成后,将在EDT中调用overridden done()方法。 使用此方法可以在其中放置代码以更新或刷新GUI. Method get() GUI. Method get()阻塞,直到后台任务完成为止。 但是,如果在方法done()调用get() ,则由于后台任务已完成,因此不会发生阻塞。 在此方法中,我们将图层添加到mapBean 。 但是,由于已经渲染了MapFrame ,因此也需要刷新它才能渲染地图图层。 这是通过重新验证MapFrame来实现的。

清单7:使用javax.swing.SwingWorker的initMap()内容

private void initMap() {SwingWorker<ShapeLayer, Void> worker = new SwingWorker<ShapeLayer, Void>() {@Overridepublic ShapeLayer doInBackground() {PropertyHandler propertyHandler = null;try {propertyHandler = new PropertyHandler.Builder().setPropertiesFile("./openmap.properties").build();} catch (IOException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}ShapeLayer shapeLayer = new ShapeLayer();if (propertyHandler != null) {shapeLayer.setProperties(propertyHandler.getProperties());}return shapeLayer;}@Overrideprotected void done() {try {if (!isCancelled()) {// Add the political layer to the mapmapBean.add(get());MapFrame.this.revalidate();}} catch (InterruptedException | ExecutionException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}}};// invoke background threadworker.execute();
}

com.bbn.openmap.util.SwingWorker

第二种解决方案使用OpenMap提供的SwingWorker (清单8)。 这是Java Swing的SwingWorker的简化版本。 参数化类型( ShapeLayer )是Construct()方法的返回类型。 在这里,我们将ShapeLayer的创建重构为其自己的方法getShapeLayer() (清单9)。

清单8:使用com.bbn.openmap.util.SwingWorker的initMap()内容

private void initMap() {com.bbn.openmap.util.SwingWorker<ShapeLayer> worker = new com.bbn.openmap.util.SwingWorker<ShapeLayer>() {@Overridepublic ShapeLayer construct() {return getShapeLayer();}@Overridepublic void finished() {// Add the political layer to the mapmapBean.add(get());MapFrame.this.revalidate();}};// invoke background threadworker.execute();
}

要启动后台线程,我们调用SwingWorker的execute()方法。 这样可以安排线程执行并立即返回。 后台任务完成后,将在EDT中调用重写的finished()方法。 使用此方法可以在其中放置代码以更新或刷新GUI。 Method get()阻塞,直到后台任务完成为止。 但是,如果在方法finished()调用get() ,则由于后台任务已完成,因此不会发生阻塞。 在此方法中,我们将图层添加到mapBean 。 但是,由于已经渲染了MapFrame ,因此也需要刷新它才能渲染地图图层。 这是通过重新验证MapFrame来实现的。

如果添加Thread.sleep(10_000);则可以在快速计算机中完成此操作Thread.sleep(10_000); construct()方法中return语句之前的语句。 您应该看到应用程序的窗口没有等待SwingWorker完成其工作才能显示。

清单9:getShapeLayer()重构方法

private ShapeLayer getShapeLayer() {PropertyHandler propertyHandler = null;try {propertyHandler = new PropertyHandler.Builder().setPropertiesFile("./openmap.properties").build();} catch (IOException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}ShapeLayer shapeLayer = new ShapeLayer();if (propertyHandler != null) {shapeLayer.setProperties(propertyHandler.getProperties());}
//    try {
//        Thread.sleep(10_000);
//    } catch (InterruptedException ex) {
//        Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);
//    }return shapeLayer;
}

java.awt.SecondaryLoop

第三种解决方案使用SecondaryLoop(清单11)。 该接口提供了两种方法enter()exit() ,可用于启动和停止事件循环。 即使属性的加载和形状层的创建是在不同的线程中完成的,UI也没有响应,并且正在等待工作线程完成之后才在屏幕上呈现。

在JavaDoc中:“当调用enter()方法时, 当前线程将被阻塞,直到循环被exit()方法终止为止。 同样,新的事件循环在事件分发线程上启动,该线程可能是当前线程,也可能不是当前线程。 通过调用其exit()方法,可以在任何线程上终止该循环。 […]应用此接口的典型用例是AWT和Swing模态对话框。 当模式对话框显示在事件分发线程上时,它将进入一个新的辅助循环。 稍后,当对话框被隐藏或放置时,它退出循环,线程继续执行。” 换句话说,它确实阻塞了当前线程,因此在所有情况下都不是SwingWorker的“替代”。 没有像SwingWorker中那样的done()回调方法,您可以在不阻塞当前线程的情况下调用get()

清单10:使用SecondaryLoop的initMap()内容

private void initMap() {final ShapeLayer shapeLayer = new ShapeLayer();final SecondaryLoop loop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();Thread work = new Thread() {@Overridepublic void run() {PropertyHandler propertyHandler = null;try {propertyHandler = new PropertyHandler.Builder().setPropertiesFile("./openmap.properties").build();} catch (IOException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}if (propertyHandler != null) {shapeLayer.setProperties(propertyHandler.getProperties());}loop.exit();}};// We start the thread to do the real work  work.start();// Blocks until loop.exit() is called  loop.enter();// Add the political layer to the mapmapBean.add(shapeLayer);
}

java.util.concurrent.CompletableFuture

Java 8提供了一个新类CompletableFutureCompletableFuture<T>通过提供功能性的单子运算并促进异步的,事件驱动的编程模型(而不是在较早的Java中进行阻止)来扩展Future<T>

您需要具有JDK 8或更高版本才能使用它。 如果没有,请右键单击OpenMap项目,然后选择Properties 。 选择类别库,然后选择Java 8 Java平台(您可能需要通过单击“ 管理平台”按钮并导航到下载和安装JDK 8的文件夹来添加新的Java 8平台)。 然后,选择Sources类别,并将Source / Binary Format更改为JDK 8

通常,Future表示由其他线程运行的一段代码,但它们不是异步的,即,您不能告诉它们异步执行任务并在将来的某个时间返回结果。 在这种情况下,您可以简单地创建一个CompletableFuture并将其返回给客户端,并且只要您认为结果可用,就可以complete()将来)并解锁所有等待该将来的客户端。 当然,像SwingWorker一样,有一个阻塞的get()方法。

CompletableFuture提供了异步方法和非异步方法,这些方法在与先前任务不同的另一个线程中执行其任务, 而非异步方法在与先前任务相同的线程中执行其任务。 在异步方法中,任务被提交到fork-join线程池,完成后,结果将传递到下一个任务。 下一个任务完成时,其结果将进一步发送,依此类推。 它非常简洁明了。

清单11:使用CompletableFuture的initMap()内容

private void initMap() {CompletableFuture.supplyAsync(() -> getShapeLayer()).thenAcceptAsync(shapeLayer -> {// Add the political layer to the mapmapBean.add(shapeLayer);MapFrame.this.revalidate();});
}

修改后的initMap()如清单11所示。您可以通过调用supplyAsync()并传递Supplier() -> getShapeLayer() )向JDK 8中引入的全局通用ForkJoinPool.commonPool()提供新任务。 。 如果您不想使用公共线程池,还有一个重写的supplyAsync()方法可以接受执行程序。 Supplier<R>是Java 8中引入的新接口,它不接受任何参数并返回类型R的值(在本例中为ShapeLayer )。

您可以使用thenApply()thenApplyAsync()方法(接受Function<T, R> )来应用进一步的处理,但是在我们的示例中thenApplyAsync()

您可以使用非阻塞的 thenAccept()thenAcceptAsync()方法异步地返回结果,该方法接受Consumer<T> 。 它们使您可以在准备就绪时消费未来的价值。 Consumer<T>Supplier<R>; 它接受类型T的参数并返回void

看看最后一个解决方案有多优雅。

结论

我们在OpenMap的第一个教程中走了很长一段路。 我们学习了如何在NetBeans IDE(它是一个Swing JFrame创建MapFrame ,并了解了如何使用IDE将OpenMap JavaBeans添加到Palette,然后将MapBean拖到MapFrame 。 我们学习了如何向MapBean添加图层以显示.shp地图文件。 通过属性文件配置层。 我们看到了如何使用PropertyHandler读取属性。 我们还看到了四种从不同线程加载地图文件的方法,即使地图文件加载时间过长,也可以使MapFrame保持响应。

在下一个教程中,我们将更深入地了解有关MapHandlerOpenMap内部。

翻译自: https://www.javacodegeeks.com/2015/10/openmap-tutorial-part-1.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356954.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

killall 后面信号_Linux 下使用 killall 命令终止进程的 8 大用法

Linux 的命令行提供很多命令来杀死进程。比如&#xff0c;你可以向 kill 命传递一个PID来杀死进程&#xff1b;pkill 命令使用一个正则表达式作为输入&#xff0c;所以和该模式匹配的进程都被杀死。但是还有一个命令叫 killall &#xff0c;默认情况下&#xff0c;它精确地匹配…

分享一些我的远程办公经验

前言 大家好&#xff0c;我叫孙叫兽&#xff0c;本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢&#xff0c;因为从事的开发项目比较保密&#xff0c;比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

SqlServer按中文数字排序

表数据: 按名称排序 并不能得到一二三四五六的顺序 select * from LiWei order by name 找到中文数字在一二三四五六七八九十的位置 select id,name,SUBSTRING(name,2,1) as 中文数字,charindex(SUBSTRING(name,2,1),一二三四五六七八九十) as 中文数字所在位置 from LiWei 按中…

C语言--直接插入排序【排序算法|图文详解】

一.直接插入排序介绍&#x1f357; 直接插入排序又叫简单插入排序&#xff0c;是一种简单直观的排序算法&#xff0c;它通过构建有序序列&#xff0c;对于未排序的数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 算法描述&#xff1a; 假设要排序…

python 读取sqlite存入文件_如何通过python读取sqlite数据文件

sqlite简介&#xff1a;sqlite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它的设计目标是嵌入式的&#xff0c;而且目前已经在很多嵌入式产品中使用了它(如安卓系统)&#xff0c;它占用资源非常的低&#xff0c;在嵌入式设…

分享一些前端优质的掘金小册,学完技术感觉已经超神了

大家好&#xff0c;本期内容给大家推荐一些优质的前端掘金小册&#xff0c;基本每个都是专栏小册的形式&#xff0c;比较适合初学者及工作几年的前端小伙伴&#xff0c;里面的内容讲解的比较详细&#xff0c;作者也是一线的大厂工作者。有兴趣的小伙伴快来打卡看一下吧&#xf…

sp烘焙流程_次世代86机甲战神制作全流程

1介绍Hello&#xff0c;大家好&#xff01;我叫周玉亮。首先感谢一下小左老师对我的作品的认可&#xff0c;以及给予我这次宝贵的分享机会。本次分享的是我的第一个次世代硬表面作品&#xff0c;名为《86机甲战神》&#xff0c;制作时间3周。时间还是相当紧的&#xff0c;要在3…

esper_Twitter4j和Esper:在Twitter上跟踪用户情绪

esper对于复杂事件处理和Twitter API的新手&#xff0c;我希望这是一个简短的教程&#xff0c;可以帮助他们Swift起步。 管理大数据并从中挖掘有用的信息是当前技术中最热门的讨论主题。 来自Twitter&#xff0c;Facebook和Linkedin等社交网络的半结构化数据的爆炸式增长使Hado…

前端实现流星雨特效

目录 前言 效果图&#xff1a; HTML CSS 完整代码 前言 使用htmlcss实现简单得浏览器特效&#xff0c;在编译器用导入项目&#xff0c;直接在浏览器打开即可&#xff0c;效果十分得炫酷&#xff0c;十分得哇塞&#xff0c;女朋友直呼NB! 效果图&#xff1a; HTML <!DO…

elementui中tabs切换item中的内容会变_中后台UX优化之道

前言“前台重体验&#xff0c;后台重逻辑”&#xff0c;B端谈 UX 有没有价值&#xff1f;一切电子化的今天&#xff0c;运营、审核、电销、账务……无数岗位依赖中后台系统来完成他们的日常工作&#xff0c;好的 UX 确实可以直接为这些产能提效当中后台的工程师们花费了巨大精力…

介体设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

jvm需要多长时间才能进行转义分析? 可能比您想象的要长。

这篇文章着眼于转义分析&#xff0c;特别是jvm在运行的程序中执行转义分析需要多长时间。 我做了一些观察&#xff0c;但目前还没有全部解释。 作为介绍&#xff0c;让我们绕道看看jvm -Xcomp中一个鲜为人知且使用更少的标志&#xff08;这将是一件好事&#xff09;。 该标志…

Linux常用操作指令整理,这个操作服务器实在是太方便了

目录 前言 常用指令 系统管理命令 打包压缩相关命令 关机/重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 更改文件的用户及用户组 文件权限管理 更改权限 前言 由于在银行工作&#xff0c;一个项目需要在云桌面、SIT、UAT、小版本、联调环境、准生产…

http invoker_Http Invoker的Spring Remoting支持

http invokerSpring HTTP Invoker是Java到Java远程处理的重要解决方案。 该技术使用标准的Java序列化机制通过HTTP公开服务&#xff0c;并且可以看作是替代方法&#xff0c;而不是Hessian和Burlap中的自定义序列化。 而且&#xff0c;它仅由Spring提供&#xff0c;因此客户端和…

前端实现数字快速递增_天正CAD教程之递增文字应用实例

好课推荐&#xff1a;1、CAD2014&#xff1a;点击查看 2、室内&全屋&#xff1a;点击查看 3、CAD2019&#xff1a;点击查看4、CAD2018&#xff1a;点击查看5、Bim教程&#xff1a;点击查看 6、室内手绘&#xff1a;点击查看7、CAD三维&#xff1a;点击查看8、全屋定制&…

模板设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

账号被暂时禁用使用VScode不能上传代码的解决办法

最近项目在开发的过程中突然不能提交代码&#xff0c;然后使用git账号登录gitee&#xff0c;发现账号账号不能登录了&#xff0c;不知道什么原因导致的禁用&#xff0c;这个账号sunjiaoshou01是被行方同步数据导致的禁用&#xff0c;一问管理员就说是可能一个月没登录会自动封禁…

地图库地之图地图窝_「方舆」秦朝地图及行政区划

秦朝是中国历史上一个极为重要的朝代&#xff0c;由战国时期的秦国发展起来的统一大国&#xff0c;它结束了自春秋起五百年来分裂割据的局面&#xff0c;成为中国历史上第一个大一统的中央集权制国家。秦朝统一六国时&#xff0c;国土面积为214万平方公里&#xff0c;后北收河套…

智能柜台C端代码规范

语法上建议&#xff1a;一、建议尽量使用””代替””上述比较好上述HX0188是一个字符串&#xff0c;用!替代比较好二、引用的组件/插件在当前vue文件内并未使用例&#xff1a;chk_bcip\src\business\common\views\ common-auditwait.vueDevice._$和Utils.AppUtils 都未使用&am…

华为云电脑和马云无影比_阿里云打造未来电脑无影,却因为5G限制,很难达到普及...

在9月17日&#xff0c;在2020阿里巴巴云栖大会上&#xff0c;阿里云发布了第一台云电脑"无影"&#xff0c;极致的简约&#xff0c;一张卡片大小的机器就等于一台电脑了。看到这款电脑的宣传片&#xff0c;真的是极致的未来感&#xff0c;随随便便一块小透明玻璃就是电…