黑马程序员Java Swing笔记分享(AWT篇)
Swing 类库结构(这边建议边学边看这个图片就可以建立一定的思维导图)
Swing 组件都采用 MVC(Model-View-Controller,即模型-视图-控制器)的设计,实现 GUI 组件的显示逻辑和数据逻辑的分离,从而允许程序员自定义 Render 来改变 GUI 组件的显示外观,以提供更多的灵活性。
Swing 围绕 JComponent 组件构建,JComponent 则由 AWT 的容器类扩展而来。Swing 组织结构如图 1 所示。
一.AWT布局管理
(1)_awt_container容器_API
Study01(创建Frame窗口)
public static void main(String[] args) {//创建窗口对象Frame frame=new Frame("window测试");// 创建窗口大小,位置frame.setLocation(100,100);frame.setSize(500,300);//设置窗口对象可见frame.setVisible(true);}
}
点击IDEA中的RUN,你可以得到一下窗口界面。
但是也有个问题我们需要手动在RUN中点掉暂停键,我们没办法关闭右上角的'X'(取消窗口) 。
Study02(创建Panel面板)
Panel是面板,是一个很少直接使用的基本组件,或者继承重写,或者用来组织其他组件。
panel和Jpanel都为中间层容器,可显示文字、图像、绘制图形,主要功能是在GUI中组织其他组件。
public static void main(String[] args) {//1.创建一个window对象,因为,panel以及其他的容器,都不能独立存在,//必须依靠window存在Frame frame=new Frame();//2.创建一个Panel对象Panel p=new Panel();//3.创建一个文本框和按钮,并且放入到Panel容器中p.add(new TextField("测试文本"));p.add(new Button("这是一个测试按钮"));//4.把Pannel放入window中frame.add(p);//5.设置window的位置以及大小frame.setBounds(100,100,500,300);//6.设置window可见frame.setVisible(true);}
1.点击运行却又出现按钮中乱码现象。
2. 此时由于我们用的是UTF-8,故需要不让乱码出现,则点击下方图片选项
3. 点进去之后,直接Alt+V,在出现的VM options的方框里面添加这么一句话 :
4.-Dfile.encoding=gbk
5.然后再次运行即可。
Study03(创建滚动窗格)
public static void main(String[] args) {Frame frame=new Frame();//1.创建一个ScrollPane对象ScrollPane sp=new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);//--->默认创建一个滚动条ScrollPane.SCROLLBARS_ALWAYS//2.往ScrollPane中添加内容sp.add(new TextField("测试文本"));sp.add(new Button("测试按钮"));//3.把ScrollPane添加到Frame中frame.add(sp);frame.setBounds(100,100,500,300);frame.setVisible(true);}
1.当然你运行的时候还是会有乱码出现,但问题不大,直接参考Study02蓝色字体。
(2)_awt_LayoutManger布局管理
Study04(创建FlowLayout)
public static void main(String[] args) {Frame frame = new Frame("测试FlowLayout");//1.通过setLayout方法设置容器的布局管理器//1)向左边对齐frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));//20为像素单位//2)向中间对齐frame.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));//20为像素单位//3)向右边对齐frame.setLayout(new FlowLayout(FlowLayout.RIGHT, 40, 20));//20为像素单位//2.添加多个按钮到frame中for (int i = 0; i <= 100; i++) {frame.add(new Button("按钮" + i));}//3.设置最佳大小,pack方法frame.pack();frame.setVisible(true);}
输出样例:向右的按钮输出
Study05(创建BorderLayout)
public static void main(String[] args) {Frame frame=new Frame("这里测试BorderLayout");//1.给frame设置BorderLayout布局管理器frame.setLayout(new BorderLayout(30,10));//2.往frame的指定区域添加组件frame.add(new Button("北侧按钮"),BorderLayout.NORTH);frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);frame.add(new Button("东侧按钮"),BorderLayout.EAST);frame.add(new Button("西侧按钮"),BorderLayout.WEST);frame.add(new Button("中间按钮"),BorderLayout.CENTER);frame.pack();frame.setVisible(true);}
输出样例:
Study06(中间区域放文本)
public static void main(String[] args) {Frame frame=new Frame("这里测试BorderLayout");//1.给frame设置BorderLayout布局管理器frame.setLayout(new BorderLayout(30,10));//2.往frame的指定区域添加组件frame.add(new Button("北侧按钮"),BorderLayout.NORTH);frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);frame.add(new Button("中间按钮"),BorderLayout.CENTER);frame.add(new TextField("测试文本"));frame.pack();frame.setVisible(true);}
输出样例:
1.但是这样的话会将中间按钮给覆盖掉了,那么如何将按钮与测试文本共同放在中间且不互相干扰呢?
public static void main(String[] args) {Frame frame=new Frame("这里测试BorderLayout");//1.给frame设置BorderLayout布局管理器frame.setLayout(new BorderLayout(30,10));//2.往frame的指定区域添加组件frame.add(new Button("北侧按钮"),BorderLayout.NORTH);frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);Panel p=new Panel();p.add(new Button("中间按钮"));p.add(new TextField("测试文本框"));frame.add(p);frame.pack();frame.setVisible(true);}
输出样例:
Study07(创建GirdLayout)
如何做一个简单的计算器界面?
public static void main(String[] args) {Frame frame = new Frame();//1、创建一个Panel对象,里面存放一个TextFiled组件Panel p=new Panel();p.add(new TextField(30));//2、把当前这个Panel添加到frame的北边区域frame.add(p,BorderLayout.NORTH);//3、创建一个Panel对象,并且设置他的布局管理器为GridLayoutPanel p2=new Panel();p2.setLayout(new GridLayout(5,10,3,3));//4.往Panel中添加内容for(int i=0;i<10;i++){p2.add(new Button(i+""));}p2.add(new Button("+"));p2.add(new Button("-"));p2.add(new Button("*"));p2.add(new Button("/"));p2.add(new Button("."));//5.把当前Panel添加到frame中frame.add(p2);frame.pack();frame.setVisible(true);}
输出样例:
Study08(创建CardLayout)
什么是CardLayout,CardLayout布局管理器以时间而非空间来管理它的组件,它将容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的Companent才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌可见。
方法名称 | 方法功能 |
CardLayout() | 创建默认的CardLayout布局管理器 |
CardLayout(int hgap,int vgap) | 通过指定卡片与容器左右边界的间距,上下边界间距来决定CardLayout的布局管理器 |
first(Container target) | 显示target容器中的第一张卡片 |
last(Container target) | 显示target容器中的最后一张卡片 |
previou(Container target) | 显示target容器中前一张卡片 |
next(Container target) | 显示target容器中的后一张卡片 |
show(Container target,String name) | 显示target容器中指定名字的卡片 |
public static void main(String[] args) {Frame frame=new Frame("测试CardLayout");//1、创建一个Panel容器,用来存储多张卡片Panel p1=new Panel();//2、创建一个CardLayout对象,并且把该对象设置给之前创建的Panel容器中CardLayout cardLayout=new CardLayout();p1.setLayout(cardLayout);//3、往Panel中储存多个组织String[] name={"第一张","第二张","第三张","第四张","第五张"};for(int i=0;i<name.length;i++){p1.add(name[i],new Button(name[i]));}//4、把Panel放到frame中的中间区域frame.add(p1);//5、创建另外一个panel p2,用来存储多个按钮组件Panel p2=new Panel();//6、创建5个按钮组件Button b1 = new Button("上一张");Button b2 = new Button("下一张");Button b3 = new Button("第一张");Button b4 = new Button("最后一张");Button b5 = new Button("第三张");//7、创建一个事件监听器,监听按钮的点击动作ActionListener listener=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String actionCommand = e.getActionCommand();//这个字符串其实就是按钮上的文字switch (actionCommand){case"上一张":cardLayout.previous(p1);break;case"下一张":cardLayout.next(p1);break;case"第一张":cardLayout.first(p1);break;case"最后一张":cardLayout.last(p1);break;case"第三张":cardLayout.show(p1,"第三张");break;}}};//8、把当前这个时间监听器和多个按钮绑定到一起b1.addActionListener(listener);b2.addActionListener(listener);b3.addActionListener(listener);b4.addActionListener(listener);b5.addActionListener(listener);//9、把按钮添加到容器p2中p2.add(b1);p2.add(b2);p2.add(b3);p2.add(b4);p2.add(b5);//10、把p2放到frame的南边区域frame.add(p2,BorderLayout.SOUTH);frame.pack();frame.setVisible(true);}
样例输出:有点类似与windows中的图片浏览软件,可以来回切换上下张图片。
Study09(创建BoxLayout)
方法名称 | 方法功能 |
BoxLayout(Container target,int axis) | 指定创建基于target容器的BoxLayout布局管理器,该布局管理器里的组件按照axis方向排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向 |
public static void main(String[] args) {Frame frame=new Frame();//1、基于frame容器,创建一个BoxLayout对象,并且,该对象存放的组件是垂直存放//BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);//------>基于frame容器,创建一个BoxLayout对象,并且,该对象存放的组件是水平存放BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);//2、把BoxLayout对象设置给Frameframe.setLayout(boxLayout);//3、往frame中添加两个按钮组件frame.add(new Button("按钮1"));frame.add(new Button("按钮2"));frame.pack();frame.setVisible(true);}
样例输出:水平方向的按钮
样例输出:垂直方向的按钮
Study10(创建容器Box)
在Java.swing中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数形况下,Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成窗口布局。
方法名称 | 方法功能 |
static Box createHorizontalBox() | 创建一个水平排列组件的Box容器 |
static Box creatVerticalBox() | 创建一个垂直排列组件的Box容器 |
public static void main(String[] args) {Frame frame = new Frame("测试BoxLayout");//1、创建一个水平排列组件的Box容器Box hBox = Box.createHorizontalBox();//2、往当前容器中添加两个按钮hBox.add(new Button("水平按钮1"));hBox.add(new Button("水平按钮2"));//3、创建一个垂直组件的Box容器Box vBox = Box.createVerticalBox();//4、往当前容器中添加两个按钮vBox.add(new Button("垂直按钮1"));vBox.add(new Button("垂直按钮2"));//5、把两个Box容器添加到FrameZ中展示frame.add(hBox, BorderLayout.NORTH);frame.add(vBox);frame.pack();frame.setVisible(true);}
样例输出:
但是这样的排布中间没有空隙, 那么怎么样让按钮之间有空隙呢?
public static void main(String[] args) {Frame frame = new Frame();//1、创建水平排列的Box容器Box hbox = Box.createHorizontalBox();//2、往hBox容器中添加按钮,还需要在多个按钮之间添加分割hbox.add(new Button("水平按钮1"));hbox.add(Box.createHorizontalGlue());//该分割在两个方向上都可以拉伸hbox.add(new Button("水平按钮2"));hbox.add(Box.createHorizontalStrut(30));//水平2与水平3之间不能拉伸,固定死了hbox.add(new Button("水平按钮3"));//3、创建垂直排列的Box容器 vBoxBox vBox = Box.createVerticalBox();//4、往vBox容器中添加按钮,还需要在多个按钮之间添加分割vBox.add(new Button("垂直按钮1"));vBox.add(Box.createVerticalGlue());//该分割在两个方向上都可以拉伸vBox.add(new Button("垂直按钮2"));vBox.add(Box.createVerticalStrut(30));//垂直按钮2与垂直按钮3之间是定死的,无论你怎么拉伸都不变vBox.add(new Button("垂直按钮3"));//5、把box容器中添加到frame中frame.add(hbox, BorderLayout.NORTH);frame.add(vBox);frame.pack();frame.setVisible(true);}
样例输出:
二.AWT中常用的组件
(1)_awt_常用基本组件
Study11(创建常用组件)
组件名 | 功能 |
Button | 按钮 |
Canvas | 用于绘图的画布 |
Checkbox | 复选框组件(也可以当作单选框组件使用) |
CheckboxGroup | 用于将多个Checkbox组件组合成一组,一组Checkbox组件将有只有一个可以被选中,即全部变成单选框组件 |
Choice | 下拉选择框 |
Frame | 窗口,在GUI程序里面通过该类创建窗口 |
Label | 标签类,用于放置提示性文本 |
List | 列表框组件,可以添加多个项目 |
Panel | 不能单独存在基本容器类,必须放到其他容器当中 |
Scrollbar | 滑动条组件,如果用户输入位于某个范围的值,就可以使用滑动条组件,比如调色板中设置RGB的三个值所用的滑动条。当创建一个滑动条时,必须指定它的方向、c初始值、滑块的大小、最小值以及最大值 |
ScrollPane | 带水平及垂直滚动条的容器组件 |
TextArea | 多行文本框 |
TextField | 单行文本框 |
1.如何利用上面组件组装成下面的例子
public class day12 {//基本步骤:创建基本组件Frame frame = new Frame();TextArea te = new TextArea(5, 20);Choice colorchoice = new Choice();CheckboxGroup cbg = new CheckboxGroup();Checkbox male = new Checkbox("男", cbg, true);Checkbox female = new Checkbox("女", cbg, false);Checkbox isMarried = new Checkbox("是否已婚");TextField tf = new TextField(20);Button ok = new Button("确认");List colorList = new List(6, true);public void init() {//1、组装界面//2、组装底部Box bBox = Box.createHorizontalBox();bBox.add(tf);bBox.add(ok);frame.add(bBox, BorderLayout.SOUTH);//3、组装 选择部分colorchoice.add("蓝色");colorchoice.add("红色");colorchoice.add("绿色");Box cBox = Box.createHorizontalBox();cBox.add(colorchoice);cBox.add(male);cBox.add(female);cBox.add(isMarried);//4、组装文本域与选择部分Box topLeft = Box.createVerticalBox();//------->组装文本区域topLeft.add(te);//------->组装选择区域topLeft.add(cBox);//5、组装顶部左边和列表框colorList.add("蓝色");colorList.add("红色");colorList.add("绿色");Box top = Box.createHorizontalBox();top.add(topLeft);top.add(colorList);frame.add(top);//设置frame为最佳大小,并且可见frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day12().init();//调用init方法}
}
1.首先将需要的组件列出来
2.将需要的组件组装起来
---->由上图可知先用一个box将下面的确定按钮以及文本区域组装在一起,并放在南边,由于文本区域与确定按钮是水平的,故用 :Box.createHorizontalBox()方法,组装为bBox
---->其次组装选择颜色的功能,由于也是与性别,已婚水平的也用Box.createHorizontalBox()方法,组装为cBox
---->组装最大文本域以及颜色选择,性别,已婚,由于二者是垂直关系,故用:Box.createVerticalBox()方法,将其组装成topLeft
---->最后例举colorlist,需要放在最top盒子的右边,那么再建造一个top盒子,将topLeft放在左边,colorlist放在右边,二者水平关系,用Box.createHorizontalBox()方法。
Study12(创建对话框Dialog)
Dialog是window类的子类,是一个容器类,属于特殊组件。对话框是可以独立存在的顶级窗口,因此与普通窗口的用法几乎完全一样,但是使用对话框需要注意下面两点:
- 对话框通常依赖其他窗口,就是通常需要有一个父类窗口
- 对话框有非模式和模式两种,当某个模式对话框被打开后,该模式对话框总是位于它的父窗口之上,在模式对话框被关闭之前,父窗口无法获得焦点。
方法名称 | 方法功能 |
Dialog(Frame owner,String title,boolean modal) |
创建一个对话框对象: onwer:当前对话框的父窗口 titile:当前对话框的标题 modal:当前对话框是否为模式对话框 |
1、什么是模式对话框?
模态对话框(Modal Dialogue Box,又叫做模式对话框),是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。所以无法对对话框以外的应用程序进行操作。
2、什么是非模式对话框
非模态对话框允许用户在处理非模态对话框的同时处理目标对话框。其实与上面的内容反之即可。
public static void main(String[] args) {Frame frame=new Frame();//1.创建两个对话框Dialog对象,一个模式,一个非模式Dialog d1 = new Dialog(frame, "模式对话框", true);Dialog d2=new Dialog(frame,"非模式对话框",false);//2、通过setBounds方法设置Dialog的位置与大小d1.setBounds(20,30,300,200);d2.setBounds(20,30,300,200);//3、创建两个按钮Button b1=new Button("打开模式对话框");Button b2=new Button("打开非模式对话框");//4、需要给这两个按钮添加点击后的行为(AWT事件)b1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {d1.setVisible(true);}});b2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {d2.setVisible(true);}});//5、把按钮添加到frame中frame.add(b1,BorderLayout.NORTH);frame.add(b2);frame.pack();frame.setVisible(true);}
3、但是如何添加组件到对话框里面去呢?
其实很简单只需要将基本组件装到Box中在将Box中的对象添加到对话框即可。
public static void main(String[] args) {Frame frame=new Frame();//1.创建两个对话框Dialog对象,一个模式,一个非模式Dialog d1 = new Dialog(frame, "模式对话框", true);//----->创建一个垂直的Box容器,把一个文本框以及确定按钮放在Box容器中Box vbox=Box.createVerticalBox();vbox.add(new TextField(20));vbox.add(new Button("确认"));//----->将vbox放在d1中去d1.add(vbox);//2、通过setBounds方法设置Dialog的位置与大小d1.setBounds(20,30,300,200);//3、创建两个按钮Button b1=new Button("打开模式对话框");//4、需要给这两个按钮添加点击后的行为(AWT事件)b1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {d1.setVisible(true);}});//5、把按钮添加到frame中frame.add(b1,BorderLayout.NORTH);frame.pack();frame.setVisible(true);}
Study13(创建对话框FileDialog)
Dialog类中还有一个子类:FileDialog,它代表一个文件对话框,用于打开或者保存文件,需要注意的是FileDialog无法指定模态还是非模态,这是因为FileDialog依赖于运行平台的实现,如果运行平台的为文件对话框是模态的,那么FileDialog也是模态的;否则就是非模态的。
方法名称 | 方法功能 |
FileDialog(Frame parent,String title.int mode) |
创建一个文件对话框: parent:指定父窗口 title:对话框标题 mode:文件对话框类型,如果指定为FileDialog.LOAD,用于打开文件,如果指定为FileDialog.SAVE,用于保存文件 |
String getDirectory() | 获取被打开或保存文件的绝对路径 |
String getFile() | 获取被打开或保存文件的文件名 |
public static void main(String[] args) {Frame frame = new Frame();//1、创建两个FileDialog对象FileDialog fileDialog = new FileDialog(frame, "选择要打开的文件", FileDialog.LOAD);FileDialog fileDialog1 = new FileDialog(frame, "选择要保存的文件", FileDialog.SAVE);//2、创建两个按钮Button b1 = new Button("打开文件");Button b2 = new Button("保存文件");//3、给这两个按钮设置点击后的行为:获取打开或者保存的路径文件名b1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {fileDialog.setVisible(true);//代码会阻塞到这里//获取选择的路径及文件String directory = fileDialog.getDirectory();String file = fileDialog.getFile();System.out.println("打开的文件路径为:" + directory);System.out.println("打开的文件名称为:" + file);}});b2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {fileDialog1.setVisible(true);//获取选择的路径及文件String directory = fileDialog1.getDirectory();String file = fileDialog1.getFile();System.out.println("打开的文件路径为:" + directory);System.out.println("打开的文件名称为:" + file);}});//4、把按钮添加到Frame中frame.add(b1, BorderLayout.NORTH);frame.add(b2);frame.pack();frame.setVisible(true);}
样例输出:
Study14(创建事件处理)
1)定义:当在某个组件上发生某些操作的时候,会自动的触发-段代码的执行。
2)在GUI事件处理机制中涉及到4个重要的概念需要理解:
事件源(Event Source) :操作发生的场所,通常指某个组件,例如按钮、窗口等;
事件( Event) : 在事件源上发生的操作可以叫做事件, GUI会把事件都封装到一个Event对象中 ,如果需要知道该事件的详细信息,就可以通过Event对象来获取。
事件监听器(Event Listener):当在某个事件源上发生了某个事件,事件监听器就可以对这个事件进行处理。
注册监听:把某个事件监听器(A)通过某个事件(B)绑定到某个事件源(C)上,当在事件源C上发生了事件B之后,那么事件监听器A的代码就会自动执行。
了解了上面机制,那么要如何实现下面图片呢,点击确定会有hello world出现?
------->
------->
public class day15 {Frame frame=new Frame();TextField tf = new TextField(30);Button ok = new Button("确定");public void init(){//组装视图//监听器//MyListener myListener=new MyListener();//注册监听ok.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {tf.setText("hello world");}});//把tf和ok放到Frame中frame.add(tf,BorderLayout.NORTH);frame.add(ok);frame.pack();frame.setVisible(true);}
// private class MyListener implements ActionListener {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// tf.setText("hello world");
// }
// }public static void main(String[] args) {new day15().init();}
Study15(常见事件和事件监听器)
事件监听器必须实现事件监听器接口,AWT提供了大量的事件监听器接口用于实现不同类型的事件监听器,用于监听不同类型的事件。AWT中提供了丰高的事件类,用于封装不同组件上所发生的特定操作, AWT的事件类都是AWTEvent类的子类,AWTEvent是EventObject的子类。
1、AWT把事件分为了两大类:
1)低级事件:这类事件是基于某个特定动作的事件。比如进入。点击、拖放等动作的鼠标事件,再比如得到焦点和失去焦点等焦点事件。
事件 | 触发时机 |
ComponentEvent | 组件事件,当组件尺寸发生变化、位置发生移动、显示/陶藏状态发生改变时触发该事件。 |
ContainerEvent | 容器事件,当容器里发生添加组件、删除组件时触发该事件。 |
WindowEvent | 窗口事件,当窗口状态发生改变(如打开、关闭。最大化、最小化)时触发该事件。 |
FocusEvent | 焦点事件,当组件得到焦点或失去焦点时触发该事件。 |
KeyEvent | 键盘事件,当按键被按下、松开、单击时触发该事件。 |
MouseEvent | 鼠标事件,当进行单击、按下、松开、移动鼠标等动作时触发该事件。 |
PaintEvent | 组件绘制事件。该事件是一个特殊的事件类型 ,当GUI组件调用update/paint方法来呈现自身时触发该事件,该事件并非专用于事件处理模型。 |
2)高级事件:这类事件并不会基于某个特定动作,而是根据功能含义定义的事件。
事件 | 触发时机 |
ActionEvent | 动作事件,当按钮、菜单项被单击,在TextField中按Enter键时触发。 |
AjustmentEvent | 调节事件,在滑动条上移动滑块以调节数值时触发该事件。 |
ItemEvent | 选项事件,当用户选中某项,或取消选中某项时触发该事件。 |
TextEvent | 文本事件,当文本框、文本域里的文本发生改变时触发该事件。 |
2、事件监听器
不同的事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口,当指定事件发生后,事件监听器就会调用所包含的事件处理器(实例方法)来处理事件。
3、案例一:
public static void main(String[] args) {Frame frame=new Frame("测试监听器");//创建组件(事件源)TextField tf=new TextField();Choice names=new Choice();names.add("刘岩");names.add("舒淇");names.add("闫妮");//给文本添加TextListener,监听内容变化tf.addTextListener(new TextListener() {@Overridepublic void textValueChanged(TextEvent e) {String text = tf.getText();System.out.println("当前文本的内容为:"+text);}});//给下拉选择框添加ItemListener,监听条目选项的变化names.addItemListener(new ItemListener() {@Overridepublic void itemStateChanged(ItemEvent e) {Object item = e.getItem();System.out.println("当前选中的条目为:"+item);}});//给frame注册ContainerListener监听器,监听容器组件的添加frame.addContainerListener(new ContainerListener() {@Overridepublic void componentAdded(ContainerEvent e) {//添加方法Component child = e.getChild();System.out.println("frame中添加了:"+child);}@Overridepublic void componentRemoved(ContainerEvent e) {//移除方法}});//添加到frame中Box hBox=Box.createHorizontalBox();hBox.add(names);hBox.add(tf);frame.add(hBox);//设置frame最佳大小并可见frame.pack();frame.setVisible(true);}
样例输出:
每次点击都会记录下监听内容:
4、 案例二:如何关闭右上角x键
public static void main(String[] args) {Frame frame=new Frame("测试WindowListener");frame.setBounds(200,200,500,300);//设置WindowListener,监听用户点击右上角X的动作,则关闭窗口frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});frame.setVisible(true);}
样例输出:
Study16(创建菜单组件)
前面讲了GUI界面的构建,其实就是把一些GUI的组件,按照一定的布局放在容器即可。在实际开发中,除了主界面,还有一类比较重要的内容就是菜单相关组件,可以通过菜单相关组件很方便的使用特定的功能,在AWT中,菜单组件的使用和之前学习的组件时一模一样的,只需要把菜单条、菜单、菜单项组合在一起,按照一定的布局,放入到容器中即可。
菜单组件名称 | 功能 |
MenuBar | 菜单条,菜单的容器 |
Menu | 菜单组件,菜单项的容器。它也是MenuItem的子类,所以可作为菜单项使用 |
PopupMenu | 菜单项组件 |
MenuItem | 菜单项组件 |
CheckboxMenuItem | 复选框菜单项组件 |
菜单相关组件使用:
1、准备菜单项组件,这些组件可以是MenuItem及子类对象
2、准备菜单组件Menu或者PopupMenu(右击弹出子菜单),把第一步中准备好的菜单项组件添加进来
3、准备菜单条组件MenuBar,把第二步准备好的菜单组件Menu添加进来
4、把第三步中准备好的菜单条组件添加到窗口对象中显示
小技巧:
1、如果要在某个菜单的菜单项之间添加分割线,那么只需要调用Menu的add(new MenuItem("-"))即可。
2、如果要给某个菜单项关联快捷键功能,那么只需要在创建菜单项对象设置即可,例如给菜单项关联ctrl+shift+Q快捷键,只需要:new MenuItem("菜单项名字",new MenuShortcut(KeyEvent.VK_Q,true);
案例一:如何做出下图呢?
------->
------->
public class day18 {//创建窗口private Frame frame = new Frame();//创建菜单条MenuBar menuBar = new MenuBar();//创建菜单组件Menu fileMenu = new Menu("文件");Menu editMenu = new Menu("编辑");Menu formatMenu = new Menu("格式");//菜单项组件MenuItem auto = new MenuItem("菜单换行");MenuItem copy = new MenuItem("复制");MenuItem paste = new MenuItem("粘贴");//关联快捷键MenuItem comment = new MenuItem("注释", new MenuShortcut(KeyEvent.VK_Q, true));MenuItem canceComment = new MenuItem("取消注释");TextArea ta = new TextArea(6,40);public void init() {//组装视图comment.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//在监听器下e.getActionCommand()点击后最后都返回注释功能ta.append("您点击菜单项:" + e.getActionCommand()+"\n");}});formatMenu.add(comment);formatMenu.add(canceComment);//组装编辑菜单editMenu.add(auto);editMenu.add(copy);editMenu.add(paste);editMenu.add(formatMenu);//组装菜单条menuBar.add(fileMenu);menuBar.add(editMenu);//把菜单条放入到Frame中frame.setMenuBar(menuBar);frame.add(ta);//设置frame最佳大小frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day18().init();
案例二:通过PopupMenu实现下图效果
实现思路:
1、创建PopupMenu菜单组件
2、创建多个MenuItem菜单项,并添加到PopupMenu中
3、将PopupMenu添加到目标组件中
4、为需要右击出现PopupMenu菜单的组件,注册鼠标监听事件,当监听到用户释放右键时,弹出菜单。
public class day19 {private Frame frame=new Frame("这里测试PopupMenu");//创建文本域TextArea ta=new TextArea("我爱中华",6,40);//创建Panel容器Panel p=new Panel();//创建PopupMenuPopupMenu popupMenu=new PopupMenu();//创建菜单项MenuItem comment=new MenuItem("注释");MenuItem cancalcomment=new MenuItem("取消注释");MenuItem copy=new MenuItem("复制");MenuItem save=new MenuItem("保存");public void init(){//组装视图ActionListener listener=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String actionCommand = e.getActionCommand();ta.append("您点击了右键:"+actionCommand+"\n");}};//传入监听器comment.addActionListener(listener);cancalcomment.addActionListener(listener);copy.addActionListener(listener);save.addActionListener(listener);//将功能放到popupMenu当中去popupMenu.add(comment);popupMenu.add(cancalcomment);popupMenu.add(copy);popupMenu.add(save);//将popupMenu放到面板中Panel中去p.add(popupMenu);//设置Panel的大小p.setPreferredSize(new Dimension(40,100));//给Panel注册鼠标事件,监听用户释放鼠标的动作,展示菜单p.addMouseListener(new MouseAdapter() {@Overridepublic void mouseReleased(MouseEvent e) {//isPopupTrigger()用来判断是否为鼠标右键点击boolean flag = e.isPopupTrigger();if(flag){//显示popupMenupopupMenu.show(p,e.getX(),e.getY());}}});frame.add(ta);frame.add(p,BorderLayout.SOUTH);//设置frame最佳大小,并可视化frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day19().init();}
}
Study17(绘图)
很多程序如各种游戏需要在窗口中绘制各种图形,除此之外,及时要开发JavaEE项目时,有时候也必须"动态"地向客户端生成各种图形、图标,比如:图形验证码、统计图等,这都需要利用AWT地绘图功能。
组件绘图原理:
之前我们已经学习很多组件,如:Button、Frame、Checkbox等等,不同的组件,展示出来的图形都不一样,其实这些组件展示出来的图形,其本质就是用AWT的绘图完成。
在AWT中,真正提供绘图功能的是Graphics对象,那么Component组件和Graphics对象存在什么关系,才能让Component绘制呢?在Component类中,提供了下列三个方法来完成组件图案的绘制于刷新;
paint(Graphics g):绘制组件的外观;
update(Graphics g):内部调用paint方法,刷新组件外观;
repaint():调用update方法,刷新组件外观;
一般情况下,update和paint方法是由AWT系统负责调用,如果程序要希望系统重新绘制组件,可以调用repaint方法完成。
1、Graphics对象的使用
实际生活中如果需要画图,首先我们得准备一张纸,然后在拿一支笔,配和一些颜色,就可以在纸上画出来各种各样的图形,例如:圆形、矩形等等。
程序绘图也一样,也需要画布,画笔,颜料等等。AWT中提供了Canvas类充当画布,提供Graphics类来充当画笔,通过调用Graphics对象的setColor()方法可以给画笔设置颜色。
2、画图的步骤
1.自定义类,继承Canvas类,重写paint(Graphics g)方法完成画图。
2.在paint方法内部,真正开始画图之前调用Graphics对象的setColor()、setFont()等方法设置画笔的颜色,字体等属性;
3.调用Graphics画笔的drawXxx()方法开始画图。
其实画图的核心就在使用Graphics画笔在Canvas画布上画出什么颜色、什么样式的图形,什么样式的图形,所以核心在画笔上,下表中列出了Graphics类中常用的一些方法:
方法名称 | 方法功能 |
setColor(Color c) | 设置颜色 |
setFont(Font font) | 设置字体 |
drawLine() | 绘制直线 |
drawRect() | 绘制矩形 |
drawRoundRect() | 绘制圆角矩形 |
drawOval() | 绘制椭圆形 |
drawPolygon() | 绘制多边形 |
drawArc() | 绘制圆弧 |
drawPolyline | 绘制折线 |
fileRect() | 填充圆角矩形区域 |
fillRoundRect() | 填充圆角矩形区域 |
fillOval() |
填充椭圆区域 |
fillPolygon() | 填充多边形区域 |
fillArc() | 填充圆弧对应的扇形区域 |
drawImage() | 绘制位图 |
3、案例一:按钮点击成图像
------>
------>
------>
public class day20 {//定义一个RECT_SHAPE以及OVAL_SHAPE当点击按钮的时候监听器打开,将二者分别进行赋值操作private final String RECT_SHAPE = "reat";private final String OVAL_SHAPE = "oval";private Frame frame = new Frame("测试绘图");Button butreat = new Button("绘制矩形");Button butoval = new Button("绘制椭圆");//定义一个变量,记录当前要绘制椭圆还是矩形private String shape = "";//1、自定义类,继承Canvas,重写paint(Graphics g)方法完成画图;private class Mycnvas extends Canvas {@Overridepublic void paint(Graphics g) {//绘制不同的图形if (shape.equals(RECT_SHAPE)) {//绘制矩形g.setColor(Color.BLACK);//设置当前画笔的颜色g.drawRect(100, 100, 150, 100);} else if (shape.equals(OVAL_SHAPE)) {//绘制椭圆g.setColor(Color.RED);g.drawOval(100, 100, 150, 100);}}}//创建自定义的画布对象Mycnvas drawArea = new Mycnvas();public void init() {//当我点击绘制矩形的时候,就会执行监听器代码butreat.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//将定义的RECT_SHAPE赋值给shapeshape = RECT_SHAPE;//并且在画布中repaint()drawArea.repaint();}});//当我点击绘制椭圆的时候,就会执行监听器代码butoval.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//将定义的OVAL_SHAPE赋值给shapeshape = OVAL_SHAPE;drawArea.repaint();}});//创建Panel,承载按钮Panel p = new Panel();p.add(butoval);p.add(butreat);frame.add(p, BorderLayout.SOUTH);//drawArea的大小需要设置drawArea.setPreferredSize(new Dimension(300, 300));frame.add(drawArea);//frame自适应frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day20().init();}
}
4、案例二:弹射小球 (非常有意思,建议自己手动敲一遍理解原理)
Java也可以用来开发一些动画。所谓动画,就是间隔一定的时间(通常小于0.1秒)重新绘制的图形,两次绘制的图像之间差异比较小,肉眼看起来就成为所谓的动画。
为了实现间隔一定的时间就重新调用组件的repain方法,可以借助Swing提供的Timer类,Timer类是一个定时器,它有如下一个构造器:
Timer(int delay,ActionListener):每间隔delay毫秒,系统自动触发ActionLinster监听器的事件处理器的方法,在方法内部我们就可以调用组件的repaint方法,完成组件重新绘制。
----->
----->
package javaswing;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class day21 {private Frame frame = new Frame("弹球游戏");//设置桌面宽度private final int TABLE_WIDTH = 300;//设置桌面高度private final int TABLE_HEIGHT = 400;//球拍的高度和宽度private final int RACKET_WIDTH = 60;private final int RACKET_HEIGHT = 20;//小球的大小private final int BALL_SIZE = 16;//定义变量,记录小球的坐标private int ballX = 120;private int ballY = 20;//定义变量,记录小球在x和y方向上分别移动的速度private int speedY = 10;private int speedX = 5;//定义变量,记录球拍的坐标private int racketX = 120;private final int racketY = 340;//y坐标固定不变的,只会在左右移动//定义变量,标识当前游戏是否结束private boolean isOver = false;//声明一个定时器private Timer timer;//自定义一个类,继承canvas,充当画布private class Mycanvas extends Canvas {//记得重写paint@Overridepublic void paint(Graphics g) {//TODO 在这里绘制内容if (isOver) {//游戏结束的内容g.setColor(Color.RED);g.setFont(new Font("Times", Font.BOLD, 30));g.drawString("游戏结束!", 50, 200);} else {//游戏进行的内容//绘制小球g.setColor(Color.BLUE);g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);//绘制球拍g.setColor(Color.PINK);g.fillRect(racketX, racketY, RACKET_WIDTH, RACKET_HEIGHT);}}}//创建绘画区域Mycanvas drawArea = new Mycanvas();//组件组装方法public void init() {//组装视图,以及游戏逻辑的控制//----->球拍的控制逻辑//----->小球的控制逻辑//完成球拍坐标的变化(创建监听器)(按键事件)(键盘事件)KeyListener listener = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//获取当前按下的键int keyCode = e.getKeyCode();//我们的键盘每一个键位都对应一个整数keycodeif (keyCode == KeyEvent.VK_LEFT) {//应该向左移动if (racketX > 0) {racketX -= 10;}}if (keyCode == KeyEvent.VK_RIGHT) {//应该向右移动if (racketX < (TABLE_WIDTH - RACKET_WIDTH)) {racketX += 10;}}}};//给frame和drawArea注册监听器frame.addKeyListener(listener);drawArea.addKeyListener(listener);//小球坐标的控制ActionListener task = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//更新小球的坐标,重绘界面//根据边界范围,修正速度//----->修正x轴弹出碰到边界的方向if (ballX <= 0 || ballX >= (TABLE_WIDTH - BALL_SIZE)) {speedX = -speedX;}//----->修正y轴弹出碰到边界的方向if (ballY <= 0 || ballY > racketY - BALL_SIZE && ballX > racketX && ballX < racketX + RACKET_WIDTH) {speedY = -speedY;}//----->超出球拍往下,游戏结束if (ballY > racketY - BALL_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)) {//当前小球超出了球拍范围//停止定时器timer.stop();//修改游戏是否结束标记isOver = true;//重新绘制界面drawArea.repaint();}ballX += speedX;ballY += speedY;//重新绘制界面drawArea.repaint();}};//这里需要手动导包import javax.swing.Timer.*;timer = new Timer(100, task);timer.start();drawArea.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));frame.add(drawArea);//frame窗口关闭frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});//frame最佳大小frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day21().init();}
Study18(处理位图)
如果仅仅绘制一些简单的几何图形,程序的图形依旧十分简单。AWT允许在组件上绘制位图,Graphics提供了drawmage(Image image)方法用于绘制位图,该方法需要一个Image参数一一代表位图,通过该方法就可以绘制出指定的位图。
位图使用步骤:
1、创建Image的子类对象BufferedImage(int width,int heigth,int ImageType),创建时需要指定位图的宽高及类型属性;此时相当于在内存中生成了一张图片;
2、调用BufferedImage对象的getGraphics()方法获取画笔,此时就可以往内存中的这张图片上绘图了,绘图的方法和之前学习的一样。
3、调用组件paint()方法中提供的Graphics对象的drawImage()方法,一次性的内存中的图片BufferedImage绘制到待定的组件上。
使用位图绘制组件的好处:
使用位图来绘制组件,相当于实现了图的缓冲区,此时绘图时没有直接把图形绘制到组件上,而是先绘制到内存中的BufferedImage上,等全部绘制完成后,再一次性的图像显示到组件上即可,这样用户的体验会好很多。
案例:
绘画不精,望谅解,重点是:
drawArea.addMouseMotionListener与drawArea.addMouseListener的区别,我就是在这里踩坑的。
drawArea.addMouseMotionListener指的是按下鼠标移动的
drawArea.addMouseListener值的是不移动鼠标的
public class day22 {private Frame frame = new Frame("简单绘图工具");//定义画图区域的宽高private final int AREA_WIDTH = 500;private final int AREA_HEIGHT = 400;//定义一个右键菜单,用于设置画笔的颜色,PopupMenu为鼠标右击private PopupMenu colorMenu = new PopupMenu();private MenuItem reditem = new MenuItem("红色");private MenuItem buleitem = new MenuItem("蓝色");private MenuItem greenitem = new MenuItem("绿色");//定义一个变量记录当前画笔的颜色private Color forceColor = Color.BLACK;//创建一个BufferImage位图对象BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);//通过位图,获取关联的Graphics对象Graphics g = image.getGraphics();//自定义一个类,继承Canvasprivate class MyCanvas extends Canvas {@Overridepublic void paint(Graphics g) {g.drawImage(image, 0, 0, null);}}//取自定义类中对象drawArea绘图区域MyCanvas drawArea = new MyCanvas();//定义一个变量,记录鼠标在拖动过程中上一次所处的坐标private int preX = -1;private int preY = -1;//组装方法public void init() {//组装视图,逻辑控制ActionListener actionListener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//e.getActionCommand()获取的是new MenuItem("红色")中的“红色”String actionCommand = e.getActionCommand();switch (actionCommand) {case "红色":forceColor = Color.RED;break;case "蓝色":forceColor = Color.BLUE;break;case "绿色":forceColor = Color.GREEN;break;}}};//将按钮添加监听器并使之进行监听reditem.addActionListener(actionListener);buleitem.addActionListener(actionListener);greenitem.addActionListener(actionListener);//colorMenucolorMenu.add(reditem);colorMenu.add(buleitem);colorMenu.add(greenitem);//把colorMenu放在绘图区域drawArea.add(colorMenu);drawArea.addMouseListener(new MouseAdapter() {@Overridepublic void mouseReleased(MouseEvent e) {//当鼠标抬起时被调用boolean popupTrigger = e.isPopupTrigger();if (popupTrigger) {//将colorMenu在drawArea展现出来,鼠标点击的x与y轴位置colorMenu.show(drawArea, e.getX(), e.getY());}}});//设置位图背景为白色g.setColor(Color.white);g.fillRect(0, 0, AREA_WIDTH, AREA_HEIGHT);//通过监听鼠标的移动,完成线条绘制drawArea.addMouseMotionListener(new MouseMotionAdapter() {@Overridepublic void mouseDragged(MouseEvent e) {if (preX != -1 && preY != -1) {g.setColor(forceColor);//画线条,需要两组坐标,分别代表起点与终点,e.getX(),e.getY()可以获取坐标g.drawLine(preX, preY, e.getX(), e.getY());}//修正preX与preY的值preX = e.getX();preY = e.getY();//重绘组件drawArea.repaint();}});drawArea.addMouseListener(new MouseAdapter() {@Overridepublic void mouseReleased(MouseEvent e) {//重置preX和preYpreX = -1;preY = -1;}});//将绘画区域设置为最合适的区域drawArea.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));frame.add(drawArea);//设置frame最佳大小并可见frame.pack();frame.setVisible(true);}public static void main(String[] args) {new day22().init();}
}
Study19 ImageIO的使用
在实际生活中,很多软件都支持打开本地磁盘已经存在的图片进行编辑,编辑完毕后,再重新保存到本地磁盘。如果使用AWT要完成这样的功能,那么需要使用到ImageIO类,可以操作本地磁盘的图片文件。
方法名称 | 方法功能 |
static BufferedImage read(File input) | 读取本地磁盘图片文件 |
static BufferedImage read(InputStream input) | 读取本地磁盘图片文件 |
static boolean write(RenderedImage im,String formatName,File output) | 往本地磁盘中输出图片文件 |
案例一:制作图片查看器
package javaswing;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;public class day23 {private Frame frame = new Frame("图片查看器");//创建菜单条MenuBar menuBar = new MenuBar();//创建菜单Menu menu = new Menu("文件");//创建菜单中的菜单名MenuItem open = new MenuItem("打开");MenuItem save = new MenuItem("另存为");//声明BufferImage对象,记录本地存取到内存的图片,到最后读入文件,直接赋值给imageBufferedImage image;private class MyCanvas extends Canvas {@Overridepublic void paint(Graphics g) {g.drawImage(image, 0, 0, null);}}MyCanvas drawArea = new MyCanvas();public void init() {//组装视图open.addActionListener(e -> {//打开一个文件对话框FileDialog fileDialog = new FileDialog(frame, "打开图片", FileDialog.LOAD);fileDialog.setVisible(true);//获取用户选择的图片路径以及名称String dir = fileDialog.getDirectory();String fileName = fileDialog.getFile();try {//记得这里要写IO读入的文件,并且赋值给imageimage = ImageIO.read(new File(dir, fileName));drawArea.repaint();} catch (IOException ex) {ex.printStackTrace();}});save.addActionListener(e -> {//获取用户设置的保存路径以及文件名称FileDialog fileDialog = new FileDialog(frame, "保存图片", FileDialog.SAVE);fileDialog.setVisible(true);//展示用户设置的保存路径以及文件名称String dir = fileDialog.getDirectory();String fileName = fileDialog.getFile();try {//注意这里要写写”JPEG“,文件格式名ImageIO.write(image, "JPEG", new File(dir, fileName));} catch (IOException ex) {ex.printStackTrace();}});//将打开文件以及保存文件放到menu组件中menu.add(open);menu.add(save);//将menu组件放在菜单栏中menuBar.add(menu);//把菜单条放在窗口中frame.setMenuBar(menuBar);frame.add(drawArea);//自定义frame的框架,并且可见frame.setBounds(200, 200, 740, 508);frame.setVisible(true);frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}public static void main(String[] args) {new day23().init();}
}
黑马程序员Java Swing笔记分享(AWT篇)相关推荐
- 黑马程序员---微服务笔记【实用篇】
微服务技术栈导学 微服务实现流程: 所有要学的技术: 分层次教学: 具体分层: 实用篇---第一天 一.认识微服务 单体架构 将业务所有功能集中在一个项目中开发,打成一个包部署 优点:架构简单.部署成 ...
- day30 | 黑马程序员Java全程笔记 | 第二阶段MySQL高级 JDBC
01.反馈回顾 事务: ★ 概述: 逻辑上的一组操作,组成这组操作的各个单元要么同时成功,要么同时失败. 事务是一个最小的执行单元. mysql中的事务控制: 手动事务: 需要手动开启,提交,回滚开启 ...
- 黑马程序员——java要点笔记——正则表达式
------- android培训.java培训.期待与您交流! ---------- 正则表达式 day28 01-正则表达式(概述) 1.正则表达式:正确的规则.它的体现,是表达式. 2.正则表达 ...
- day29 | 黑马程序员Java全程笔记 | 第二阶段MySQL高级事务-索引-视图-触发器-存储过程
目录 01.反馈 02.回顾 03.并发访问MySQL-问题概述 并发访问的问题 04.并发访问MySQL-问题演示 05.并发访问MySQL-read-committed解决脏读问题 06.并发访问 ...
- 黑马程序员Maven学习笔记
前言 这里是黑马程序员Maven学习笔记分享,这是视频链接. 我还有其它前端内容的笔记,有需要可以查看. 文章目录 前言 基础 Maven简介 Maven是什么 Maven的作用 Maven的下载 M ...
- 黑马程序员Java教程学习笔记(五)
学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...
- 黑马程序员Java教程学习笔记(三)
学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(三) 面向对象:设计对象.注意事 ...
- 2023年黑马程序员Java学习路线图
2023年Java学科免费学习资源放送40+套课程,超过600小时的内容! 在过去的一年里,为了帮助更多人线上充电,学会更多技能,黑马程序员举办了 150+ 场免费直播公开课,新增精品视频教程 80+ ...
- 黑马程序员 JAVA WEB 第三节 MYSQL 约束
这是阿锃总结的第三节黑马程序员JAVA WEB视频的MYSQL约束部分的笔记.希望可以帮助跟我一样正在学习Java web的同学们.我们一起进步. b_d 若果有同学也想学习黑马程序员Java w ...
最新文章
- 计算机网络_NAT与NAPT
- 同行评审以权谋私,让投稿人多引用自己文章,爱思唯尔将彻查此事
- NOIP2015 D1 解题报告
- 遍历文件夹下所有文件和文件夹
- Java虚拟机(JVM)概念简介
- iOS重写和成员变量访问权限
- 修改 timezone
- Git 与 Github 基础(二)—— Git for Windows
- scala yield入门详解
- COCOS2D-X 不反复随机数
- Linux服务器SMB服务挂载目录
- 智慧交通day02-车流量检测实现13:基于虚拟线圈法的车辆统计+视频中的车流量统计原理解析
- 浏览器地址栏和标题栏显示的小图标
- 罗马数字序号与word2013中如何插入
- quartz表删除顺序
- 如何看待腾讯市值(按 2012 年 8 月 17 日股价)超过 Facebook?
- Mac 显示/不显示隐藏文件
- 双ip的oracle集群该怎么连接,如何配置电信联通双线双IP接入
- 微信小程序无法看视频
- vue项目网站ico图标设置
热门文章
- python中opener_Python request.build_opener方法代码示例
- 悄悄是别离的笙箫,夏虫也为我沉默
- 吴昊品游戏核心算法 Round 17 —— 吴昊教你玩拼图游戏(8 puzzle)
- IC设计、制造、封测,看这篇就够了(转载)
- 怎么区分辨别狗狗是否哮喘?
- 【概率论】伽马分布的期望与方差
- python-字符串的模板替换 Template.substitute()
- 浙大2020年Mooc数据结构笔记--第三讲 树(下)
- 2021海口市华侨中学高考成绩查询,2021海口高中排名前十
- OneData方法论-维度表设计