黑马程序员——>第二十二天<GUI(概念-布局-事件监听-鼠标键盘-对话框-菜单)>

android培训java培训、期待与您交流-------

01GUI(概述)


两种和用户交互的界面


GUI 图形用户界面

GUI Graphical User Interface 图形用户接口

   用图形的方式,来显示计算机操作的界面,这样更方便更直观

CLI  
Command Line User Interface  命令行用户接口

  就是常见的Dos命令行操作
  需要记忆一些常用的命令,操作不直观

举例:  

  比如:创建文件夹,或者删除文件夹

JAVA为GUI提供的对象都存在java.Awt  和 javax.Swing两个包中


Awt与Swing

java.Awt:Abstract Window ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能(有点依赖于平台)。属重量级控件    跨平台性不是特别的好(在这个平台开发的程序  拿到另一个平台上  界面可能差别不大  但是具体的一些细节  比如 颜色 字体 甚至于大小上稍微有点不同 )   所以它比较依赖于 系统

重量级   说明与系统的 依赖性要强一些           它的实现其实都是在调用系统里的实现方式

为了进行彻底的跨平台  对其进行了升级
javax.Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且安全由java实现。增强了移植性,属轻量级控件。   在任何系统下  显示的效果都一模一样

eclipse 用的swt界面


继承关系图

                                                             Component  构件
                         Container    容器                                        Button   按钮

               Window窗口              Panel 面板                                    Label    标签(封装文字)     
       Frame 框架        Dialog 对话框                                             Checkbox   复选框

                                                                                                     TextComponent   文本组件

                        FileDialog   文件对话框 保存时的界面          TextArea文本区域   TextField文本框
                              
Container 作为一个组件,它里边能添加组件。  而其他那些  虽然跟它平级,但是他们不能添加组件

          可以通过add方法添加其他组件进来  

学习完这个体系完以后    一会参阅完component里边的方法,创建谁的对象比较合适。      Frame比较合适   因为我们要创建一个窗体出来,                                                         
02GUI(布局)

布局管理器

容器中的组件的排放方式,就是布局

 常见的布局管理器
  FlowLayout(流式布局管理器)
    从左到右的顺序排列
    Panel默认的布局管理器
  BorderLayout(边界布局管理器)
    东,南,西,北,中          默认居中   添加新组件就会覆盖
    Frame默认的布局管理器
  GridLayout(网格布局管理器)   计算器
    规则的矩阵
  CardLayout(卡片布局管理器)   右键  属性  里边的都是卡片布局
    选项卡
  GridBagLayout(网格包布局管理器)  计算器中的 ce按钮
    非规则的矩阵

在编程之前都要打草稿,否则   做出来的东西虽然功能实现 但是奇丑无比

坐标式布局是最牛的   想放哪里放哪里!

多种布局完成:  这是一个窗体或者叫做 frame,你必须先将窗体进行大区快的划分,那就是先设置一下窗体的布局,设置完以后,这里边加入进来的不是那些组件,而是 panel(面板)。然后将那些具体的组件都添加到面板当中,如果上一个面板是边界式布局的话,那么只要设置面板的布局管理器就行了。  在下一个面板当中再设置流式布局。

03GUI(Frame)
component是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互。典型图形用户界面中的按钮。复选框和滚动条都是组件示例。

container add(Component comp,int index)  可以添加索引
    将指定的组件添加到此容器的给定位置上
  container能够添加组件   那些组件都是对象,它把对象都添加到窗体当中,代表了 (它内部其实封装了一个集合),它把这些组件对象都添加到集合当中,都带着角标。所以你可以在其任意的位置上添加元素

看了父类的方法  用子类创建对象

Frame()   构造一个最初不可见的Frame新实例().

