尝试JavaFX开发

曾经有报道说JavaFX将使java在桌面开发上大有作为,感觉好像是很高端的样子,今天尝试了一下,界面对于自用的工具来说,本来也不多重要,只是一个简单的尝试 简单说下大致的步骤和一些思路,可能有错误。 javafx需要sdk支持,java7之后的都有的。设计思路是数据和代码分离,界面通过xml或json数据来描述,这样就把业务逻辑代码和界面实现代码分开了 一个简单的开发过程应该是这样的 1.使用JavaFX Scene Builder来绘制界面,保存为xml/json格式 画的话没啥要说的,了解一下基本的整体概念就行。 2.在eclipse里新建工程,可以是普通工程,将1中的文件放到资源目录,在代码里加载,然后界面就加载成功了。 Node topNode = FXMLLoader.load(AFI.class.getResource("/afimain.fxml")); 逻辑代码,比如一个简单的按钮事件可以通过 Node node = topNode.lookup("#paneRightBottom"); 来查找到id为paneRightBottom的元素,然后就可以通过对node添加事件监听器来完成一些功能了 主要想说的是: JavaFX和WPF其实思路是一模一样的,恰好WPF我也用过,感觉两个都没搞起来,虽然界面炫,然后我去维基看了下: 该产品于2007年5月在JavaOne大会上首次对外公布。JavaFX技术主要应用于创建Rich Internet application(RIAs)。JavaFX期望能够在桌面应用的开发领域与Adobe公司的AIR、OpenLaszlo以及微软公司的Silverlight相竞争 已经7年了,用户数应该是非常少的,成熟的商业型产品也没几个,在尝试的过程中,我在stackoverflow,以及一些很不错的java博客上,大量查找基本也没有太多的信息,都是一些很浅的应用,包括stackoverflow上的回答数,基本还是能反映出来的,主要应用于RIA,而当前RIA已经出html5的天下了。SL早都不更新了,这种坑爹的所谓新技术。 Oracle还是好好把Swing搞好吧。。不建议尝试。

2014-02-11 · 1 min · bystander

[笔记]写代码遇到的一些问题汇总下

