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对象,并且设置他的布局管理器为GridLayout Panel 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() { @Override public 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对象设置给Frame frame.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容器 vBox Box 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() { @Override public void actionPerformed(ActionEvent e) { d1.setVisible(true); } }); b2.addActionListener(new ActionListener() { @Override public 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() { @Override public 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() { @Override public 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() { @Override public 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上发生了事件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() { @Override public 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() { @Override public void textValueChanged(TextEvent e) { String text = tf.getText(); System.out.println("当前文本的内容为:"+text); } }); //给下拉选择框添加ItemListener,监听条目选项的变化 names.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { Object item = e.getItem(); System.out.println("当前选中的条目为:"+item); } }); //给frame注册ContainerListener监听器,监听容器组件的添加 frame.addContainerListener(new ContainerListener() { @Override public void componentAdded(ContainerEvent e) {//添加方法 Component child = e.getChild(); System.out.println("frame中添加了:"+child); } @Override public 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() { @Override public 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() { @Override public 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(); //创建PopupMenu PopupMenu 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() { @Override public 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() { @Override public void mouseReleased(MouseEvent e) { //isPopupTrigger()用来判断是否为鼠标右键点击 boolean flag = e.isPopupTrigger(); if(flag){ //显示popupMenu popupMenu.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 { @Override public 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() { @Override public void actionPerformed(ActionEvent e) { //将定义的RECT_SHAPE赋值给shape shape = RECT_SHAPE; //并且在画布中repaint() drawArea.repaint(); } }); //当我点击绘制椭圆的时候,就会执行监听器代码 butoval.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //将定义的OVAL_SHAPE赋值给shape shape = 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 @Override public 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() { @Override public void keyPressed(KeyEvent e) { //获取当前按下的键 int keyCode = e.getKeyCode();//我们的键盘每一个键位都对应一个整数keycode if (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() { @Override public 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() { @Override public 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(); //自定义一个类,继承Canvas private class MyCanvas extends Canvas { @Override public 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() { @Override public 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); //colorMenu colorMenu.add(reditem); colorMenu.add(buleitem); colorMenu.add(greenitem); //把colorMenu放在绘图区域 drawArea.add(colorMenu); drawArea.addMouseListener(new MouseAdapter() { @Override public 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() { @Override public 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() { @Override public void mouseReleased(MouseEvent e) { //重置preX和preY preX = -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对象,记录本地存取到内存的图片,到最后读入文件,直接赋值给image BufferedImage image; private class MyCanvas extends Canvas { @Override public 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读入的文件,并且赋值给image image = 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() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } public static void main(String[] args) { new day23().init(); } }说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。
Java真的没有发展吗
学习Java并非真的没有退路,相反,如果将Java与现在热门的大模型结合会碰撞出不一样的火花
大模型技术正在为Java开发者开辟新赛道
1、推理环节的核心语言
- 大模型训练依赖Python生态的高性能计算资源,但推理阶段更注重模型部署、性能优化和系统集成。Java凭借其稳定性、跨平台特性和生态优势,成为推理环节的理想选择。例如,通过DJL(Deep Java Library)直接加载和使用预训练模型,无需深入底层Python代码。
2、工程化落地的关键角色
- 大模型从实验室到产业级应用的过程中,工程化能力成为核心竞争力。Java开发者在代码规范、测试流程、版本管理等方面的积累,能大幅降低大模型项目的研发成本。例如,利用Spring Cloud Gateway实现大模型调用的网关,进行请求限流、熔断降级和日志追踪。
3、多场景应用的桥梁
- Java在大模型工程化中承担关键职责:
- 数据处理层:通过Apache PDFBox、Spring Batch等工具解析非结构化数据,实现知识库的向量化处理。
- 检索服务层:调用大模型的Embedding API生成向量数据,并通过向量数据库(如Milvus)进行相似度匹配。
- 模型调用层:通过适配器模式封装不同大模型的调用接口,实现“一键切换”。
应用服务层:基于Spring Boot构建RESTful API,灵活编排“检索-生成”链路。
因此捕获AI,掌握技术是关键,让AI成为我们最便利的工具.
一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。
即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!
如何学习AGI大模型?
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享**
一、2025最新大模型学习路线
一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。
我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。
L1级别:AI大模型时代的华丽登场
L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。
L2级别:AI大模型RAG应用开发工程
L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。
L3级别:大模型Agent应用架构进阶实践
L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。
L4级别:大模型微调与私有化部署
L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。
整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。
二、大模型经典PDF书籍
书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)
三、大模型视频教程
对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。
四、大模型项目实战
学以致用,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。
五、大模型面试题
面试不仅是技术的较量,更需要充分的准备。
在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享