import java.awt.*;
/*
通过5步来完成  图形化界面的制作
1.创建frame窗体
2.对窗体进行基本设置
   比如大小,位置,布局
3.定义组件
4.将组件通过窗体的add方法添加到窗体中。
5.让窗体显示,通过setVisible(true)

class AwtDemo
{
 public static void main(String[] args)
 {
  Frame f = new Frame("my awt");
  f.setSize(500,100);   //设置长宽 500走的是横坐标  100走的是纵坐标   这个时候出来的位址总是左上角

  f.setLocation(300,,200);//设置本地位置  300顶点距离左边的距离   200  顶点距离上边的距离
  f.setVisible(true); 

  f.setLayout(new FolwLayout());  // 创建流式布局管理器

  Button b = new Button("我是一个按钮");  //创建按钮   直接创建对象  现在按钮和窗体没有关系
  f.add(b);//用容器的add方法将这个按钮加进来
   
 }  
}

这时 创建出来的 窗体无法关闭  那是因为:现在是少了一些动作,我们只做了界面,做完以后并没有去给这些界面加一些效果。  这里就涉及到一个最重要的一个部分   事件监听机制
04GUI(事件监听机制)


事件监听机制组成

  事件源(组件)
  事件(Event)
  监听器(Listener)
  事件处理(引发事件后处理方式)


事件监听机制流程图 (自己画的)

                                               4将事件对象传给事件处理方式
监听器  监听引发事件的动作(事件处理方式)   <--------------------------------------                         
               |                                                                                              |
               |1 将监听器注册到事件源                                                       |
              \|/                3产生事件对象                                                      |
          事件源(组件)--------------------------------> 事件对象----------------->-
              /|\                                                              
               | 2 有监听器所监听的动作  作用于事件源上                        
               |
            外部动作

 


 首先要有一个事件源(锁),然后要将警报器安到锁上,这个警报器称为监听器, 监听器里边要有动作,监听砸的动作。将监听器安装到事件源上;只有将砸的动作作用到事件源上才会被监听到,  所以紧跟真要有一个外部动作,如果这个动作整好符合监听器监听的这个砸的动作,  监听器监听到这个动作,立刻产生事件对象, 砸锁事件就产生了,这个事件会被封装成一个对象,(事件中要封装一个  到底谁出的事   所以  事件中至少会封装事件源)   这个事件一发生,谁在监听这个事件就给谁,   保安室将这个事件注册到事件源上,当事件源发生了事情以后,就将事件发送给了 监听这个动作的监听器,  传过来后,这个监听器里边就可以写相对应的处理方式。

事件监听机制的特点

   事件源    就是awt包或者swing包中的那些图形界面组件

   事件      每一个事件源都有自己特有的对应事件和共性事件

   监听器    将可以触发某一个事件的动作(不止一个动作)都已经封装到了监听器中   好处 :完全由监听器进行处理

   处理方式       我们能做的就是处理方式     


以上三者,在java中都已经定义好了
  直接获取其对象来用就可以了

 

我们要做的事情是:就是对产生的动作进行处理       不管怎么处理   都得有按钮

事件监听机制
  确定事件源(容器或组件)
  通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上
  该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象

  一般用匿名内部类来表示
  在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收
  事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者getComponent()获取)


 用户对组件的操作,就是一个事件,那么产生事件的组件就是事件源。
 接收并处理事件,与用户进行交互的行为就是事件处理器。
 这些处理方式都封装在监听器中。

 就如同开密码锁,为了安全,密码锁上安装了报警装置,只要锁被砸就会把锁事件通知保安。
 那么保安就有相应的处理方式
 如果锁没有被砸,而是密码输入错误,那么报警装置也会将锁事件通知保安,保安也会有相应的处理方式


那么锁就是事件源,报警装置就是监听器,可以用来监听引发事件的动作。但必须要注册到锁上,否则锁被砸保安室不知道的。

对于每一种动作都有不同的处理方式


博物馆里来了一批宝物,要锁一个柜子里,那个锁是密码锁,这个密码锁如果有人要是去破坏它,保安那边得知道 密码锁得报警。 那么这个密码锁就做为一个事件源存在。这个密码锁放在这里  为了能和保安室有关系,应该把一个报警装置注册(装)到密码锁上, 什么情况下  报警装置会叫?  这里监控的是当有锁被砸的时候,报警装置就会响。一响   保安室就来人了。 这就是对报警这个事件进行的处理!  这里边就涉及到一些问题  1 锁是事件源,  2  报警装置(要注册到事件源上)  3  还涉及到了动作(砸)  换句话说   报警装置负责监控的动作就是砸   你砸完后  警报响了   就把砸锁事件传给了保安室  保安室就会有相对应的处理方式  (这个处理方式可以自定义 )


05GUI(窗体事件)
import java.awt.*;
import java.awt.event.*;
//图形化界面通常情况下要导两个包    因为你光做图形化界面没有效果是不行的    效果就是事件监听

class AwtDemo
{
 public static void main(String[] args)
 {
  Frame f = new Frame("my awt");
  f.setSize(500,100);     
  f.setLocation(300,,200);
  f.setVisible(true);
  //System.out.println("Hello World!");   
  

  f.setLayout(new FlowLayout());  
  Button b = new Button("我是一个按钮");  
  f.add(b); 

  f.addWindowListener(new MyWin());     //一点击  就监听到这个动作了   自动的调用处理方式

  f.addWindowListener(new WindowAdapter()    //匿名内部类
  {
   public void windowClosing(windowEvent e)
   {
    System.out.println("我关");       //   这个是最常用动作
    System.exit(0);
   }
public void windowActivated(WindowEvent e)  //窗体前置
{
 System.out.println("我活了。");
}

public void windowActivated(WindowEvent e)   //开启动作执行一次   打开完   它就结束
{
 System.out.println("我被打开了,hahahhaha");
}


  }); 
      
 }  
}


 


窗体frame   是事件源

addWindowListener(WindowListener l)
 // 添加指定的窗口侦听器,以从此窗口接收窗口事件


WineowAdapter// 接收窗口事件的抽象适配器类,此类中的方法为空。此类存在的目的是方便创建侦听器对象


class MyWin implements WindowListener
{
//覆盖7个方法。可是我只用到了关闭的动作
//其他动作都没有用到,可以却必须复写
}


//因为WindowListener的子类WindowAdapter已经实现了WindowListener接口
//并覆盖了其中的所有方法。那么我只要继承自WindowAdapter覆盖我需要的方法即可

class MyWin extends WindowAdapter
{
 public void windowClosing(WindowEvent e)//事件就接收进来了
 {
  //System.out.println("window closing");
  ///System.out.println("window closing----"+e.toString());
  System.exit(0); // 退出
 }
]


06GUI(Action事件)

把图形化界面和事件分离出来

class  FrameDemo            
{

 //定义该图形中所需的组件的引用。
 private Frame f;       //先有frame
 private Button but;   // 再有按钮          在这里建立引用  可以作用于整个类  都能被访问到,比较方便

 FrameDemo()   //通过构造函数的形式建立引用
 {
  init();
 }

 public void init()   //图形化界面初始化
 {
  f = new Frame("my frame");

  //对frame进行基本设置。

setBounds(int x,int y,int width, int height) // x y   坐标值   宽  高         移动组件并调整其大小

  f.setBounds(300,100,600,500);  
  f.setLayout(new FlowLayout());  //不想让按钮太大,单独指定布局管理器

  but = new Button("my button");  // 初始化  button

  //将组件添加到frame中
  f.add(but);

                                    // 这个时候不要加事件   要事件和图形化界面分离出来
  //加载一下窗体上事件。
  myEvent();

  //显示窗体;
  f.setVisible(true);

 }
 private void myEvent()       //可以将事件都加入这个里边来
 {
  f.addWindowListener(new WindowAdapter()
  {
   public void windowClosing(WindowEvent e)  //添加窗体监听  返回 窗体事件
   {
    System.exit(0);
   }
  });


 

  让按钮具备退出程序的功能

  按钮就是事件源。
  那么选择哪个监听器呢?
  通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器。 

  需要查看该组件对象的功能。因为具体的组件支持哪些监听   只有组件自己知道   所以添加监听器的方法肯定定义在组件内部   窗体监听  找  frame对象      按钮监听  要找按钮对象
   通过查阅button的描述。发现按钮支持一个特有监听addActionListener

    适配器的作用就一个   方便创建监听器对象   因为监听器里边有多个方法,  而我只需要用一个,我覆盖很多歌很麻烦,所以  给我们提供一个已有的子类   我们只要继承它,复写其中我们需要的那个就可以了
ActionListener里边只有一个方法,   就不需要适配器了   覆盖完这个方法就可以了  不需要适配器    只要方法超过三个的,包含三个  都要有适配器adapter

ActionListener是少数没有适配器接口的其中一个   几乎那些Listener(监听器)都有适配器

07GUI(鼠标事件)        08GUI(键盘事件)

 

  tf.addKeyListener(new KeyAdapter()    
  {
   public void keyPressed(KeyEvent e)
   {
    int code = e.getKeyCode();
    if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9))
    {
     System.out.println(code+".....是非法的");
     e.consume();
    } // 使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件:也就是说,按一下键盘,产生事件了,键盘的内容进到文本框中去,                                                                                     //就进去了,这个说不按照默认的方式处理,就是说不进去,不处理  取消掉屏蔽键


   }
  });

 

keyPressed(KeyEvent e)  //按下某个键时调用此方法

keyReleased(KeyEvent e)// 释放某个键时调用此方法

keyTyped(KeyEvent e)  //  键入某个键时调用此方法

 

//给But添加一个键盘监听。
  but.addKeyListener(new KeyAdapter() // 也是将but作为事件源,   有适配器
  {
   public void keyPressed(KeyEvent e) // 键盘事件内部会封装你按的那个键,
   { 

if(e.getKeyCode()==27)    //按Esc键退出程序   而 27我们一般情况下记不住,
{
 System.exit(0);
}
//而 27我们一般情况下记不住,所以

if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
{    
 System.exit(0);
}
    if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER)// 组合键 一起用 
ctrl+enter
     //System.exit(0);
    System.out.println("ctrl+enter is run");

    //System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"...."+e.getKeyCode());
System.out.println(e.getKeyChar()+"...."+e.getKeyCode()); /* 按钮现在是当前事件源,怎么判断是否是当前事件源呢?按钮上有一圈虚线框,这个时候就代表着它是当前事件源了,

      如果再有几个按钮的话,点到其他按钮上去,那么它就不是当前按钮了。     那么现在我只要按键盘,它就会触发当前事件源,就会有一个键盘事件产生,

        but是事件源,  在这个事件源上注册了addKeyListener,   那么现在这个but事件源已经存在了,看到这个but事件源作为当前事件存在就可以按键盘了,一按键盘,当前事件源的键盘监听就被触发了,因为按钮上有标示,

       有监听器,在监听键盘按下去的效果, 一按键盘就开始打印   .getKeyChar()键是谁       getKeyCode()键对应的码是谁
*/  }
  });


 

  but.addActionListener(new ActionListener()  // 按钮活动监听 
  {
   public void actionPerformed(ActionEvent e)
   {
    System.out.println("action ok");
   }   // 和下面那个哪个先发生   点击动作先执行
  });