本篇是用来填上一篇 挖下的坑的。 1.java调用webservice 有一些已有的webservice服务,由xfire生成发布,有些有参数,有些无参数,无参数的直接我直接使用org.codehaus.xfire这个包里的Client来动态生成客户端。然后调用就可以了。非常简单 Client client = null; try { client = new Client( new URL( "http://leaver.me/testService?wsdl")); client.invoke("refreshAllCache", new Object[0]); } catch (MalformedURLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } 但对于有参的,且是服务器自定义的类作为参数的时候,实在是搞不定。。不管是把自定义的类放到本地,包名一致,在invoke的时候生成这个对象还是其他什么方法。都无法完成。 最终换了直接发送soap报文来完成。dirty hack啊。如果你有一些好的方法希望不吝赐教。 解决方案来源自stackoverflow,因为stackoverflow现在国内好像有时候打不开。因此把代码贴过来。有疑问的话留言讨论。 import javax.xml.soap.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; public class SOAPClientSAAJ { /** * Starting point for the SAAJ - SOAP Client Testing */ public static void main(String args[]) { try { // Create SOAP Connection SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection(); // Send SOAP Message to SOAP Server String url = "http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx"; SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url); // Process the SOAP Response printSOAPResponse(soapResponse); soapConnection.close(); } catch (Exception e) { System.err.println("Error occurred while sending SOAP Request to Server"); e.printStackTrace(); } } private static SOAPMessage createSOAPRequest() throws Exception { MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage soapMessage = messageFactory.createMessage(); SOAPPart soapPart = soapMessage.getSOAPPart(); String serverURI = "http://ws.cdyne.com/"; // SOAP Envelope SOAPEnvelope envelope = soapPart.getEnvelope(); envelope.addNamespaceDeclaration("example", serverURI); /* Constructed SOAP Request Message: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://ws.cdyne.com/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <example:VerifyEmail> <example:email>[email protected]</example:email> <example:LicenseKey>123</example:LicenseKey> </example:VerifyEmail> </SOAP-ENV:Body> </SOAP-ENV:Envelope> */ // SOAP Body SOAPBody soapBody = envelope.getBody(); SOAPElement soapBodyElem = soapBody.addChildElement("VerifyEmail", "example"); SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("email", "example"); soapBodyElem1.addTextNode("[email protected]"); SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("LicenseKey", "example"); soapBodyElem2.addTextNode("123"); MimeHeaders headers = soapMessage.getMimeHeaders(); headers.addHeader("SOAPAction", serverURI + "VerifyEmail"); soapMessage.saveChanges(); /* Print the request message */ System.out.print("Request SOAP Message = "); soapMessage.writeTo(System.out); System.out.println(); return soapMessage; } /** * Method used to print the SOAP Response */ private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); Source sourceContent = soapResponse.getSOAPPart().getContent(); System.out.print("\nResponse SOAP Message = "); StreamResult result = new StreamResult(System.out); transformer.transform(sourceContent, result); } } 2.Access restriction on class due to restriction on required library rt.jar? 报错 ...

2014-02-08 · 4 min · bystander

[藏]Class.getResource和ClassLoader.getResource不同点

有一次遇到了,查了查。原文地址 Java中取资源时,经常用到Class.getResource和ClassLoader.getResource,这里来看看他们在取资源文件时候的路径问题。 Class.getResource(String path) path不以’/'开头时,默认是从此类所在的包下取资源; path 以’/'开头时,则是从ClassPath根下获取; 什么意思呢?看下面这段代码的输出结果就明白了: package testpackage; public class TestMain { public static void main(String[] args) { System.out.println(TestMain.class.getResource("")); System.out.println(TestMain.class.getResource("/")); } } 输出结果: file:/E:/workspace/Test/bin/testpackage/ file:/E:/workspace/Test/bin/ 上面说到的【path以’/'开头时,则是从ClassPath根下获取;】在这里就是相当于bin目录(Eclipse环境下)。 再来一个实例,假设有如下Project结构: 如果我们想在TestMain.java中分别取到1~3.properties文件,该怎么写路径呢?代码如下: package testpackage; public class TestMain { public static void main(String[] args) { // 当前类(class)所在的包目录 System.out.println(TestMain.class.getResource("")); // class path根目录 System.out.println(TestMain.class.getResource("/")); // TestMain.class在<bin>/testpackage包中 // 2.properties 在<bin>/testpackage包中 System.out.println(TestMain.class.getResource("2.properties")); // TestMain.class在<bin>/testpackage包中 // 3.properties 在<bin>/testpackage.subpackage包中 System.out.println(TestMain.class.getResource("subpackage/3.properties")); // TestMain.class在<bin>/testpackage包中 // 1.properties 在bin目录(class根目录) System.out.println(TestMain.class.getResource("/1.properties")); } } ※Class.getResource和Class.getResourceAsStream在使用时,路径选择上是一样的。 Class.getClassLoader().getResource(String path) path不能以’/'开头时; path是从ClassPath根下获取; 还是先看一下下面这段代码的输出: package testpackage; public class TestMain { public static void main(String[] args) { TestMain t = new TestMain(); System.out.println(t.getClass()); System.out.println(t.getClass().getClassLoader()); System.out.println(t.getClass().getClassLoader().getResource("")); System.out.println(t.getClass().getClassLoader().getResource("/"));//null } } 输出结果: class testpackage.TestMain sun.misc.Launcher$AppClassLoader@1fb8ee3 file:/E:/workspace/Test/bin/ null 从结果来看【TestMain.class.getResource("/") == t.getClass().getClassLoader().getResource("")】 如果有同样的Project结构 使用Class.getClassLoader().getResource(String path)可以这么写: package testpackage; public class TestMain { public static void main(String[] args) { TestMain t = new TestMain(); System.out.println(t.getClass().getClassLoader().getResource("")); System.out.println(t.getClass().getClassLoader().getResource("1.properties")); System.out.println(t.getClass().getClassLoader().getResource("testpackage/2.properties")); System.out.println(t.getClass().getClassLoader().getResource("testpackage/subpackage/3.properties")); } }   ※Class.getClassLoader().getResource和Class.getClassLoader().getResourceAsStream在使用时,路径选择上也是一样的。

2013-12-14 · 1 min · bystander

Java动态代理实例

首先什么是代理? 所谓代理呢也就是在调用实现类的方法时,可以在方法执行前后做额外的工作,这个就是代理。 那动态代理呢,官方解释是: Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。 老湿,你说的是个毛啊,完全没看懂啊! 我更喜欢另一种通俗的解释,官方的解释总是高度抽象的,等用了一段时间才能理解体会 动态代理实现了日志和业务的分开,也就是某个类只是要提供了某些业务,比如银行取款业务。这个类实现了取款业务的同时也需要实现日志功能,如果不用动态代理的话,那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念,spring里面的AOP就是一个很好的例子。 不直观啊,老湿,能再给力一点不? 额,这样的话,我们来看一个例子,要用到的两个类 实现java.lang.reflect.InvocationHandler接口提供一个执行处理器,也就是真正做事的,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行业务方法,在业务方法被调用的同时,执行处理器会被自动调用。 记住,动态代理只能对接口 首先业务接口: public interface HelloWorld { public void sayHelloWorld(); } 然后我们是这样写的实现 public class HelloWorldImpl implements HelloWorld { public void sayHelloWorld() { System.out.println("Hello World!"); } } 后来我们觉得执行这个方法前能不能做点其他啥事呢,比如写个日志?见个妹子?啥,这段代码不让改了,改了的话,业务方法和日志混合的一塌糊涂啊,以后想改个日志格式你来写啊 那我们就得定义一个拦截器/执行处理器了。 public class HelloWorldHandler implements InvocationHandler { //目标对象 private Object targetObject; public HelloWorldHandler(Object targetObject){ this.targetObject = targetObject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法调用前"); Object result = method.invoke(this.targetObject, args); System.out.println("方法调用结束"); return result; } } 这客户端咋用啊,老湿 public class HelloWorldTest { public static void main(String[] args) { //业务对象 HelloWorld obj = new HelloWorldImpl(); //拦截器对象 HelloWorldHandler handler = new HelloWorldHandler(obj); //返回业务对象的代理对象 HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance( obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler); //通过代理对象执行业务对象的方法 proxy.sayHelloWorld(); } } 看到没,通过Proxy类的newProxyInstance方法,传入类加载器,类接口,和这个处理器,我们就获得一个代理 执行结果是这样的 方法调用前 Hello World! 方法调用结束 恩,电脑没死机,是这样的

2013-11-24 · 1 min · bystander

使用Maven创建Web项目

本文通过Maven完成一个简单的Web项目(注意,Spring配置不是重点,看看就行) 1.从Maven模板创建Web应用程序 命令格式如下: mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false 这就告诉Maven从**maven-archetype-webapp **这个模板来创建 友情提示:是不是太难记了..好吧,直接输入 mvn archetype:generate 根据向导来创建把。。 比如我这样写: > mvn archetype:generate -DgroupId=com.mkyong -DartifactId=CounterWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] Generating project in Batch mode [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.mkyong [INFO] Parameter: packageName, Value: com.mkyong [INFO] Parameter: package, Value: com.mkyong [INFO] Parameter: artifactId, Value: CounterWebApp [INFO] Parameter: basedir, Value: /Users/mkyong/Documents/workspace [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: /Users/mkyong/Documents/workspace/CounterWebApp [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.147s [INFO] Finished at: Thu Dec 20 20:35:19 MYT 2012 [INFO] Final Memory: 12M/128M [INFO] ------------------------------------------------------------------------ 就创建了一个包名为com.mkyong,类名为CounterWebApp的项目了 2.Maven的Web程序目录结构 标准的web.xml部署描述文件生成了 CounterWebApp |-src |---main |-----resources |-----webapp |-------index.jsp |-------WEB-INF |---------web.xml |-pom.xml 对结构有疑问的去这里 ...

2013-09-20 · 3 min · bystander

Maven安装教程

Maven不需要作为服务组件安装到windows上,仅仅需要下载,解压,然后配置一下环境变量就行了 1.JDK和JAVA_HOME 确保JDK已经安装,同时JAVA_HOME变量已经添加到了windows环境变量里,指向jdk目录 2.下载Maven 去Maven主页,选个版本,点击下载 3.解压 解压下载的zip文件,重命名,比如我放到D盘的Maven目录 4.添加MAVEN_HOME环境变量 添加一个新的环境变量MAVEN_HOME到环境变量,指向Maven目录 5.添加path变量 更新Path变量,把Maven的bin目录添加进去,这样就可以在任何地方执行mvn命令了 6.验证 打开命令行,输入 mvn -version 如果看到类似下面的 C:\Documents and Settings\mkyong>mvn -version Apache Maven 2.2.1 (r801777; 2009-08-07 03:16:01+0800) Java version: 1.6.0_13 Java home: C:\Program Files\Java\jdk1.6.0_13\jre Default locale: en_US, platform encoding: Cp1252 OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows" Maven已经成功的安装配置了。 老外写的太详细了。。。

2013-09-19 · 1 min · bystander

Maven实例入门-随机数生成

看了很多个例子,发现这个最好,译文中会带有我的一些了理解,有问题欢迎指出。 0.Maven是什么? Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 可以看到,核心就是项目管理和自动构建了,从例子中将会体会更深。本例创建一个随机数生成程序。 1.从Maven模板创建项目 Maven的环境变量配置和java类似,直接添加系统变量MAVEN_HOME指向你下载的maven目录,然后将bin目录添加到path环境变量里。 在命令行下,进入到你想存储项目的位置,比如,我自己有个叫work的目录,那么我就cd到work目录,然后按下面的格式输入命令 mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 这是告诉Maven从**maven-archetype-quickstart **创建一个java项目,如果你这个参数不填,那么会列出一个列表,让你选择你想创建什么类型,比如web项目啊,啥的。 友情提示:是不是太难记了..好吧,直接输入 mvn archetype:generate 根据向导来创建把。。 比如 >mvn archetype:generate -DgroupId=com.mkyong -DartifactId=NumberGenerator -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false [INFO] Scanning for projects... [INFO] [INFO] -- omitted for readability [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.mkyong [INFO] Parameter: packageName, Value: com.mkyong [INFO] Parameter: package, Value: com.mkyong [INFO] Parameter: artifactId, Value: NumberGenerator [INFO] Parameter: basedir, Value: /Users/mkyong/Documents/workspace [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: /Users/mkyong/Documents/workspace/NumberGenerator [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.917s [INFO] Finished at: Mon Dec 17 18:53:58 MYT 2012 [INFO] Final Memory: 9M/24M [INFO] ------------------------------------------------------------------------ 这里的groupId就是包名,artifactId就是类名,以后具体的一些其他参数我希望有时间可以跟大家分享。 2.Maven目录结构 上面的命令第一次执行的时候会从apache网站下载maven的一些其他东西,所以务必保持联网。执行成功后,会生成一个这样的目录结构 NumberGenerator |-src |---main |-----java |-------com |---------mkyong |-----------App.java |---test |-----java |-------com |---------mkyong |-----------AppTest.java |-pom.xml 这里main目录是我们的程序住代码目录。源代码会放在/src/main/java/包名 目录里,而单元测试代码会放在/src/test/java/包名 目录里。当然还有一个标准的pom.xml文件会生成。这个pom文件其实类似于Ant的build.xml文件,它包含了项目的信息,从目录结构到项目插件到项目依赖,都有了。。 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mkyong</groupId> <artifactId>NumberGenerator</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>NumberGenerator</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project> 3.用Eclipse写代码 maven已经生成了一个完整的工程了,为了能够导入到eclipse里来编辑代码,我们可以把这个项目转换成eclipse可用的。 ...

2013-09-19 · 2 min · bystander

Maven提示缺少tools.jar

记录一下。 这两天在熟悉Maven,长见识了.后续可能的话会写上一两篇,今天配置的时候提示tools.jar文件。于是使用everything搜了一下,本机的jdk目录还真没有,最后搜了一下,发现是安装jdk时候的问题,具体就是因为安装jdk的时候,后面被让继续安装jre,这个时候,我为了方便,将jre安装在了jdk的目录里,结果导致jre会覆盖到jdk的这两个文件。同时还会覆盖dt.jar这个包,于是,就没了。。这个问题略隐晦了.. 重新安装了jdk,将jdk和jre分开目录,然后设置一下jdk的lib目录到classpath就可以了,问题解决。

2013-09-19 · 1 min · bystander

[译]Java中的CountDownLatch和CyclicBarrier

本文译自官方文档,有细微改动,Java多线程的时候,看了好多文档,还是官方说的最清楚。结合自己的理解,译之。 CountDownLatch 字面意思就是倒计数闩,后面会讲到,这里的同步允许一个或多个线程等待,,知道其他线程进行的一系列操作完成。而CountDownLatch通过一个参数count(数目)来构造,而await()则阻塞当前线程,直到countDown()将count减为了0,然后,所有的阻塞线程被释放,也就是那些调用了await方法的线程立即返回,注意,这是一次性的,也就是说count不能被自动重置,如果你想这么做,CyclicBarrier是可以的。 CountDownLatch用处很多,当用count=1来构造的时候,这就相当于一个开关,所有调用了await方法的线程都在等待,直到有一个线程调用了countDown(),CountDownLatch通过count=N构造的话,就可以使一个线程等待其他N个线程完成操作,或者一个操作被做N次。 简单的demo: 一组worker(工人)线程使用两个CountDownLatch 第一个是开始信号,用来阻止工人提前操作,直到(driver)传送带准备好了才允许开始 第二个是完成信号,他使传送带等待直到所有的worker都完成 class Driver { // ... void main() throws InterruptedException { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // 创建并启动线程 new Thread(new Worker(startSignal, doneSignal)).start(); doSomethingElse(); // 传送带做点准备工作 startSignal.countDown(); // 减为0,工人可以开始了 doSomethingElse(); doneSignal.await(); // 等待直到所有的工人完成任务 } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await();//工人们等待开关打开 doWork(); //做事 doneSignal.countDown(); //做完了就给countdownlatch 减去1 } catch (InterruptedException ex) {} // return; } void doWork() { ... } } 另一个典型的例子就是把问题分成N部分,通过线程执行每一部分,具体的话是将线程入队到一个Executor对象里。然后调用execute方法。当执行完毕一部分,就并给latch 减去1,当减到0的时候调用await的方法就可以继续运行了,当需要重复计数的话,用CyclicBarrier代替 class Driver2 { // ... void main() throws InterruptedException { CountDownLatch doneSignal = new CountDownLatch(N); Executor e = ... for (int i = 0; i < N; ++i) // 创建并开始线程 e.execute(new WorkerRunnable(doneSignal, i)); doneSignal.await(); // 等待所有的线程完成 } } class WorkerRunnable implements Runnable { private final CountDownLatch doneSignal; private final int i; WorkerRunnable(CountDownLatch doneSignal, int i) { this.doneSignal = doneSignal; this.i = i; } public void run() { try { doWork(i); doneSignal.countDown(); } catch (InterruptedException ex) {} // 返回; } void doWork() { ... } } ...

2013-09-15 · 2 min · bystander

使用CSS3的自定义字体美化文字

之前看到一些设计师的主题的字体很美,下载下来发现使用了css3的自定义字体,可以用来显示服务器上的字体,非常方便,学习了一下 1.首先得到字体 这个方法很多,本机的字体,一些国外的免费网站,比如这个:http://www.dafont.com,下载后的字体一般为ttf格式,ttf字体被很多浏览器支持,但是,IE不支持,为了兼容性,需要为IE单独设置字体文件,格式必须为eot,所以我们需要转换字体,使用在线工具,比如http://www.kirsle.net/wizards/ttf2eot.cgi,当然类似的网站有很多,根据个人爱好,随意。 2.添加内容 这里,我写一个简单的html文件,内容为 <body> <p class="test">bystander</p> </body> 在没有设置customFont这个类的css之前,字体就是默认的字体了。 3.设置css样式 @font-face { font-family:myFont;/*主流浏览器可用*/ src:url("PONCTUATION.ttf"); } @font-face { font-family:myFont;/*兼容IE*/ src:url("PONCTUATION.eot"); } .test { font-family:myFont; font-size:40px; } 显示效果就是这样的了…只是用来演示的一个字体。 因为浏览器是要自动下载这个字体文件的,所以对于英文字体没啥问题,英文字体一般这个字体文件在100k左右,和一张图片比起来,基本算不是问题,但是对于中文字体,包一般在10M-20M左右,这样是不现实的,我的想法是,可以自己制作字体包,这样只需要满足常用的一些汉字就行了,大大减少包的大小,然后去找了一下,发现了http://www.high-logic.com/font-editor/fontcreator.html这个软件,是可以直接编辑字体包的,也可以创建字体包,有空了用来试试.

2013-07-17 · 1 min · bystander