??xml version="1.0" encoding="utf-8" standalone="yes"?>
以下是从“恋花和”的——六Ʋ红(博客Q处看到的一个关于Eclipse的东东,因ؓq日在学习用EclipseQ觉得他整理的这个列表很好,一时看不完Q特意抓到自q本本里,嘿嘿Q可以留着慢慢看:
1、Apress.The.Definitive.Guide.to.SWT.and.JFace
Apress出版的《The.Definitive.Guide.to.SWT.and.JFace》chm格式?sh)子书,Eclipseq_的两个用L面工LQSWT和JFace的java~程指南?BR>http://www.amazon.com/exec/obidos/tg/detai...6889430-0550522
http://images.amazon.com/images/P/15905932...SCMZZZZZZZ_.jpg
2、JasperAssistant.v1.4.2
JasperAssistant是一Ƒ֏视化的JasperReports报表设计工具QJasperReports是一个非常流行的开放源码报告引擎。JasperAssistantZEclipse的插件程序结构,通过逼真的图形界面方便的创徏JasperReports报表定义文g?BR>http://www.jasperassistant.com/
http://www.jasperassistant.com/shots/full.png
3、JVider.for.Eclipse.v1.7e1.Java
一ƾؓJavaSwing应用E序设计的GUIBuilder工具。在他的帮助下,你可以很单的Z的Java校应用程序和E序设计囑Ş用户界面?BR>http://www.jvider.com/
http://www.jvider.com/jviderscreen.png
4、RMI.Plugin.for.Eclipse.v1.6.1
Eclipse开发^台的RMIQ基于Java的分布计框Ӟ插gQ是在JavaSDKq_通过调用RMI~译器自动生成远E对象stubQ桩Q和skeletonQ框Ӟ的简便方法?BR>http://www.genady.net/rmi/
http://www.genady.net/rmi/v16/screenshots/...rmi-eclipse.png
5、ddison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004
?sh)子书,Eclipsepd之SWT_解QSWT是StandardWidgetToolkitQ是在java中创建图形界面的cd
http://www.amazon.com/exec/obidos/ASIN/032...8151071-6877408
http://images.amazon.com/images/P/0321256638.01.LZZZZZZZ.jpg
http://0daycheck.eastgame.net/0day/archives/22338_AddisonWesley.html
6、Omondo.Eclipse.UML.Studio.Edition.v1.1.0
OmondoEclipseUML是一Ƒ֏视化的模块设计工P可以完全集成于Eclipse和CVS?BR>http://www.omondo.com
http://0daycheck.eastgame.net/0day/archives/21757_OmondoEclipse.html
Omondo.Eclipse.UML.Studio.Edition.v1.1.0
OmondoEclipseUML是一Ƒ֏视化建模工具Q可以与Eclipse和CVS无缝集成?/P>
7、Oxygen.XML.Editor.v5.0.Eclipse.plugin
OxygenXMLeditor是一Ƒ֟于Java的XML~辑器,支持XML,XSL,TXT,XSD,DTD文档Q能自行校验XML,XSL,XSD代码Q提C本错误。Oxygen能自动完成结束标{,代码高亮现实Q支持Unicode?BR>http://www.oxygenxml.com/features/
http://www.oxygenxml.com/img/oxygen-mac.gif
http://0daycheck.eastgame.net/0day/archives/19151_OxygenXMLEdit.html
8、Jigloo.GUI.Builder.v3.0.1
为EclipseJavaIDE和WebSphereStudio设计的插Ӟ可以用来创徏和管理Swing和SWTGUIcR?BR>http://cloudgarden.com/jigloo/
http://cloudgarden.com/jigloo/images/screenshot4_sm.jpg
http://0daycheck.eastgame.net/0day/archives/19038_JiglooGUIBuil.html
9、Code.Pro.Studio.3.0.0
一ƾؓ那些使用IBMwebspherestuodio和eclipse开发环境的开发者设计的软g。能够让java的开发者有效开速的开发高质量的Y件。这ƾY件可以通过许多重复d来完成Y件的开发,同时能够极大的提高用L面和使开发活动流水线化。此ƾY仉成了CodeProAdisorQCodeProAgilityandCodeProBuild?BR>http://www.instantiations.com/codepro/default.htm
http://www.instantiations.com/codepro/imag...pstudio3-sm.gif
10、Window.Builder.Pro.2.1.1
一Ƒ֟于EclipseSWT技术上的双向javaGui设计软g。具备SWT设计以及Swing设计两个主要功能。该软g会被作ؓ一个插仉嵌入Eclipse以及其他一些兼容的IDEs中(WSSD,WSAD,WSED{等Q。新?.0版本支持Eclipse3.0?BR>http://www.windowbuilderpro.com/
http://www.instantiations.com/swt-designer...ts/designer.gif
11、Jigloo.GUI.Builder.v3.0.0
Jigloo.GUI.Builder是一个ؓEclipsejave和WebSphereStudio开发的插gQ能够创建出滚动控制和SWTGUI的效果界面?/P>
Vi.plugin.for.Eclipse3.v1.86
ViPlugin可以在vi~辑器上d一个功能条Q这个是用于Eclipse3+的?/P>
12、Parasoft.JTest.v5.1.71.DC.20040912.WinNT2kXP
自动q行JAVA单元试和代码标准检查来帮助开发h员编写克L代码的工兗可分析c,然后生成单元试案例来包括最大的覆盖试Q发现未处理的异常ƈ校验需求?BR>-自动的基本错误预Ԍ包括单元试和自动代码标准检?BR>-生成q执行单元测试案?BR>-提供了进行黑盒测试、模型测试和pȝ试的快速简单的途径
-识别q防未处理的运行时异常Q函数错误,内存泄露Q性能问题和安全弱?BR>-对群或方案优先作试和报?BR>-监控试的覆盖范?BR>-自动回归试
-支持按比例压~设?BR>-查超q?00个来自JAVA专家的编码规?BR>-Ҏ(gu)q反过200个编码规范的错误
-允许用户创徏自己的编码规?BR>-可在组范围内管理共享测试文?BR>-和IBMWebSphere和Eclipse集成
-支持BorlandQJBuilderQ?TogetherQControlCenterQ?和Ant
13、Borland.Together.for.Eclipse.v6.3
最佳的E序分析设计工具Q提供实时的协同工作能力?BR>·支持所有主要的UML囑Ş
充分利用UnifiedModelingLanguage(l一建模语言—UML)搭徏正确的架构,以便满你的业务目标。每一个Y仉目都需要一个蓝图,以保持整个小l向相同的方向前qƈ构徏正确的Y件。通过集成UML能力的方式,Together扩展了开发框Ӟ化了构徏软g的复杂过E?BR>·TogetherLiveSource自动q行模型与代码的同步
使用同步的模型与代码Q允许进行更加有效的开发小l沟通与协作。同时的同步化让手工更新成ؓq去Q用相同的信息保持开发小l的信息更新。模型处于灵zȝ状态,不会q时Q这是因为开发小l做出的M变化L同时反映在代码与模型之中Q让开发小l更加高效、更加有效?BR>·自动文档生成
保持开发小l专注于设计与实玎ͼ而不是拟制文档。Together提供了强大的、可以定制的文档生成能力Q其中包括多U文档格式与定制模板的能力。通过自动生成文档的方式,开发者可以集中精力搞软g开发,而小l领导随旉有所需要的信息?BR>·支持业界标准的模?BR>使用业界领先的模式着手开发工作,改善了架构的质量。Together支持标准的模式,比如GoF与J2EEQƈ且同时也提供了更改现有模式、创建新模式的能力。广泛的模式支持使得开发小l在来的项目中复用模式Q改善所有项目的架构质量?BR>·使用审计定软g质量
审计为开发小l提供了在Y件开发的初期定质量Q强化企业标准的能力—在软g开发的初期Q开发小l还在编制Y件的代码呢。在分发之前定质量Q开发者可以改善代码的质量Q在代码转交QA组之前Q发现ƈ修复自己的错误。审计变量可以被定制q保存,q样开发小l就能制订代码标准,监视代码出认可规范的问题。审计也被用来改变开发者的个h代码~制风格Q以便符合企业的~码标准?BR>·使用度量q行软g开发的量化
量度为开发小l提供了量软g目复杂E度、质量与规模的能力。通过量q对信息q行标准查,理人员能够知晓开发小l与开发过E的质量与效率,更好地进行当前与未来目的量化?BR>·重构
在Together技术之中的大量重构Ҏ(gu)验证所有的pȝ变化都被正确C送到整个应用。所得到的结果便是代码不易出错,应用的质量得到改善?BR>·Together与Eclipse的集?BR>Eclipse是一U开放源代码的业界^収ͼTogether技术与Eclipse的集成ؓEclipse用户提供了一U熟(zhn)的环境Q用来进行Y件开发。在Eclipse环境中,开发者可以利用TogetherEditionforEclipse之中的、领先的建模、设计与质量保证功能Q快速构建高质量的企业应用。通过在Eclipse本地开发用于TogetherEditionforEclipse的用h口,用户可受益于紧密的集成,q利用在同一个工具之中两U技术的优势?BR>http://www.borland.com/together/index.html
http://0daycheck.eastgame.net/0day/archives/16494_BorlandTogethe.html
14、Clay.Database.Modeling.Pro.for.Eclipse.v1.0.5
作ؓ插gq行于Eclipse开发环境的数据库设计工兗通过直观的界面图形化地设计数据库模型。它可以通过逆向设计来根据现存数据库来设计新的数据库模型。更多地Q它q能生成适合你的数据库的SQL(DDL)代码?BR>http://www.azzurri.jp/en/software/clay/index.jsp
http://www.azzurri.jp/en/software/clay/ima...y_eclipse_1.png
http://0daycheck.eastgame.net/0day/archives/11208_ClayDatabaseM.html
15、Oxygen.XML.Editor.v4.2.Eclipse.plugin
OxygenXMLeditor是一Ƒ֟于Java的XML~辑器,支持XML,XSL,TXT,XSD,DTD文档Q能自行校验XML,XSL,XSD代码Q提C本错误。Oxygen能自动完成结束标{,代码高亮现实Q支持Unicode?BR>http://www.oxygenxml.com/features/
http://www.oxygenxml.com/img/oxygen-mac.gif
http://0daycheck.eastgame.net/0day/archives/10689_OxygenXMLEdit.html
16、MC.Press.Eclipse.Step.by.Step
MCPress出版的《Eclipse循序渐近?Eclipse:StepbyStep)?sh)子版,Eclipse是一个开放源代码的、基于Java的可扩展开发^台。就其本w而言Q它只是一个框架和一l服务,用于通过插glg构徏开发环境。幸q的是,Eclipse附带了一个标准的插g集,包括Java开发工PJavaDevelopmentToolsQJDTQ。该书包括了Eclipseq_开发的Ҏ(gu)面面Q可以手把手帮助你编写完整的可用的程序,q更好的立即各种基本概念
http://www.amazon.com/exec/obidos/tg/detail/-/1583470441/
http://images.amazon.com/images/P/15834704...SCMZZZZZZZ_.jpg
http://0daycheck.eastgame.net/0day/archives/10486_MCPressEclips.html
17、Window.Builder.Pro.v2.0.1
一Ƒ֟于EclipseSWT技术上的双向JavaGui设计软g。具备SWT设计以及Swing设计两个主要功能。该软g会被作ؓ一个插仉嵌入Eclipse以及其他一些兼容的IDEs中(WSSD,WSAD,WSED{等Q。新?.0版本支持Eclipse3.0?BR>http://www.windowbuilderpro.com/
http://www.instantiations.com/swt-designer...ts/designer.gif
http://0daycheck.eastgame.net/0day/archives/10310_WindowBuilder.html
18、XMLBuddy.PRO.v2.0.11
Eclipse插gQ提供XML~辑功能Q支持XML,DTD,XMLSchema,RELAXNG,RELAXNGcompactsyntax,XSLT
http://xmlbuddy.com/
http://xmlbuddy.com/2.0/screen.jpg
http://0daycheck.eastgame.net/0day/archives/9848_XMLBuddyPROv2.html
19、Compuware.DevPartner.Java.Edition.v3.0.3
快速高质量的开发javaE序的开发工LQ增强组件和软g的可靠性。可以针对个人定制不同的览数据H口和调试工兗?BR>新的3.03版本h如下更新Q?BR>-hEclipse插g
-可以在系l,开发环境和应用E序之间交互切换
-q有其他更新{?/P>
20、Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer
?sh)子?Eclipse实践Qjava开发h员指南?BR>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/
http://images.amazon.com/images/P/1930110960.01.<u>PE32_PIdp-schmoo2,TopRight,7,-26_SCMZZZZZZZ</u>.jpg
21、Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer
?sh)子书《jave开发指南?BR>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/
http://images.amazon.com/images/P/19301109...SCMZZZZZZZ_.jpg
22、SignSoft_intelliBO_v3.6.2
一个中间g的应用,不仅仅执行JavaDataObjects标准(JDO)Q现在支持JDO标准1.0.1Q,而且实现的数据访问,所以称作:“intelligentBusinessObjects”。可集成于Eclipse及IBMWebsphereApllicationDeveloperIDE?/P>
23、OReilly.Eclipse.A.Java.Developers.Guide.eBook
《Java开发者指南?/P>
24、IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook
?sh)子书,提供l那些具备良好知识基以及丰富l验的用EclipseSDK来开发插件代码的E序?用以校验插g的工作性能?BR>http://publib-b.boulder.ibm.com/Redbooks.n...s/sg246302.html
25、IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook
书名Q《用Graphical.Editing.Framework和Eclipse.Modeling.Frameworkq行Eclipse开发?BR>作者:BillMooreetal.
出版C:IBMRedbooks
格式QCHM
分类Q计机/软g开?BR>ISBNQ?738453161
内容介:
一本介l用GraphicalEditingFramework(GEF)和EclipseModelingFramework(EMF).q行Eclipseplugin开发的书?/P>
26、Rational.XDE.v2003.Developer.Plus.NET.Edition.Retail
RationalXDEDeveloper是一个十分完善的可视化设计和开发的环境Q它可以l合Rational支持的集成开发环境(IDEQ来使用Q比如Eclipseplatform,IBMWebSphereStudioApplicationDeveloper,MicrosoftVisualStudio.NET{。RationalXDEDeveloper可以在构Z业应用和WebZ心的解决Ҏ(gu)上开发h员提供支持。通过l合使用RationalXDEDeveloper的多U特性(比如Q代码的双向工程Q自动和按需的对代码和模型进行同步,模式引擎支持Q多模型的支持,数据库资逆向工程为数据模型,团队协作Q可选择的过E指南)可以减轻一些被需要的代码开发和设计的工作。这个是VisualStudio.NET版本的License?BR>http://www.rational.com/products/xde/index.jsp
27、Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---1
讲述在Eclipse(一U正在兴L软g开发环?下进行插件开发的?sh)子图?/P>
28、Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---2
出版QAddison-WesleyPubCoQ作者:ErichGamma,KentBeckQISBNQ?321205758?BR>一本关于Eclipse的书。这本书不仅仅教你怎么做而且使你完全理解Eclipse?BR>http://www.amazon.com/exec/obidos/tg/detai...l/-/0321205758/
29、Addison.Wesley.Eclipse.Modeling.Framework.A.Developers.Guide.eBook
?sh)子书,EclipseModelingFramework模型构架可以使Java,XML,和UML语言开发者统一h使用令h惊讶的模板快速构建健L应用E序,是一本Y件开发h员指g
http://www.amazon.com/exec/obidos/ASIN/013...1308053-5737658
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.undo.*;
/**HTML文g文档~辑?/
public class HTMLDocumentEditor extends JFrame implements ActionListener
{
/** 声明一个网|档对象变?/
private HTMLDocument document;
/** 创徏一个文本编辑板*/
private JTextPane textPane = new JTextPane();
private boolean debug = false;
/** 声明一个文件对象变?/
private File currentFile;
/** 侦听在当前文档上的编辑器 */
protected UndoableEditListener undoHandler = new UndoHandler();
/** d撤消理?*/
protected UndoManager undo = new UndoManager();
/** d撤消侦听?/
private UndoAction undoAction = new UndoAction();
/** d恢复侦听?/
private RedoAction redoAction = new RedoAction();
/** d剪切侦听?/
private Action cutAction = new DefaultEditorKit.CutAction();
/** d复制侦听?/
private Action copyAction = new DefaultEditorKit.CopyAction();
/** d_脓(chung)侦听?/
private Action pasteAction = new DefaultEditorKit.PasteAction();
/** d加粗侦听?/
private Action boldAction = new StyledEditorKit.BoldAction();
/** d加下划线侦听?/
private Action underlineAction = new StyledEditorKit.UnderlineAction();
/** d倾斜侦听?/
private Action italicAction = new StyledEditorKit.ItalicAction();
private Action insertBreakAction = new DefaultEditorKit.InsertBreakAction();
private HTMLEditorKit.InsertHTMLTextAction unorderedListAction = new HTMLEditorKit.InsertHTMLTextAction("Bullets", "<ul><li> </li></ul>",HTML.Tag.P,HTML.Tag.UL);
private HTMLEditorKit.InsertHTMLTextAction bulletAction = new HTMLEditorKit.InsertHTMLTextAction("Bullets", "<li> </li>",HTML.Tag.UL,HTML.Tag.LI);
/** 构造方?/
public HTMLDocumentEditor()
{
/** 讄ȝ体标?/
super("HTMLDocumentEditor");
HTMLEditorKit editorKit = new HTMLEditorKit();
/** 创徏默认文档指向|页引用document*/
document = (HTMLDocument)editorKit.createDefaultDocument();
// 强制SWINGSET实现跨^収ͼ不改变风?
try
{
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// 如果你想用系l的界面风格替代Q请注释掉上一行代码,而取消下一行代码的注释Q?
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception exc)
{
//产生异常Q则昄错误消息Q加载L&F错误
System.err.println("Error loading L&F: " + exc);
}
//调用初始化方?BR> init();
}
/**L法,起动E序*/
public static void main(String[] args)
{
//创徏一个类的实例,卛_Z个网늼辑器
HTMLDocumentEditor editor = new HTMLDocumentEditor();
}
/**初始化各lg的方?/
public void init()
{
//调用自定义承WindowListener的侦听器FrameListenerQ给ȝ体添加WindowListener
addWindowListener(new FrameListener());
JMenuBar menuBar = new JMenuBar();
getContentPane().add(menuBar, BorderLayout.NORTH);
JMenu fileMenu = new JMenu("File"); //文g
JMenu editMenu = new JMenu("Edit"); //~辑
JMenu colorMenu = new JMenu("Color"); //颜色
JMenu fontMenu = new JMenu("Font"); //字体
JMenu styleMenu = new JMenu("Style"); //样式
JMenu alignMenu = new JMenu("Align"); //寚w
JMenu helpMenu = new JMenu("Help"); //帮助
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(colorMenu);
menuBar.add(fontMenu);
menuBar.add(styleMenu);
menuBar.add(alignMenu);
menuBar.add(helpMenu);
JMenuItem newItem = new JMenuItem("New", new ImageIcon("whatsnew-bang.gif")); //新徏
JMenuItem openItem = new JMenuItem("Open",new ImageIcon("open.gif")); //打开
JMenuItem saveItem = new JMenuItem("Save",new ImageIcon("save.gif")); //保存
JMenuItem saveAsItem = new JMenuItem("Save As"); //另存
JMenuItem exitItem = new JMenuItem("Exit",new ImageIcon("exit.gif")); //退?BR>
newItem.addActionListener(this);
openItem.addActionListener(this);
saveItem.addActionListener(this);
saveAsItem.addActionListener(this);
exitItem.addActionListener(this);
fileMenu.add(newItem);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(saveAsItem);
fileMenu.add(exitItem);
//l菜单项d侦听?BR> JMenuItem undoItem = new JMenuItem(undoAction); //撤消
JMenuItem redoItem = new JMenuItem(redoAction); //恢复
JMenuItem cutItem = new JMenuItem(cutAction); //剪切
JMenuItem copyItem = new JMenuItem(copyAction); //复制
JMenuItem pasteItem = new JMenuItem(pasteAction); //_脓(chung)
JMenuItem clearItem = new JMenuItem("Clear"); //清除
JMenuItem selectAllItem = new JMenuItem("Select All"); //全?BR> JMenuItem insertBreaKItem = new JMenuItem(insertBreakAction);
JMenuItem unorderedListItem = new JMenuItem(unorderedListAction);
JMenuItem bulletItem = new JMenuItem(bulletAction); //目W号
cutItem.setText("Cut");
copyItem.setText("Copy");
pasteItem.setText("Paste");
insertBreaKItem.setText("Break");
cutItem.setIcon(new ImageIcon("cut.gif"));
copyItem.setIcon(new ImageIcon("copy.gif"));
pasteItem.setIcon(new ImageIcon("paste.gif"));
insertBreaKItem.setIcon(new ImageIcon("break.gif"));
unorderedListItem.setIcon(new ImageIcon("bullets.gif"));
clearItem.addActionListener(this);
selectAllItem.addActionListener(this);
editMenu.add(undoItem);
editMenu.add(redoItem);
editMenu.add(cutItem);
editMenu.add(copyItem);
editMenu.add(pasteItem);
editMenu.add(clearItem);
editMenu.add(selectAllItem);
editMenu.add(insertBreaKItem);
editMenu.add(unorderedListItem);
editMenu.add(bulletItem);
JMenuItem redTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Red",Color.red));
JMenuItem orangeTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Orange",Color.orange));
JMenuItem yellowTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Yellow",Color.yellow));
JMenuItem greenTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Green",Color.green));
JMenuItem blueTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Blue",Color.blue));
JMenuItem cyanTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Cyan",Color.cyan));
JMenuItem magentaTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Magenta",Color.magenta));
JMenuItem blackTextItem = new JMenuItem(new StyledEditorKit.ForegroundAction("Black",Color.black));
redTextItem.setIcon(new ImageIcon("red.gif"));
orangeTextItem.setIcon(new ImageIcon("orange.gif"));
yellowTextItem.setIcon(new ImageIcon("yellow.gif"));
greenTextItem.setIcon(new ImageIcon("green.gif"));
blueTextItem.setIcon(new ImageIcon("blue.gif"));
cyanTextItem.setIcon(new ImageIcon("cyan.gif"));
magentaTextItem.setIcon(new ImageIcon("magenta.gif"));
blackTextItem.setIcon(new ImageIcon("black.gif"));
colorMenu.add(redTextItem);
colorMenu.add(orangeTextItem);
colorMenu.add(yellowTextItem);
colorMenu.add(greenTextItem);
colorMenu.add(blueTextItem);
colorMenu.add(cyanTextItem);
colorMenu.add(magentaTextItem);
colorMenu.add(blackTextItem);
JMenu fontTypeMenu = new JMenu("Font Type");
fontMenu.add(fontTypeMenu);
String[] fontTypes = {"SansSerif", "Serif", "Monospaced", "Dialog", "DialogInput"};
for (int i = 0; i < fontTypes.length;i++)
{
if (debug) System.out.println(fontTypes[i]);
JMenuItem nextTypeItem = new JMenuItem(fontTypes[i]);
nextTypeItem.setAction(new StyledEditorKit.FontFamilyAction(fontTypes[i], fontTypes[i]));
fontTypeMenu.add(nextTypeItem);
}
JMenu fontSizeMenu = new JMenu("Font Size");
fontMenu.add(fontSizeMenu);
int[] fontSizes = {6, 8,10,12,14, 16, 20,24, 32,36,48,72};
for (int i = 0; i < fontSizes.length;i++)
{
if (debug) System.out.println(fontSizes[i]);
JMenuItem nextSizeItem = new JMenuItem(String.valueOf(fontSizes[i]));
nextSizeItem.setAction(new StyledEditorKit.FontSizeAction(String.valueOf(fontSizes[i]), fontSizes[i]));
fontSizeMenu.add(nextSizeItem);
}
JMenuItem boldMenuItem = new JMenuItem(boldAction);
JMenuItem underlineMenuItem = new JMenuItem(underlineAction);
JMenuItem italicMenuItem = new JMenuItem(italicAction);
boldMenuItem.setText("Bold");
underlineMenuItem.setText("Underline");
italicMenuItem.setText("Italic");
boldMenuItem.setIcon(new ImageIcon("bold.gif"));
underlineMenuItem.setIcon(new ImageIcon("underline.gif"));
italicMenuItem.setIcon(new ImageIcon("italic.gif"));
styleMenu.add(boldMenuItem);
styleMenu.add(underlineMenuItem);
styleMenu.add(italicMenuItem);
JMenuItem subscriptMenuItem = new JMenuItem(new SubscriptAction());
JMenuItem superscriptMenuItem = new JMenuItem(new SuperscriptAction());
JMenuItem strikeThroughMenuItem = new JMenuItem(new StrikeThroughAction());
subscriptMenuItem.setText("Subscript");
superscriptMenuItem.setText("Superscript");
strikeThroughMenuItem.setText("StrikeThrough");
subscriptMenuItem.setIcon(new ImageIcon("subscript.gif"));
superscriptMenuItem.setIcon(new ImageIcon("superscript.gif"));
strikeThroughMenuItem.setIcon(new ImageIcon("strikethough.gif"));
styleMenu.add(subscriptMenuItem);
styleMenu.add(superscriptMenuItem);
styleMenu.add(strikeThroughMenuItem);
JMenuItem leftAlignMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction("Left Align",StyleConstants.ALIGN_LEFT));
JMenuItem centerMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction("Center",StyleConstants.ALIGN_CENTER));
JMenuItem rightAlignMenuItem = new JMenuItem(new StyledEditorKit.AlignmentAction ("Right Align",StyleConstants.ALIGN_RIGHT));
leftAlignMenuItem.setText("Left Align");
centerMenuItem.setText("Center");
rightAlignMenuItem.setText("Right Align");
leftAlignMenuItem.setIcon(new ImageIcon("left.gif"));
centerMenuItem.setIcon(new ImageIcon("center.gif"));
rightAlignMenuItem.setIcon(new ImageIcon("right.gif"));
alignMenu.add(leftAlignMenuItem);
alignMenu.add(centerMenuItem);
alignMenu.add(rightAlignMenuItem);
JMenuItem helpItem = new JMenuItem("帮助");
helpItem.addActionListener(this);
helpMenu.add(helpItem);
JMenuItem shortcutsItem = new JMenuItem("Keyboard Shortcuts");
shortcutsItem.addActionListener(this);
helpMenu.add(shortcutsItem);
JMenuItem aboutItem = new JMenuItem("About QuantumHyperSpace");
aboutItem.addActionListener(this);
helpMenu.add(aboutItem);
JPanel editorControlPanel = new JPanel();
//editorControlPanel.setLayout(new GridLayout(3,3));
editorControlPanel.setLayout(new FlowLayout());
/* 按钮 */
JButton cutButton = new JButton(cutAction); //创徏“剪切”按钮,d剪切侦听
JButton copyButton = new JButton(copyAction); //创徏“复制”按钮,d复制?BR> JButton pasteButton = new JButton(pasteAction); //创徏“粘贴”按钮,d_脓(chung)?BR>
JButton boldButton = new JButton(boldAction); //创徏“加_”按钮,d加粗侦听
JButton underlineButton = new JButton(underlineAction); //创徏“下划线”按钮,d下划U侦?BR> JButton italicButton = new JButton(italicAction); //创徏“斜体”按钮,d斜体侦听
//JButton insertButton = new JButton(insertAction);
//JButton insertBreakButton = new JButton(insertBreakAction);
//JButton tabButton = new JButton(tabAction);
cutButton.setText("Cut");
copyButton.setText("Copy");
pasteButton.setText("Paste");
boldButton.setText("Bold");
underlineButton.setText("Underline");
italicButton.setText("Italic");
//insertButton.setText("Insert");
//insertBreakButton.setText("Insert Break");
//tabButton.setText("Tab");
cutButton.setIcon(new ImageIcon("cut.gif"));
copyButton.setIcon(new ImageIcon("copy.gif"));
pasteButton.setIcon(new ImageIcon("paste.gif"));
boldButton.setIcon(new ImageIcon("bold.gif"));
underlineButton.setIcon(new ImageIcon("underline.gif"));
italicButton.setIcon(new ImageIcon("italic.gif"));
editorControlPanel.add(cutButton);
editorControlPanel.add(copyButton);
editorControlPanel.add(pasteButton);
editorControlPanel.add(boldButton);
editorControlPanel.add(underlineButton);
editorControlPanel.add(italicButton);
//editorControlPanel.add(insertButton);
//editorControlPanel.add(insertBreakButton);
//editorControlPanel.add(tabButton);
JButton subscriptButton = new JButton(new SubscriptAction());
JButton superscriptButton = new JButton(new SuperscriptAction());
JButton strikeThroughButton = new JButton(new StrikeThroughAction());
subscriptButton.setIcon(new ImageIcon("subscript.gif"));
superscriptButton.setIcon(new ImageIcon("superscript.gif"));
strikeThroughButton.setIcon(new ImageIcon("strikethough.gif"));
JPanel specialPanel = new JPanel();
specialPanel.setLayout(new FlowLayout());
specialPanel.add(subscriptButton);
specialPanel.add(superscriptButton);
specialPanel.add(strikeThroughButton);
//JButton leftAlignButton = new JButton(new AlignLeftAction());
//JButton centerButton = new JButton(new CenterAction());
//JButton rightAlignButton = new JButton(new AlignRightAction());
JButton leftAlignButton = new JButton(new StyledEditorKit.AlignmentAction("Left Align",StyleConstants.ALIGN_LEFT));
JButton centerButton = new JButton(new StyledEditorKit.AlignmentAction("Center",StyleConstants.ALIGN_CENTER));
JButton rightAlignButton = new JButton(new StyledEditorKit.AlignmentAction ("Right Align",StyleConstants.ALIGN_RIGHT));
JButton colorButton = new JButton(new StyledEditorKit.AlignmentAction ("Right Align",StyleConstants.ALIGN_RIGHT));
leftAlignButton.setIcon(new ImageIcon("left.gif"));
centerButton.setIcon(new ImageIcon("center.gif"));
rightAlignButton.setIcon(new ImageIcon("right.gif"));
colorButton.setIcon(new ImageIcon("color.gif"));
leftAlignButton.setText("Left Align");
centerButton.setText("Center");
rightAlignButton.setText("Right Align");
JPanel alignPanel = new JPanel();
alignPanel.setLayout(new FlowLayout());
alignPanel.add(leftAlignButton);
alignPanel.add(centerButton);
alignPanel.add(rightAlignButton);
document.addUndoableEditListener(undoHandler);
resetUndoManager();
textPane = new JTextPane(document);
textPane.setContentType("text/html");
JScrollPane scrollPane = new JScrollPane(textPane);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension scrollPaneSize = new Dimension(5*screenSize.width/8,5*screenSize.height/8);
scrollPane.setPreferredSize(scrollPaneSize);
//创徏工具栏面板,q设|面板布局理器,d子面?BR> JPanel toolPanel = new JPanel();
toolPanel.setLayout(new BorderLayout());
toolPanel.add(editorControlPanel, BorderLayout.NORTH);
toolPanel.add(specialPanel, BorderLayout.CENTER);
toolPanel.add(alignPanel, BorderLayout.SOUTH);
//向主H体d菜单?BR> getContentPane().add(menuBar, BorderLayout.NORTH);
//向主H体d工具?BR> getContentPane().add(toolPanel, BorderLayout.CENTER);
//向主H体d滚动面板
getContentPane().add(scrollPane, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
startNewDocument();
show();
}
public void actionPerformed(ActionEvent ae)
{
String actionCommand = ae.getActionCommand();
if (debug)
{
int modifier = ae.getModifiers();
long when = ae.getWhen();
String parameter = ae.paramString();
System.out.println("actionCommand: " + actionCommand);
System.out.println("modifier: " + modifier);
System.out.println("when: " + when);
System.out.println("parameter: " + parameter);
}
if (actionCommand.compareTo("New") == 0)
{
startNewDocument();
}
else if (actionCommand.compareTo("Open") == 0)
{
openDocument();
}
else if (actionCommand.compareTo("Save") == 0)
{
saveDocument();
}
else if (actionCommand.compareTo("Save As") == 0)
{
saveDocumentAs();
}
else if (actionCommand.compareTo("Exit") == 0)
{
exit();
}
else if (actionCommand.compareTo("Clear") == 0)
{
clear();
}
else if (actionCommand.compareTo("Select All") == 0)
{
selectAll();
}
else if (actionCommand.compareTo("帮助") == 0)
{
help();
}
else if (actionCommand.compareTo("Keyboard Shortcuts") == 0)
{
showShortcuts();
}
else if (actionCommand.compareTo("About QuantumHyperSpace") == 0)
{
aboutQuantumHyperSpace();
}
}
public void startNewDocument()
{
Document oldDoc = textPane.getDocument();
if(oldDoc != null)
oldDoc.removeUndoableEditListener(undoHandler);
HTMLEditorKit editorKit = new HTMLEditorKit();
document = (HTMLDocument)editorKit.createDefaultDocument();
textPane.setDocument(document);
currentFile = null;
setTitle("HTMLDocumentEditor");
textPane.getDocument().addUndoableEditListener(undoHandler);
resetUndoManager();
}
public void openDocument()
{
try
{
File current = new File(".");
JFileChooser chooser = new JFileChooser(current);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setFileFilter(new HTMLFileFilter());
int approval = chooser.showSaveDialog(this);
if (approval == JFileChooser.APPROVE_OPTION)
{
currentFile = chooser.getSelectedFile();
setTitle(currentFile.getName());
FileReader fr = new FileReader(currentFile);
Document oldDoc = textPane.getDocument();
if(oldDoc != null)
oldDoc.removeUndoableEditListener(undoHandler);
HTMLEditorKit editorKit = new HTMLEditorKit();
document = (HTMLDocument)editorKit.createDefaultDocument();
editorKit.read(fr,document,0);
document.addUndoableEditListener(undoHandler);
textPane.setDocument(document);
resetUndoManager();
}
}
catch(BadLocationException ble)
{
System.err.println("BadLocationException: " + ble.getMessage());
}
catch(FileNotFoundException fnfe)
{
System.err.println("FileNotFoundException: " + fnfe.getMessage());
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
}
}
public void saveDocument()
{
if (currentFile != null)
{
try
{
FileWriter fw = new FileWriter(currentFile);
fw.write(textPane.getText());
fw.close();
}
catch(FileNotFoundException fnfe)
{
System.err.println("FileNotFoundException: " + fnfe.getMessage());
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
}
}
else
{
saveDocumentAs();
}
}
public void saveDocumentAs()
{
try
{
File current = new File(".");
JFileChooser chooser = new JFileChooser(current);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setFileFilter(new HTMLFileFilter());
int approval = chooser.showSaveDialog(this);
if (approval == JFileChooser.APPROVE_OPTION)
{
File newFile = chooser.getSelectedFile();
if (newFile.exists())
{
String message = newFile.getAbsolutePath() + " already exists. \n" + "Do you want to replace it?";
if (JOptionPane.showConfirmDialog(this, message) == JOptionPane.YES_OPTION)
{
currentFile = newFile;
setTitle(currentFile.getName());
FileWriter fw = new FileWriter(currentFile);
fw.write(textPane.getText());
fw.close();
if (debug) System.out.println("Saved " + currentFile.getAbsolutePath());
}
}
else
{
currentFile = new File(newFile.getAbsolutePath());
setTitle(currentFile.getName());
FileWriter fw = new FileWriter(currentFile);
fw.write(textPane.getText());
fw.close();
if (debug) System.out.println("Saved " + currentFile.getAbsolutePath());
}
}
}
catch(FileNotFoundException fnfe)
{
System.err.println("FileNotFoundException: " + fnfe.getMessage());
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
}
}
public void exit()
{
String exitMessage = "Are you sure you want to exit?";
if (JOptionPane.showConfirmDialog(this, exitMessage) == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
/**调用startNewDocument()Ҏ(gu)Q清除当前文本,开始一个新文档*/
public void clear()
{
startNewDocument();
}
/**调用JTextPane的全选方?/
public void selectAll()
{
textPane.selectAll();
}
/**利用消息框显C帮助信?/
public void help()
{
JOptionPane.showMessageDialog(this,"DocumentEditor.java\n" + "Author: Charles Bell\n" + "Version: May 25, 2002\n" +
" }
/**利用消息框显C快捷键*/
public void showShortcuts()
{
String shortcuts = "Navigate in | Tab\n" + "Navigate out | Ctrl+Tab\n" + "Navigate out backwards | Shift+Ctrl+Tab\n" +
"Move up/down a line | Up/Down Arrown\n" + "Move left/right a component or char | Left/Right Arrow\n" +
"Move up/down one vertical block | PgUp/PgDn\n" + "Move to start/end of line | Home/End\n" +
"Move to previous/next word | Ctrl+Left/Right Arrow\n" + "Move to start/end of data | Ctrl+Home/End\n" +
"Move left/right one block | Ctrl+PgUp/PgDn\n" + "Select All | Ctrl+A\n" +
"Extend selection up one line | Shift+Up Arrow\n" + "Extend selection down one line | Shift+Down Arrow\n" +
"Extend selection to beginning of line | Shift+Home\n" + "Extend selection to end of line | Shift+End\n" +
"Extend selection to beginning of data | Ctrl+Shift+Home\n" + "Extend selection to end of data | Ctrl+Shift+End\n" +
"Extend selection left | Shift+Right Arrow\n" + "Extend selection right | Shift+Right Arrow\n" +
"Extend selection up one vertical block | Shift+PgUp\n" + "Extend selection down one vertical block | Shift+PgDn\n" +
"Extend selection left one block | Ctrl+Shift+PgUp\n" + "Extend selection right one block | Ctrl+Shift+PgDn\n" +
"Extend selection left one word | Ctrl+Shift+Left Arrow\n" + "Extend selection right one word | Ctrl+Shift+Right Arrow\n";
JOptionPane.showMessageDialog(this,shortcuts);
}
public void aboutQuantumHyperSpace()
{
JOptionPane.showMessageDialog(this,"QuantumHyperSpace Programming Services\n" + " "email: support@quantumhyperspace.com\n" + " or \n" + "email: charles@quantumhyperspace.com\n",
"QuantumHyperSpace",JOptionPane.INFORMATION_MESSAGE, new ImageIcon("quantumhyperspace.gif"));
}
/**内部c:自定义承WindowListener的侦听器FrameListener*/
class FrameListener extends WindowAdapter
{
/**处理点击H体关闭按钮事gQ实现程序的关闭停止*/
public void windowClosing(WindowEvent we)
{
exit();
}
}
class SubscriptAction extends StyledEditorKit.StyledTextAction
{
public SubscriptAction()
{
super(StyleConstants.Subscript.toString());
}
public void actionPerformed(ActionEvent ae)
{
JEditorPane editor = getEditor(ae);
if (editor != null)
{
StyledEditorKit kit = getStyledEditorKit(editor);
MutableAttributeSet attr = kit.getInputAttributes();
boolean subscript = (StyleConstants.isSubscript(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setSubscript(sas, subscript);
setCharacterAttributes(editor, sas, false);
}
}
}
class SuperscriptAction extends StyledEditorKit.StyledTextAction
{
public SuperscriptAction()
{
super(StyleConstants.Superscript.toString());
}
public void actionPerformed(ActionEvent ae)
{
JEditorPane editor = getEditor(ae);
if (editor != null)
{
StyledEditorKit kit = getStyledEditorKit(editor);
MutableAttributeSet attr = kit.getInputAttributes();
boolean superscript = (StyleConstants.isSuperscript(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setSuperscript(sas, superscript);
setCharacterAttributes(editor, sas, false);
}
}
}
class StrikeThroughAction extends StyledEditorKit.StyledTextAction
{
public StrikeThroughAction()
{
super(StyleConstants.StrikeThrough.toString());
}
public void actionPerformed(ActionEvent ae)
{
JEditorPane editor = getEditor(ae);
if (editor != null)
{
StyledEditorKit kit = getStyledEditorKit(editor);
MutableAttributeSet attr = kit.getInputAttributes();
boolean strikeThrough = (StyleConstants.isStrikeThrough(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setStrikeThrough(sas, strikeThrough);
setCharacterAttributes(editor, sas, false);
}
}
}
class HTMLFileFilter extends javax.swing.filechooser.FileFilter
{
public boolean accept(File f)
{
return ((f.isDirectory()) ||(f.getName().toLowerCase().indexOf(".htm") > 0));
}
public String getDescription()
{
return "html";
}
}
protected void resetUndoManager()
{
undo.discardAllEdits();
undoAction.update();
redoAction.update();
}
class UndoHandler implements UndoableEditListener
{
/**
* Messaged when the Document has created an edit, the edit is
* added to <code>undo</code>, an instance of UndoManager.
*/
public void undoableEditHappened(UndoableEditEvent e)
{
undo.addEdit(e.getEdit());
undoAction.update();
redoAction.update();
}
}
class UndoAction extends AbstractAction
{
public UndoAction()
{
super("Undo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e)
{
try
{
undo.undo();
}
catch (CannotUndoException ex)
{
System.out.println("Unable to undo: " + ex);
ex.printStackTrace();
}
update();
redoAction.update();
}
protected void update()
{
if(undo.canUndo())
{
setEnabled(true);
putValue(Action.NAME, undo.getUndoPresentationName());
}
else
{
setEnabled(false);
putValue(Action.NAME, "Undo");
}
}
}
class RedoAction extends AbstractAction
{
public RedoAction()
{
super("Redo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e)
{
try
{
undo.redo();
}
catch (CannotRedoException ex)
{
System.err.println("Unable to redo: " + ex);
ex.printStackTrace();
}
update();
undoAction.update();
}
protected void update()
{
if(undo.canRedo())
{
setEnabled(true);
putValue(Action.NAME, undo.getRedoPresentationName());
}
else
{
setEnabled(false);
putValue(Action.NAME, "Redo");
}
}
}
}
|
|
|
|
|
|
4.BEA JRockit JVM的?
Bea WebLogic 8.1使用的新的JVM用于Intelq_。在Bea安装完毕的目录下可以看到有一个类gjrockit81sp1_141_03的文件夹。这是Bea新JVM所在目录。不同于HotSpot把Java字节码编译成本地码,它预先编译成cR?
JRockitq提供了更细致的功能用以观察JVM的运行状态,主要是独立的GUI控制収ͼ只能适用于用Jrockit才能使用jrockit81sp1_141_03自带的console监控一些cpu及memory参数Q或者WebLogic Server控制台?
Bea JRockit JVM支持4U垃圾收集器Q?
4.1.1.分代复制攉?
它与默认的分代收集器工作{略cM。对象在新域中分配,即JRockit文档中的nursery。这U收集器最适合单cpuZ型堆操作?
4.1.2.单空间ƈ发收集器
该收集器使用完整堆,q与背景U程共同工作。尽这U收集器可以消除中断Q但是收集器需p较长的时间寻找死对象Q而且处理应用E序时收集器l常q行。如果处理器不能应付应用E序产生的垃圾,它会中断应用E序q关闭收集?
分代q发攉?q种攉器在护理域用排它复制收集器Q在旧域中则使用q发攉器。由于它比单I间共同发生攉器中断频J,因此它需要较?yu)的内存Q应用程序的q行效率也较高,注意Q过的护理域可以导致大量的临时对象被扩展到旧域中。这会造成攉器超负荷q作Q甚至采用排它性工作方式完成收集?
4.1.3.q行攉?
该收集器也停止其他进E的工作Q但使用多线E以加速收集进E。尽它比其他的攉器易于引起长旉的中断,但一般能更好的利用内存,E序效率也较高?
默认状态下QJRockit使用分代q发攉器。要改变攉器,可用:
|
对应四个攉器分别ؓgencopyQsingleconQgencon以及parallel。可使用-Xms?Xmx讄堆的初始大小和最大倹{要讄护理域,则用:
|
管JRockit支持-verbose:gc开养I但它输出的信息会因收集器的不同而异。JRockitq支持memory、load和codegen的输出?
注意 Q如?使用JRockit JVM的话q可以用WLS自带的consoleQC:\bea\jrockit81sp1_141_03\bin下)来监控一些数据,如cpuQmemery{。要惌构监控必d启动服务时startWeblogic.cmd中加入-Xmanagement参数?
5.如何从JVM中获取信息来q行调整
-verbose.gc开兛_昄gc的操作内宏V打开它,可以昄最忙和最I闲攉行ؓ发生的时间、收集前后的内存大小、收集需要的旉{。打开-xx:+ printgcdetails开养I可以详细了解gc中的变化?
打开-XX: + PrintGCTimeStamps开养I可以了解q些垃圾攉发生的时_自JVM启动以后以秒计量。最后,通过-xx: + PrintHeapAtGC开关了解堆的更详细的信息?
Z了解新域的情况,可以通过-XX:=PrintTenuringDistribution开关了解获得用期的对象权?
6.PdmpȝJVM调整
6.1.服务器:前提内存1G 单CPU
可通过如下参数q行调整Q-server 启用服务器模式(如果CPU多,服务器机使用此项Q?
QXms,QXmx一般设为同样大?800m
QXmn 是将NewSize与MaxNewSize设ؓ一致?20m
QXX:PerSize 64m
QXX:NewSize 320m
此D大可调大新对象区Q减Full GCơ数
QXX:MaxNewSize 320m
QXX:NewRato NewSize
设了可不设?
QXX: SurvivorRatio
QXX:userParNewGC
可用来设|ƈ行收?
QXX:ParallelGCThreads
可用来增加ƈ行度
QXXUseParallelGC
讄后可以用ƈ行清除收集器
QXXQUseAdaptiveSizePolicy
与上面一个联合用效果更好,利用它可以自动优化新域大以及救助空间比?
6.2.客户机:通过在JNLP文g中设|参数来调整客户端JVM
JNLP中参敎ͼinitial-heap-size和max-heap-size
q可以在framework的RequestManager中生成JNLP文g时加入上q参敎ͼ但是q些值是要求Ҏ(gu)客户机的g状态变化的Q如客户机的内存大小{)。徏议这两个参数D为客h可用内存?0Q(有待试Q?
Z在动态生成JNLP时以上两个参数D够随客户Z同而不同,可靠虑获得客hpȝ信息q将q些嵌到首页index.jsp中作接请求的参数?
在设|了上述参数后可以通过Visualgc 来观察垃圑֛收的一些参数状态,再做相应的调整来改善性能。一般的标准是减fullgc的次敎ͼ最好硬件支持用ƈ行垃圑֛Ӟ要求多CPUQ?
(转蝲自赛q网开发者论?
Copyright (C) 2001 by Eric S. Raymond
中文版Copyleft 2001 by D.H.Grand(nOBODY/Ginux)
英文版: http://www.tuxedo.org/~esr/faqs/smart-questions.html
中文版原版位|: http://www.linuxforum.net/doc/smartq-grand.html
==
==
在黑客世界里Q当提出一个技术问题时Q你能得到怎样的回{?q取决于挖出{案的难度,同样取决于你提问的方法。本指南旨在帮助你提高发问技巧,以获取你最惌的答案?
首先你必L白,黑客们只偏爱艰巨的Q务,或者能Ȁ发他们思维的好问题。如若不Ӟ我们q来q吗Q如果你有值得我们反复咀嚼玩味的好问题,我们自会对你感激不尽。好问题是激励,是厚C|可以提高我们的理解力Q而且通常会暴露我们以前从没意识到或者思考过的问题。对黑客而言Q“问得好Q”是发自内心的大力称赞?
管黑客们有蔑视单问题和不友善的坏名壎ͼ有时看v来似乎我们对新手Q对知识贫乏者怀有敌意,但其实不是那L?
我们不想掩饰对这样一些h的蔑?-他们不愿思考,或者在发问前不d成他们应该做的事。这Uh只会谋杀旉--他们只愿索取Q从不付出,无端消耗我们的旉Q而我们本可以把时间用在更有趣的问题或者更值得回答的hw上。我们称q样的h为“失败者”(׃历史原因Q我们有时把它拼作“lusers”)?
我们也知道,很多人只想用我们编写的软gQ对技术细节没什么兴。对多数Z而言Q计机不过是一个工P一U达到目的的手段Q他们有更重要的事情要做Q有更重要的生活要过。我们明白这点,也ƈ不奢望每个h都对另我们痴狂的技术问题有兴致。然而,我们回答问题的风格是针对q样一h--他们有兴,q且愿意U极参与问题的解冟뀂这点不会改变,也不应该改变Q如果变了,我们失L们引以ؓ傲的效率?
我们在很大程度上属于志愿者,从繁忙的生活中抽出时间来解惑{疑Q而且时常被提问没。所以我们无情的滤掉一些话题,特别是抛弃那些看h象失败者的家伙Q以便更高效的利用时间来回答胜利者的问题?
如果你觉得我们过于傲慢的态度让你不爽Q让你委屈,不妨设n处地x。我们ƈ没有要求你向我们屈服--事实上,我们中的大多Ch最喜欢公^交易不过了,只要你付出小努力来满最L的要求,我们׃Ƣ迎你加入到我们的文化中来。但让我们帮助那些不愿意帮助自己的h是没有意义的。如果你不能接受q种“歧视”,我们你花炚w扑֮商业公司{个技术支持协议得了,别向黑客乞求帮助?
如果你决定向我们求助Q当然不希望被视为失败者,更不愿成为失败者中的一员。立d到有效答案的最好方法,是象胜利者那h?-聪明、自信、有解决问题的思\Q只是偶在特定的问题上需要获得一点帮助?
Q欢q对本指南提出改q意见。Q何徏议请E-mail至esr@thyrsus.comQ然而请注意Q本文ƈ非网l礼节的通用指南Q我通常会拒l无助于在技术论坛得到有用答案的。)
Q当Ӟ如果你写中文Q最好还是寄到DHGrand@hotmail.com;-Q?
====
====
在通过?sh)邮、新ȝ或者聊天室提出技术问题前Q检查你有没有做刎ͼ
当你提出问题的时候,首先要说明在此之前你q了些什么;q将有助于树立你的Ş象:你不是一个妄图不劌获的乞讨者,不愿费别h的时间。能说明你从q些操作中学C什么就更好了。如果提问者能从答案中学到东西Q我们更乐于回答他的问题?
周全的思考,准备好你的问题,草率的发问只能得到草率的回答Q或者根本得不到M{案。越表现出在L帮助前ؓ解决问题付出的努力,你越能得到实质性的帮助?
心别问错了问题。如果你的问题基于错误的假设Q普通黑客(J. Random HackerQ通常会用无意义的字面解释来答复你Q心里想着“蠢问题...”,希望着你会从问题的回答Q而非你想得到的答案)中݅取教训?
决不要自以ؓ够资格得到答案,你没q种资格。毕竟你没有U服务支付Q何报酬。你要自己去“挣”回一个答案,靠提Z个有内涵的,有趣的,有思维Ȁ׃用的问题--一个对C的经验有潜在贡献的问题,而不仅仅是被动的从他人处索要知识--L到这个答案?
另一斚wQ表明你愿意在找{案的过E中做点什么,是一个非常好的开端。“谁能给Ҏ(gu)C?”、“我q个例子里缺了什么?”以及“我应该查什么地方?”比“请把确切的q程贴出来”更Ҏ(gu)得到{复。因Z昑־只要有h指点正确的方向,你就有完成它的能力和军_?
====
====
心选择提问的场合。如果象下面描述的那P你很可能被忽略掉或者被看作p|者:
黑客们通常砍掉问错地方的问题,以保护自qC不被大量无关帖子Ҏ(gu)。你不会希望自己的帖子被q样砍掉吧?
ȝ说来Q问题发到精心挑选的公众论坛Q比发到闭的小圈子更容易得到有用的{案。这一现象有多U原因,其中之一是公众论坛有更多潜在的问题回{者;另一个原因是公众论坛有更多的听众。黑客们更愿意让量多的?-而非有限的一两个--从回{中受益?
如果某项目有自己的开发邮件列表,要把问题发到q个邮g列表而不是某个开发者,即你很清楚谁最能回{你的问题。仔l查看项目文档和目主页Q找到这个项目的邮g列表地址Q这样做的理由有四:
如果你找不到目的邮件列表地址Q只能看到项目维护者的Q那写l维护者吧。在q种情况下,也别以ؓ邮g列表q不存在。在你的信中写明你已力LQ仍无法扑ֈ邮g列表。另外表明你不介意将此消息{l他人。(大多Ch认ؓU信应该是U下的,即q没有什么可保密的内宏V允怽的消息被转寄l他人,l了收信者一U处理你邮g的选择。)
我们从经验中发现Q粗心的写作者通常也是马虎的思考者(我敢打包)。回{粗心大意者的问题很不值得Q我们宁愿把旉耗在别处?
因此Q明充分表qC的问题非帔R要。如果你嫌这样做ȝQ我们也会懒得搭理你。注意推敲你的用辞,不一定要用呆板正式的语言--事实上,黑客文化的h(hun)D是不拘小节。准的q用俚语和富有幽默感的语aQ但别ؕ用;一定要能表明你在思考,在关注?
正确的拼写,标点W号和大写很重要。别把“its”和“it's”或者“loose”和“lose”搞h了。别用全部大写的形式Q这被视为粗鲁的大声叫嚷Q全都用写也好不到哪儿去,因ؓq会l阅d来困难。Alan Cox可以用全部小写,但你不行Q?
更一般的_如果你的提问写得象个半文Ԍ你很有可能被忽视。如果写得象一个窥客(破解爱好者)或者灰客(只会用现成工L捣ؕ者)l对是自己找死,保证你除了无情的抵制什么也得不刎ͼ或者,最好的l局是得C大堆挖苦嘲笑的“帮助”)?
如果你在使用非母语的论坛提问Q你可以犯点拼写和语法上的小?-但决不能在思考上马虎Q没错,我们能弄清两者的分别Q。另外,除非你确切知道你的回{者会使用什么语aQ否则请用英文。匆匆忙忙的黑客往往单的跌他们看不懂的问题Q而英文是|络上的工作语言。用英文可以降低你的问题未被阅读即遭抛弃的风险?
如果Zؓ造成你的提问难以阅读和理解,会更容易被人忽略。因此你要:
在邮件列表或者新ȝ中,大约50字以内的主题标题是抓住资׃家注意力的黄金时机。别用喋喋不休的“帮帮忙”(更别说“救命啊Q!Q!Q”这栯人反感的话)来浪费这个机会。不要妄想用你的痛苦E度来打动我们,别用I格代替问题的描qͼ哪怕是极其短的描述?
蠢问题:
救命啊!我的膝上Z能正常显CZQ?
聪明问题Q?
XFree86 4.1下鼠标光标变形,Fooware MV1005的显C片?
如果你在回复中提出问题,记得要修改内Ҏ(gu)题,表明里面有一个问题。一个看h象“ReQ测试”或者“ReQ新bug”的问题很难引v_重视。另外,引用q删减前文的内容Q给新来的读者留下线索?
量惌一个黑客会怎样反问你,在提问的时候预先给他答案?
Simon Tatham写过一名为《如何有效的报告Bug》的短文。强力推荐你也读一诅R?
你需要提供精有效的信息。这q不是要求你单的把成吨的出错代码或者数据完全{储摘录到你的提问中。如果你有庞大而复杂的试条gQ尽量把它剪裁得小好?
q样做的用处臛_有三炏V?
告诉黑客们你认ؓ问题是怎样引v的没什么帮助。(如果你的推断如此有效Q还用向别h求助吗?Q,因此要确信你原原本本告诉了他们问题的症状Q不要加q你自己的理解和推论。让黑客们来诊断吧?
蠢问题:
我在内核~译中一ơ又一ơ遇到SIG11错误Q我怀疑某条飞U搭在主板的走线上了Q这U情况应该怎样查最好?
聪明问题Q?
我自制的一套K6/233pȝQ主板是FIC-PA2007 QVIA Apollo VP2芯片l)Q?56MBCorsair PC133 SDRAMQ在内核~译中频频生SIG11错误Q从开?0分钟以后有q种情况Q开机前20分钟内从没发生过。重启也没有用,但是x一晚上又能工?0分钟。所有内存都换过了,没有效果。相关部分的典型~译记录如下...?
Ҏ(gu)出问题最有帮助的U烦Q往往是问题发生前的一pd操作Q因此,你的说明应该包含操作步骤Q以及电(sh)脑的反应Q直到问题生。在命o行操作的情况下,保存一个操作记录(例如使用脚本工具Q,q且引用相关的大U?0条命令会大有帮助?
如果崩溃的程序有诊断选项Q例如用 -v 转到详尽模式Q,试着仔细考虑选择选项以在操作记录中增加有用的调试信息?
如果你的说明很长Q超q四个段落)Q在开头简q问题会有所帮助Q接下来按时间顺序详q。这样黑客们q道该在你的说明中找什么?
黑客们认决问题应该有公开、透明的流E。只要Q何更有见地的人注意到{案的不完善或者不正确Q这个最初的{案可以和应该得到U正。同Ӟ通过能力和知识被大家注意Q被大家接受Q回{问题者得C应有的奖励?
如果你要求对方私下回{你Q这既破坏了整个程Q也破坏了奖励制度。别提这要求Q这是回{者的权利Q由他来选择是否U下{复--如果他选择q样做,通常是因Z认ؓq个{案q于显而易见或者有不良的公开影响Q别Z会感兴趣?
只有一U有限的例外Q如果你预计收到大量雷同的{复Q你可以_“把{案寄给我,由我来汇d。”将邮g列表或者新ȝ从大量重复的帖子中打救出来是很有君子之风?-但请CQ行自己关于汇ȝ承诺?
漫无辚w的提问近乎无休无止的旉黑洞。最能给你有用答案的Z正是最忙的人(他们忙是因ؓ要亲自完成大部分工作Q。这L人对无节制的旉黑洞不太感冒Q因此也可以说他们对漫无辚w的提问不大感冒?
如果你明表q需要回{者做什么(提供Q发送一D代码,查你的补丁或是别的)Q就最有可能得到有用的{案。这会定Z个时间和_֊的上限,便于回答者集中精力来帮你Q这很凑效?
要理解专家们生活的世界,要把专业技能想象ؓ充裕的资源,而回复的旉则是贫乏的资源。解决你的问题需要的旉少Q越能从忙碌的专家口中掏出答案?
因此Q优化问题的l构Q尽量减专家们解决它所需要的旉Q会有很大的帮助--q通常和简化问题有所区别。因此,问“我x好的理解XQ能l点提示吗?”通常比问“你能解释一下X吗?”更好。如果你的代码不能工作,问问它有什么地方不对,比要求别人替你修改要明智得多?
黑客们L善于分L哪些问题应该׃自己解决Q因为我们中的大多数都曾自己解决q类问题。同Pq些问题得由你来搞定Q你会从中学Cѝ你可以要求l点提示Q但别要求得到完整的解决Ҏ(gu)?
别用无意义的话结束提问,例如“有帮我吗?”或者“有{案吗?”?
彬{有礼Q多用“请”和“先道个谢了”。让大家都知道你对他们花Ҏ(gu)间义务提供帮助心存感Ȁ?
实话实说Q虽然这不象合乎语法、清楚准的描述Q避免私有格式等{那么重要(也不能用来替代它们)Q黑客一般更喜欢直接了当然而技术上敏锐的bug报告Q而不是{彬有C的废话Q如果这让你qh不解Q请CQ我们衡量一个问题h(hun)值的标准是:它能让我们学会多)?
然而,如果你有很多问题无法解决Q礼貌将会增加你得到有用{案的机会?
Q我们注意到Q自从本指南发布后,从资深黑客处得到的唯一严重~陷反馈Q就是对预先道谢q一条。一些黑客觉得“先谢了”的a外之意是q后׃会再感谢MZ。我们的是:都道谢。)
问题解决后,向所有帮助过你的人发个说明,让他们知道问题是怎样解决的,q再一ơ向他们表示感谢。如果问题在新闻l或者邮件列表中引v了广泛关注,应该在那里脓(chung)一个补充说明?
补充说明不必很长或是很深入;单的一句“你好,原来是网U出了问题!谢谢大家--Bill”比什么也不说要强。事实上Q除非结论真的很有技术含量,否则短可q结比长学术论文更好。说明问题是怎样解决的,但大可不必将解决问题的过E复qC遍?
除了表示CD和反馈信息以外,q种补充有助于他人在邮g列表/新闻l?论坛中搜索对你有q帮助的完整解决Ҏ(gu)Q这可能对他们也很有用?
最后(臛_Q)Q这U补充有助于所有提供过帮助的h从中得到满感。如果你自己不是老手或者黑客,那就怿我们Q这U感觉对于那些你向他们求助的导师或者专家而言Q是非常重要的。问题久拖未决会让h灰心Q黑客们渴望看到问题被解冟뀂好人有好报Q满他们的渴望Q你会在下次贴出新问题时到甜头?
========
========
有一个古老而神圣的传统Q如果你收到“RTFM QRead The Fucking ManualQ”的回复Q回{者认Z应该去读TMD手册。当Ӟ基本上他是对的,你应该读一诅R?
RTFM有一个年ȝ亲戚。如果答案是“STFW QSearch The Fucking WebQ”,回答者认Z应该到TMD的网上去搜烦。基本上Q他也是对的Q你去扑?
通常Q用q两句之一回答你的Zl你一份包含你需要内容的手册或者一个网址Q而且他们打这些字的时候正在阅ȝ。这些答复意味着回答者认?
别ؓq个而不爽;依照黑客的标准,他没有对你的要求视而不见,已经能大致能表示对你的关注。你应该对他母般的慈祥表示感谢?
如果你不是很理解{案Q别立刻要求Ҏ(gu)解释。象你以前试着自己解决问题旉P利用手册QFAQQ网l,w边的高手)Q去理解它。如果你真的需要对方解释,记得表现Z已经学到了点什么?
比方_如果我回{你Q“看来似乎是zEntry被阻塞了Q你应该先清除它。”,然后Q?
一个很p的后箋问题Q“zEntry是什么??
聪明的问法应该是q样Q“哦~我看q帮助了:)但是只有-z?p两个参数中提CzEntry:(而且q都没有清楚的解?<你是指这两个中的哪一个吗Q还是我看漏了什么??
黑客圈子里很多貌似粗鲁的a行ƈ非有意冒犯。更恰当的说Q这是直率、不说废话的沟通方式的产物Q这U沟通方式源于h们关注问题的解决--多过让h感受温暖亲情然而却依旧p里p涂--的天性?
如果你觉得受到粗鲁的对待Q请保持冷静。如果真有h表现_野Q通常会有列表/新闻l?论坛的长辈找他谈心,如果没有q样Q而你又大发脾气,则很可能Ҏ(gu)的言行是黑客C行ؓ规范许可内,而你被认为是有过错的。这会不利于你得C息或者帮助?
另一斚wQ你偶尔也会无缘无故有粗野的a行和心态。上q现象的另一面是Qh们允许狠狠打ȝ正的冒犯者,用尖ȝa语剖析他们的不当a行。如果你真决定这样做Q先仔细又仔l的掂量一下你自己的分量。合理的_鲁与发动一场无意义的论战之间只隔了一条细l的U,冒冒失失撞上ȝ黑客不在数Q如果你是新手或者门外汉Q不犯这U错的机会是很ؓ茫的。如果你惛_C息而不是来胡闹Q别冒险回复Q最好把手从键盘上拿开?
Q有些h声称多数黑客有孤?ni)或者社交障综合征的轻度症Ӟ而且实~少部分有助“常人”进行社交行为的脑组l结构。这也许是真的,也许不是。如果你自己不是黑客Q那么,把我们想象成脑部有缺L人有助你面对我们的古怪。有话直_我们无所谓;我们乐于按自qx生活Q而且L对医学概忉|相当怀疑的态度。)
在下一节里Q我们将谈论另一个话题;当你行差t错时可能遇到的“无C”?
============
============
很有可能Q你在黑客社区的论坛会受到很多公开的攻?-用本文提到的各种方式或类似的Ҏ(gu)Q而且很可能会有各式各L旁敲侧击来告诉你你有多讨厌?
如果噩梦成真Q你能做的最p的事就是ؓ此发牢骚Q抱怨受Chw攻击,要求Ҏ(gu)道歉Q尖叫,屏住呼吸Q威胁要控诉Ҏ(gu)Q向他老板告状Q不掀起马桶圈,{等{等。然而,你应该这P
由它dQ这没什么大不了的。实际上q么做是恰当的和有益的(主要是有利n心健?Q?
C的规范不靠社区,而是靠积极推行它们的Z来维护,q种l护是公开的,显而易见的。别抱怨说一切批评都应该通过U信传送,它本来就不该那样。当别h指出你的话有错误Q或者他有不同观点的时候,坚持认ؓ他在i你是没有用的。这些都是失败者的态度?
有那么一些黑客论坛,Z寚w度自谦的误解Q禁止参与者张贴专lh找茬的帖子,而且被告知“如果不愿帮助用P那就闭嘴。”,他们认ؓQ引开参与者的话题Q只会得他们陶醉在毫无意义的喋喋不休中Q从而失M技术论坛的意义?
夸张的“友善”(以那U方式)q是有用的帮助:你自己选择吧?
CQ当黑客说你很烦人,Q无论用多么_暴的语aQ警告你别再那样做了Q他的本意ƈ非是针对(1)你,以及(2)他的C。他本来可以L的忽略你Q把你从他的视线中抹厅R如果你无法接受要向他表C感ȀQ至应该表现出你的气度Q别抱怨,别期望只因ؓ你是ChQ你有戏剧般的敏感脆q经和自的权利Q而受到易玩偶般的特别对待?
======
======
以下是几个经典蠢问题Q以及黑客在拒绝回答时的心中所惻I
问题Q我能在哪找到XE序Q?
问题Q我的程?配置/SQLx没有?
问题Q我的Windows有问题,你能帮我吗?
问题Q我在安装LinuxQ或者XQ时有问题,你能帮我吗?
问题Q我怎么才能破解root帐号/H取OPҎ(gu)/d人的邮g呢?
提问Q我能在哪找到XE序Q?
回答Q就在我扑ֈ它的地方啊蠢?-搜烦引擎的那一头。天呐!q有Z会用Google吗?
提问Q我的程序(配置、SQLxQ没有用
回答Q这不算是问题吧Q我Ҏ(gu)Z的真正问题没兴趣--如果要我问你二十个问题才扑־出来的话--我有更有意思的事要做呢。在看到q类问题的时候,我的反应通常不外如下三种Q?
提问Q我的Windows有问题,你能帮我吗?
回答Q能啊,扔掉萎Y的垃圾,换Linux吧?
提问Q我在安装LinuxQ或者XQ时有问题,你能帮我吗?
回答Q不能,我只有亲自在你的?sh)脑上动手才能找到毛病。还是去找你当地的Linux用户l寻求手把手的指导吧Q你能在q儿扑ֈ用户l的清单Q?
提问Q我怎么才能破解root帐号/H取OPҎ(gu)/d人的邮g呢?
回答Q想要这样做Q说明你是个卑鄙hQ想找个黑客帮你Q说明你是个白痴Q?
==========
==========
最后,我D一些例子来说明Q怎样聪明的提问;同一个问题的两种问法被放在一P一U是愚蠢的,另一U才是明智的?
蠢问题:我可以在哪儿扑ֈ关于Foonly Flurbamatic的资料?
q种问法无非惛_到“STFW”这L回答?
聪明问题Q我用Google搜烦q“Foonly Flurbamatic 2600”,但是没找到有用的l果。谁知道上哪儿去扑֯q种讑֤~程的资料?
q个问题已经STFWq了Q看h他真的遇Cȝ?
蠢问题:我从FOO目找来的源码没法编译。它怎么q么烂?
他觉得都是别人的错,q个傲慢自大的家?(
聪明问题QFOO目代码在Nulix 6.2版下无法~译通过。我读过了FAQQ但里面没有提到跟Nulix有关的问题。这是我~译q程的记录,我有什么做得不对的地方吗?
他讲明了环境Q也读过了FAQQ还指明了错误,q且他没有把问题的责L到别人头上,q个家伙值得留意?
蠢问题:我的L有问题了Q谁来帮我?
普通黑客对q类问题的回{通常是:“好的,q要帮你拍拍背和换尿布吗Q?Q然后按下删除键?
聪明问题Q我在S2464L上试q了X、Y和ZQ但没什么作用,我又试了A、B和C。请注意当我试C时的奇怪现象。显然边带传输中出现了收~,但结果出人意料。在多处理器L上引赯带泄漏的通常原因是什么?谁有好主意接下来我该做些什么测试才能找出问题?
q个家伙Q从另一个角度来看,值得d{他。他表现Z解决问题的能力,而不是坐{天上掉{案?
在最后一个问题中Q注意“告诉我{案”和“给我启C,指出我还应该做什么诊断工作”之间微妙而又重要的区别?
事实上,后一个问题源自于2001q?月在Linux内核邮g列表上的一个真实的提问。我QEricQ就是那个提出问题的人。我在Tyan S2464L上观察到了这U无法解释的锁定现象Q列表成员们提供了解决那一问题的重要信息?
通过我的提问Ҏ(gu)Q我l了大家值得玩味的东西;我让Z很容易参与ƈ且被吸引q来。我昄了自己具备和他们同等的能力,邀请他们与我共同探讨。我告诉他们我所走过的弯路,以避免他们再费旉Q这是一U对他h旉价值的重?
后来Q当我向每个C感谢,q且赞赏q套E序Q指邮g列表中的讨论--译者注Q运作得非常的时候,一个Linux内核邮g列表QlkmlQ成员表C,问题得到解决q׃我是q个列表中的“名人”,而是因ؓ我用了正的方式来提问?
我们黑客从某U角度来说是拥有丰富知识但缺乏h情味的家伙;我相信他是对的,如果我象个乞讨者那h问,不论我是谁,一定会Ҏ(gu)某些人或者被他们忽视。他我记下这件事Q给~写q个指南的h一些指对{?
============
============
如果仍得不到{案Q请不要以ؓ我们觉得无法帮助你。有时只是看C问题的h不知道答案Ş了。没有回应不代表你被忽视Q虽然不可否认这U差别很隑分?
ȝ说来Q简单的重复张脓(chung)问题是个很糟的想法。这被视ؓ无意义的喧闹。你可以通过其它渠道获得帮助Q这些渠道通常更适合初学者的需要?
有许多网上的以及本地的用LQ由狂热的Y件爱好者(即他们可能从没亲自写过M软gQ组成。通常Zl徏q样的团体来互相帮助q帮助新手?
另外Q你可以向很多商业公司寻求帮助,不论公司大还是小QRed Hat和LinuxCare是两个最常见的例子)。别付费才能获得帮助而感到沮丧!毕竟Q假使你的汽车发动机汽密封圈爆掉了--完全可能如此--你还得把它送到修R铺,q且为维修付贏V就Y件没p你一分钱Q你也不能强求技术支持L免费的?
对大众化的YӞpLinux之类而言Q每个开发者至会有上万名用户。根本不可能׃个h来处理来自上万名用户的求助电(sh)话。要知道Q即使你要ؓ帮助付费Q同你必购买同cY件相比,你所付出的也是微不道的Q通常闭源代码Y件的技术支持费用比开放源代码软g要高得多Q而且内容也不那么丰富Q?
-- LaserHe - 13 Jul 2005
Q{载自http://www.pgsqldb.orgQ?/P>