光标不点击按钮也能执行,按钮只要被活动,它就能执行,就能出来那个动作,而鼠标键盘都能让按钮活动,   所以按钮上加事件的时候,尽量加ActionEvent,  但是两者是有区别的    点击要先执行,因为比活动更具体些。

mouseClicked(MouseEvent e)         鼠标按键在组件上单击(按下并释放)时调用

mouseEntered(MouseEvent e)         鼠标进入到组件上时调用

mouseExited(MouseEvent e)    鼠标离开组件时调用

mouseReleased(MouseEvent e)    鼠标按钮在组件上释放时调用

  but.addMouseListener(new MouseAdapter() // 确定事件源
  {//在but上添加鼠标监听器
   private int count = 1;
   private int clickCount = 1;
   public void mouseEntered(MouseEvent e) 
   {
    System.out.println("鼠标进入到该组件"+count++);
   }
   public void mouseClicked(MouseEvent e)
   {
    if(e.getClickCount()==2)   //返回与此事件关联的鼠标单击次数
     System.out.println("双击动作"+clickCount++);

System.out.println("鼠标进入到该组件"+count++);
   }
  });
  */
 }

当鼠标事件产生的时候,可以获取到鼠标的按键,或者说被点击后鼠标的点击次数,这些东西都属于鼠标内的东西(你按的左键还是右键 都可以知道),只有鼠标事件产生以后才会产生这样的信息,

