搜索
首页Javajava教程使用Java Swing 创建一个XML编辑器(三)

假如你现在正在寻找一个跨平台、资源开放的xml编辑器的话,您可能很快就能够实现这个愿望了。在这个三部分系列文章中,我将带您利用一些最通常的Java 2 Swing组件开发一个简单的 XML编辑器。本系列将有益于那些想编写他们的自己的XML编辑器的朋友或者帮助您学习或温习Swing。 
 

  这是本系列的第三篇文章。在第一个篇文章中,我们简要地讨论了XML和为什么树形结构适合显示XML、如何处理XML 数据、如何使用JTree Swing组件,并且我们还构建一个可重用组件用来解析XML文件并在JTree中显示数据。

  在第二篇文章中,我们创建了用于我们XML编辑器的框架结构。为了做到这个目的,我们谈到了许多Swing组件(包括 jsplitPane、JScrollPane、 JButton和JTextArea )。 JSplitPane对象又包含了两个JScrollPane对象,一个用于XML的图形化浏览,另外一个用于文本浏览。

  在这最后一篇文章中,我们将把最后的界面添加到 XML编辑器中,使它能够更加用户友好化。我们将先构建一个菜单系统,然后继续构造访问基层文件系统的JFileChooser组件来答应保存XML文件并打开新建文档。最后,我们将构建一个JDialog框,使用户能够取消一个命令并退出应用程序。

  那么如何增强我们的Swing应用程序的性能,以使它们利用菜单,访问文件系统并答应用户取消操作呢?我们需要创建JMenu组件来处理应用程序的菜单,创建JFileChooser组件来访问基层文件系统,使用JDialog框来答应用户取消操作。

  在以前的文章中,我们开发了XTree类??一个衍生于 JTree类的可重用组件,能够把 XML数据以图形化树来显示。因为我们喜欢使用面向对象原则,我们今天所做的修改不会接触那个类。因为我们喜欢使用面向对象原则,我们今天所做的修改不会接触那个类。它是一个自包含可重复使用的类,被我们的JFrame容器使用而不是被结合。

  第一节 构建菜单组件

  一个JMenu组件包括几个对象:一个菜单栏、一个或更多菜单和一个或更多菜单项。菜单栏包含菜单,而菜单又包含菜单项。这些Swing组件的名称都相当直观的(分别为 JMenuBar、JMenu和 JMenuItem)。

  下面是创建一个包含单一菜单项的最小的" File "菜单的全部的代码:

JMenu fileMenu = new JMenu( "File" );
JmenuItem exitItem = new JMenuItem( "Exit" );

fileMenu.add( exitItem );

JmenuBar menuBar = new JMenuBar();
 
menuBar.add( fileMenu );

setJMenuBar( menuBar );

  这个过程我们应该非常熟悉,JMenu组件使在任何其他 Java GUI组件构建时创建的。最内部的元素被加到它们的直接父元素中,直到所有的元素都已定义了一个适当的容器。

  返回XmlEditor个案研究中,我们实际上已经创建了一个完整的文件菜单,有创建新的 XML文件、打开一个现有的文件、保存文件和退出的功能。我们将在下一小节中具体谈谈它。

  第二节 处理菜单事件

  我们想要创建一个典型的文件菜单,能让我们的用户创建一个新文档,打开一个现有的文件,保存当前的文件并退出应用程序。既然我们知道如何构建这个菜单,那么我们如何响应用户的菜单选择呢?和其他Swing组件一样,答案就在于事件模型和可用的监听者组件。

  处理一个菜单选择最基本的方法就是把一个作用监听者添加到菜单项中: exitItem.addActionListener(new exitMenuHandler());当处理复杂的事件处理时(因为菜单系统有可能变得很复杂),应当把事件处理程序定义成单独的类。上面给出的那个例子添加一个exitMenuHandler类型的行动监听者。这个类型稍后将在这个应用程序中定义。下面是一个定义exitMenuHandler类所需要最少的代码:

class exitMenuHandler implements ActionListener {
public void actionPerformed( ActionEvent ae ) {
System.exit(0);
}
}

  虽然这个实现用来证实一个单独类的定义可能似乎太过简单了,但是当我们定义用于打开并保存文件的事件处理代码时,你将熟悉到把单独的功能性放入单独的类文件的重要性。此外,这个方法将答应你在不同的应用程序之间重复使用公共菜单功能。

第三节 构建文件系统存取组件

  这个Java应用程序经常需要答应用户通过一个图形化文件系统浏览程序访问文件系统。典型情况下,这是因为用户想要打开或保存一个组件或文件。在我们的XmlEditor应用程序中,我们想要用户能够做到这些。

  为了访问基本文件系统,javax.swing包中有一个非常好的组件:JFileChooser组件。无疑,在利用 JFileChooser组件之前你已经使用一个 Swing应用程序。

  为了创建一个JFileChooser,你要先实例化一个 JFileChooser对象,设置它的大小然后声明它要么用于打开文件要么用于保存文件。你要把这个对象和它的父对象-用来激活它的对象 (在我们的例子中是一个菜单项)联系起来,然后把它要么设置为打开对话框或者保存对话。为了做到这点,你要使用showSaveDialog()或 showOpenDialog()方法,两个都返回一个int类型的返回值。下面是一个简短的例子:

JFileChooser jfc = new JFileChooser();
jfc.setSize( 500, 250 );
Container parent = openItem.getParent();
int choice = jfc.showOpenDialog(parent);

  最后一行返回的整数值指出用户最后到底是打开/保存一个文件还是按下取消按钮。为了响应打开/保存事件,可以把这个整数值定义在 JFileChooser类中的 APPROVE_OPTION常数比较。此时,你只须使用适当的方法打开/保存用户请求的文件。

  请参看代码段1,是这个应用程序的完整的实现;它包含了所有的六个方法用于构造 XmlEditor应用程序的菜单处理功能。

  第四节 构建对话框组件来验证选择

  现在,当你点击 Jframe的关闭窗口时,这个应用程序立即关闭。这不太好。假如用户在操作一个文件时意外地关闭窗口,那么怎么办?我们想提示用户,询问他们是否真要关闭应用程序。

  我们可以使用一个JDialog对话框来实现这个目的。每个图形应用程序可以在用户覆盖另外一个文件、没有保存就关闭某个文件或在关闭应用程序之前使用它们来提醒用户。为了简化编程,我们就把关心的重点放在关闭编辑器的时候,提醒用户。

  我们需要做的就是创建一个JDialog对话框,这个对话框配有Jlabel,它包含了提示语和两个按钮,一个用来接收关闭程序的命令,另外一个取消关闭程序的命令。下面是构造这个组件的代码:

JDialog verifyDialog = new JDialog( this, "Confirm Exit", true );
Jlabel question = new JLabel( "Are you sure you want to exit?" );
Jbutton okButton = new JButton( "OK" );
okButton.addActionListener( this );
Jbutton cancelButton = new JButton( "Cancel" );
cancelButton.addActionListener( this );
verifyDialog.getContentPane().setLayout( new FlowLayout() );
verifyDialog.getContentPane().add( question );
verifyDialog.getContentPane().add( okButton );
verifyDialog.getContentPane().add( cancelButton );
verifyDialog.hide();

  现在,还剩两件事没做。我们必须为这两个按钮编写事件处理代码并把窗口关闭事件行为用之取代。就处理这两个按钮而言,我们只要在按下 OK时关闭这个应用程序而当按下 Cancel时隐藏对话框。

  最后一步就是覆盖默认的窗口关闭事件动作。默认情况,即使你创建了一个对话框然后用户单击取消按钮, JFrame仍然接收到关闭窗口事件。这将造成 JFrame隐藏本身,除非我们使用下列设置覆盖它:

setDefaultCloSEOperation( JFrame.DO_NOTHING_ON_CLOSE );

  新的设置将使响应窗口关闭事件时绝对不会关闭它本身。它只有响应System.exit()调用时才会关闭它本身。

  一旦你添加了菜单组件,定义用于菜单事件的事件处理程序并添加取消意外关闭窗口事件的方法,我们就可以测试这个应用程序并开始创建、编辑并保存 XML文件了。

  恭喜!恭喜!你已经有了手工编写的基于Swing的XML编辑器。剩下的工作就由你来完成了,你需要验证它,增加它的健壮性,还可以增加一些新的功能。

附:代码段1

class newMenuHandler implements ActionListener
{
 public void actionPerformed ( ActionEvent ae )
 {
  textArea.setText( "" );
  try
  { // 创建一个新的XTree
   xTree = new XTree();
   xTree.getSelectionModel().setSelectionMode(  
      TreeSelectionModel.SINGLE_TREE_SELECTION );
   xTree.setShowsRootHandles( true );
   // 这个工具更高级的版本,答应修改JTree
   xTree.setEditable( false );
  }
  catch( Exception ex )
  {
   String message = ex.getMessage();
   ex.printStackTrace();
  }
  file://结束try/catch
 }
 file://结束actionPerformed()
}
file://结束class newMenuHandler
class openMenuHandler implements ActionListener
{
 JFileChooser jfc;
 Container parent;
 int choice;
 openMenuHandler()
 {
  super();
  jfc = new JFileChooser();
  jfc.setSize( 400,300 );
  jfc.setFileFilter( new XmlFileFilter() );
  parent = openItem.getParent(); }
  file://结束openMenuHandler()
  class openMenuHandler implements ActionListener
  {
   JFileChooser jfc;
   Container parent;
   int choice;

   openMenuHandler()
   {
    super();
    jfc = new JFileChooser();
    jfc.setSize( 400,300 );
    jfc.setFileFilter( new XmlFileFilter() );
 
    parent = openItem.getParent();
   }
 public void actionPerformed( ActionEvent ae )
 {

  choice = jfc.showOpenDialog( parent );
 
  if ( choice == JFileChooser.APPROVE_OPTION )
  {
   String fileName, line;
   BufferedReader reader;

   fileName = jfc.getSelectedFile().getAbsolutePath();

   try
   {
    reader = new BufferedReader(
    new FileReader( fileName ) );

    textArea.setText( reader.readLine() + " " );

    while ( ( line = reader.readLine() ) != null )
    {
     textArea.append( line + " " );
    }
   reader.close();

   xTree.refresh( textArea.getText() );
  }
  catch ( Exception ex )
  {
   String message = ex.getMessage();
   ex.printStackTrace();
  }

  jfc.setCurrentDirectory( new File( fileName ) );
  }

 }
}
class saveMenuHandler implements ActionListener
 {
  JFileChooser jfc;
  Container parent;
  int choice;