09GUI(练习-列出指定目录内容)

在文本框中输入目录,点击“转到”按钮,将该目录中的文件与文件夹名称列在下面的文本区域中。
 先把界面做出来,然后往里边加事件,把事件写完再验证一边就ok了!
   制作界面

  添加功能    c:\     一点转到按钮,  里边列出的是c盘的文件和文件夹名称
 这个功能中按钮是事件源  按钮操作TextField和TextArea   先获取TextField中的数据(你要获取文本框中的数据,要找文本框这个对象),

形化界面仅仅是与用户进行交互的一种方式,更为直观的方式,你最终操作到具体的细节上还是我们当年的写代码。

10GUI(对话框Dialog)

上面的窗体功能实现了  但是错误提示却没有完成,你总不能写上一个输出语句说你输入的目录是错的  这样的方式到后期就用不了了,因为我们可以把这个图形化界面做成一个可执行程序,也就是说   不需要再依赖于控制台了,你写输出语句是没地方打印的,   这时就搞一个对话框

Dialog是一个带标题和边界的顶层窗口
 通常情况下  对话框不单独存在,是因为只有发生一些事情才会蹦出来,  在窗体中进行了一些操作后,因为误操产生了对话框,所以对话框一般依赖于窗体。  这时就要new dialog 对象    为了 优化效果,等你满足否则这个条件后,再去new这个对象,因为我们没有必要说窗体一产生 Dialog对象就存在了 这样没有什么意义,等什么时候误操作了 再new对象  这是比较优化内存的效果



 private Dialog d;  //为了方便阅读程序就写到外面了  就是窗体加载完不该先有的对象,你不让他先存在
                                //有可能别人点半天 没有出现误操作,这个对话框就没有必要在内存中存在
Dialog中有两个因素:  信息  按钮


  d = new Dialog(f,"提示信息-self",true);   //dialog初始化     true代表模式

//模式为true  这个对话框你不操作,它所属的那个窗体你操作不了
//模式为false 只个对话框你不操作,扔一边去,这个窗体继续操作

  d.setBounds(400,200,240,150);  // 设置dialog
  d.setLayout(new FlowLayout());
  lab = new Label();          // label初始化   里边没有信息   因为我还不知道写什么信息
  okBut = new Button("确定");

  d.add(lab);
  d.add(okBut);


  // 只有见到某些操作,对话框窗体才会存在,需要来一个d.setVisible(true);而不是时时刻刻存在
  f.add(tf);    // d本身是一个窗体  不能加入到 frame当中去  因为frame一打开它就存在,没意义
  f.add(but);
  f.add(ta);
//Dialog默认布局为 边界式布局  而且 点差   没效果
图形化界面这点不太好  new对象特别多   导致运行有点慢

11GUI(菜单)

在做菜单之前先分析一个问题,  你先看到的是什么  菜单栏; 菜单栏里边有很多菜单, 菜单里边有很多菜单下, 菜单下有很多子菜单,


MenuBar类封装绑定到框架的菜单栏的平台概念,为了将该菜单栏与Frame对象关联,可以调用该框架的setMenuBar方法,而不是add方法

menu菜单是menuItem菜单项中的子类

MenuBar中有     add(Menu m)                                菜单栏
 Menu方法    中有   add(MenuItem mi)                菜单
  MenuItem                                   菜单项
菜单当中可以添加菜单项
 菜单中还可以添加菜单

菜单有箭头   条目没有箭头

往菜单里边添加菜单   右边就会有箭头      菜单项是最终项

菜单中可以添加菜单条  也可以添加菜单  既可以添加它的父类   也可以添加自己

12GUI(练习-打开文件)