  saveMenuHandler()
  {
   super();
   jfc = new JFileChooser();
   jfc.setSize( 400,300 );
   jfc.setFileFilter( new XmlFileFilter() );

   parent = saveItem.getParent();
  }

 public void actionPerformed( ActionEvent ae )
 {
 
  choice = jfc.showSaveDialog( parent );

  if ( choice == JFileChooser.APPROVE_OPTION )
  {
   String fileName;
   File fObj;
   FileWriter writer;

   fileName = jfc.getSelectedFile().getAbsolutePath();

   try
   {
    writer = new FileWriter( fileName );

    textArea.write( writer );

    writer.close();
   }
   catch ( IOException ioe )
   {
    ioe.printStackTrace();
   }
   jfc.setCurrentDirectory( new File( fileName ) );
  }

 }
}

class exitMenuHandler implements ActionListener
{
 public void actionPerformed( ActionEvent ae )
 {
  verifyDialog.show();
 }
}
class XmlFileFilter extends javax.swing.filechooser.FileFilter
{
 public boolean accept( File fobj )
 {
  if ( fobj.isDirectory() )
   return true;
  else
   return fobj.getName().endsWith( ".xml" );
  }

public String getDescription()
{
 return "*.xml";
}

 以上就是使用Java Swing 创建一个XML编辑器(三)的内容,更多相关内容请关注PHP中文网(www.php.cn)! 


声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
说明JVM如何充当Java代码和基础操作系统之间的中介。说明JVM如何充当Java代码和基础操作系统之间的中介。Apr 29, 2025 am 12:23 AM

JVM的工作原理是将Java代码转换为机器码并管理资源。1)类加载:加载.class文件到内存。2)运行时数据区:管理内存区域。3)执行引擎:解释或编译执行字节码。4)本地方法接口:通过JNI与操作系统交互。

解释Java虚拟机(JVM)在Java平台独立性中的作用。解释Java虚拟机(JVM)在Java平台独立性中的作用。Apr 29, 2025 am 12:21 AM

JVM使Java实现跨平台运行。1)JVM加载、验证和执行字节码。2)JVM的工作包括类加载、字节码验证、解释执行和内存管理。3)JVM支持高级功能如动态类加载和反射。

您将采取哪些步骤来确保Java应用程序在不同的操作系统上正确运行?您将采取哪些步骤来确保Java应用程序在不同的操作系统上正确运行?Apr 29, 2025 am 12:11 AM

Java应用可通过以下步骤在不同操作系统上运行:1)使用File或Paths类处理文件路径;2)通过System.getenv()设置和获取环境变量;3)利用Maven或Gradle管理依赖并测试。Java的跨平台能力依赖于JVM的抽象层,但仍需手动处理某些操作系统特定的功能。

Java是否需要特定于平台的配置或调整区域?Java是否需要特定于平台的配置或调整区域?Apr 29, 2025 am 12:11 AM

Java在不同平台上需要进行特定配置和调优。1)调整JVM参数,如-Xms和-Xmx设置堆大小。2)选择合适的垃圾回收策略,如ParallelGC或G1GC。3)配置Native库以适应不同平台,这些措施能让Java应用在各种环境中发挥最佳性能。

哪些工具或库可以帮助您解决Java开发中特定于平台的挑战?哪些工具或库可以帮助您解决Java开发中特定于平台的挑战?Apr 29, 2025 am 12:01 AM

Osgi,Apachecommonslang,JNA和JvMoptionsareeForhandlingForhandlingPlatform-specificchallengesinjava.1)osgimanagesdeppedendendencenciesandisolatescomponents.2)apachecommonslangprovidesitorityfunctions.3)

JVM如何在不同平台上管理垃圾收集?JVM如何在不同平台上管理垃圾收集?Apr 28, 2025 am 12:23 AM

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

为什么Java代码可以在不同的操作系统上运行,而无需修改?为什么Java代码可以在不同的操作系统上运行,而无需修改?Apr 28, 2025 am 12:14 AM

Java代码可以在不同操作系统上无需修改即可运行,这是因为Java的“一次编写,到处运行”哲学,由Java虚拟机(JVM)实现。JVM作为编译后的Java字节码与操作系统之间的中介,将字节码翻译成特定机器指令,确保程序在任何安装了JVM的平台上都能独立运行。

描述编译和执行Java程序的过程,突出平台独立性。描述编译和执行Java程序的过程,突出平台独立性。Apr 28, 2025 am 12:08 AM

Java程序的编译和执行通过字节码和JVM实现平台独立性。1)编写Java源码并编译成字节码。2)使用JVM在任何平台上执行字节码,确保代码的跨平台运行。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具