package mymenu;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class MyMenuTest
{

 private Frame f;
 private MenuBar bar;
 private TextArea ta;  // 文本区域
 private Menu fileMenu;
 private MenuItem openItem,saveItem,closeItem; //  打开   保存  关闭条目


 private FileDialog openDia,saveDia;  //  FileDialog类显示一个对话框窗口,用户可以从中选择文件。

 private File file;
 MyMenuTest()
 {
  init();
 }
 public void init()
 {
  f = new Frame("my window");
  f.setBounds(300,100,650,600);

  bar = new MenuBar();

  ta = new TextArea();     //初始化文本区域

  fileMenu = new Menu("文件");
  
  openItem = new MenuItem("打开");   //依次初始化
  saveItem = new MenuItem("保存");
  closeItem = new MenuItem("退出");
  
  fileMenu.add(openItem);  //挨个往里边添加
  fileMenu.add(saveItem);
  fileMenu.add(closeItem);
  bar.add(fileMenu);

  f.setMenuBar(bar);

//FileDialog类显示一个对话框窗口,用户可以从中选择文件。
  openDia = new FileDialog(f,"我要打开",FileDialog.LOAD);  //加载
  saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE); // 保存
//默认为打开 load

  f.add(ta);
  myEvent();

  f.setVisible(true);


 }



13GUI(练习-保存文件)
  当我们新创建了一个文件,写点数据  一点保存,会弹出对话框   因为弹与不弹,依据的就是这个数据所在那个文件是否存在,文件存在了 就不需要再弹了,文件不存在才需要弹       而另存为是说无论文件是否存在都要弹出

 

private void myEvent()
 {

 saveItem.addActionListener(new ActionListener()
  {
  
   public void actionPerformed(ActionEvent e)
   {
    if(file==null) // 弹与不弹只要判断文件是否存在就可以了
    {  //文件不存在   才做这些事情  并给文件初始化
     saveDia.setVisible(true);  //先弹出来
//要将文件存到哪里去 要指定那个位置  所以一样要获取那个目录以及文件名
     String dirPath = saveDia.getDirectory();
     String fileName = saveDia.getFile();
     if(dirPath==null || fileName==null)
      return ;
     file = new File(dirPath,fileName);
    }

    try
    { // 若存在  直接将文本区域中的数据写到文件当中就可以了  这个时候只讲目的,源是文本区域中的数据  不再是控制台  也不再是键盘录入了
     BufferedWriter bufw  = new BufferedWriter(new FileWriter(file));

     String text = ta.getText();

     bufw.write(text);
     //bufw.flush(); // 这里可以不写flush
     bufw.close();
    }
    catch (IOException ex)
    {
     throw new RuntimeException();
    }
    
   }
  });


  openItem.addActionListener(new ActionListener()
  {
   public void actionPerformed(ActionEvent e)
   {
    openDia.setVisible(true);                          //  要展示出来


//要操作硬盘上已有的数据并将其显示在文本区域中   要操作的是源,是纯文本文件要用到filereader或bufferedreader
    //但是前提是你要知道我选的是哪个文件   你选择的是哪个文件是通过的filedialog对象在操作,那么怎么选   它最清楚
    String dirPath = openDia.getDirectory();  //路径
    String fileName = openDia.getFile();      //文件名
//    System.out.println(dirPath+"..."+fileName);
    if(dirPath==null || fileName==null)
     return ;   // 直接返回  不做任何事情
//若不写  会有空指针异常

    ta.setText("");
    file = new File(dirPath,fileName);  //new 对象

    try
    {
     BufferedReader bufr = new BufferedReader(new FileReader(file));

     String line = null;

     while((line=bufr.readLine())!=null)
     {
      ta.append(line+"\r\n");//读一行就添加到 
     }

     bufr.close();
    }
    catch (IOException ex)
    {
     throw new RuntimeException("读取失败");
    }


   }
  });

14GUI(jar包双击执行)

 
如何制作可以双击执行的jar包呢?
1,将多个类封装到了一个包(package)中。
2,定义一个jar包的配置信息。
 定义一个文件a.txt 。文件内容内容为:
 Main-Class:(空格)包名.类名(回车)
3,打jar包。
 jar -cvfm my.jar a.txt 包名
4,通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。

5,通过工具--文件夹选项--文件类型--jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。
 jdk\bin\javaw.exe -jar

6,双击试试!。哦了。

 

-------android培训java培训、期待与您交流-------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值