java必學(xué)必會(huì)之GUI編程
一、事件監(jiān)聽(tīng)

測(cè)試代碼一:
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestTextField {
public static void main(String args[]) {
new MyFrameTextField();
}
}
class MyFrameTextField extends Frame {
MyFrameTextField() {
TextField tf = new TextField();
add(tf);
tf.addActionListener(new Monitor3());
tf.setEchoChar('*');
/*
* 這個(gè)setEchoChar()方法是設(shè)置文本框輸入時(shí)顯示的字符,這里設(shè)置為*,
* 這樣輸入任何內(nèi)容就都以*顯示出來(lái),不過(guò)打印出來(lái)時(shí)依然可以看到輸入的內(nèi)容
*/
setVisible(true);
pack();
}
}
class Monitor3 implements ActionListener {
/*
* 接口里面的所有方法都是public(公共的)
* 所以從API文檔復(fù)制void actionPerformed(ActionEvent e)時(shí) 要在void前面加上public
*/
public void actionPerformed(ActionEvent e) {
/* 事件的相關(guān)信息都封裝在了對(duì)象e里面,通過(guò)對(duì)象e的相關(guān)方法就可以獲取事件的相關(guān)信息 */
TextField tf = (TextField) e.getSource();
/*
* getSource()方法是拿到事件源,注意:拿到這個(gè)事件源的時(shí)候,
* 是把它當(dāng)作TextField的父類來(lái)對(duì)待
* getSource()方法的定義是:“public Object getSource()”返回值是一個(gè)Object對(duì)象,
* 所以要強(qiáng)制轉(zhuǎn)換成TextField類型的對(duì)象
* 在一個(gè)類里面想訪問(wèn)另外一個(gè)類的事件源對(duì)象可以通過(guò)getSource()方法
*/
System.out.println(tf.getText());// tf.getText()是取得文本框里面的內(nèi)容
tf.setText("");// 把文本框里面的內(nèi)容清空
}
}
測(cè)試代碼二:
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestActionEvent2{
public static void main(String args[]){
Frame f = new Frame("TestActionEvent");
Button btn1 = new Button("start");
Button btn2 = new Button("stop");
Monitor2 m2 = new Monitor2();//創(chuàng)建監(jiān)聽(tīng)對(duì)象
btn1.addActionListener(m2);
/*一個(gè)監(jiān)聽(tīng)對(duì)象同時(shí)監(jiān)聽(tīng)兩個(gè)按鈕的動(dòng)作*/
btn2.addActionListener(m2);
btn2.setActionCommand("GameOver");//設(shè)置btn2的執(zhí)行單擊命令后的返回信息
f.add(btn1,BorderLayout.NORTH);
f.add(btn2,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}
class Monitor2 implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.println("a button has been pressed,"+"the relative info is:\n"+e.getActionCommand());
/*使用返回的監(jiān)聽(tīng)對(duì)象e調(diào)用getActionCommand()方法獲取兩個(gè)按鈕執(zhí)行單擊命令后的返回信息
根據(jù)返回信息的不同區(qū)分開(kāi)當(dāng)前操作的是哪一個(gè)按鈕,btn1沒(méi)有使用setActionCommand()方法設(shè)置
則btn1返回的信息就是按鈕上顯示的文本*/
}
}
二、TextField事件監(jiān)聽(tīng)

測(cè)試代碼:
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestTextField {
public static void main(String args[]) {
new MyFrameTextField();
}
}
class MyFrameTextField extends Frame {
MyFrameTextField() {
TextField tf = new TextField();
add(tf);
tf.addActionListener(new Monitor3());
tf.setEchoChar('*');
/*
* 這個(gè)setEchoChar()方法是設(shè)置文本框輸入時(shí)顯示的字符,這里設(shè)置為*,
* 這樣輸入任何內(nèi)容就都以*顯示出來(lái),不過(guò)打印出來(lái)時(shí)依然可以看到輸入的內(nèi)容
*/
setVisible(true);
pack();
}
}
class Monitor3 implements ActionListener {
/*
* 接口里面的所有方法都是public(公共的)
* 所以從API文檔復(fù)制void actionPerformed(ActionEvent e)時(shí) 要在void前面加上public
*/
public void actionPerformed(ActionEvent e) {
/* 事件的相關(guān)信息都封裝在了對(duì)象e里面,通過(guò)對(duì)象e的相關(guān)方法就可以獲取事件的相關(guān)信息 */
TextField tf = (TextField) e.getSource();
/*
* getSource()方法是拿到事件源,注意:拿到這個(gè)事件源的時(shí)候,
* 是把它當(dāng)作TextField的父類來(lái)對(duì)待
* getSource()方法的定義是:“public Object getSource()”返回值是一個(gè)Object對(duì)象,
* 所以要強(qiáng)制轉(zhuǎn)換成TextField類型的對(duì)象
* 在一個(gè)類里面想訪問(wèn)另外一個(gè)類的事件源對(duì)象可以通過(guò)getSource()方法
*/
System.out.println(tf.getText());// tf.getText()是取得文本框里面的內(nèi)容
tf.setText("");// 把文本框里面的內(nèi)容清空
}
}
使用TextField類實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestMath {
public static void main(String args[]) {
new TFFrame();
}
}
/* 這里主要是完成計(jì)算器元素的布局 */
class TFFrame extends Frame {
TFFrame() {
/*
* 創(chuàng)建3個(gè)文本框,并指定其初始大小分別為10個(gè)字符和15個(gè)字符的大小 這里使用的是TextField類的另外一種構(gòu)造方法 public TextField(int columns)
*/
TextField num1 = new TextField(10);
TextField num2 = new TextField(10);
TextField num3 = new TextField(15);
/* 創(chuàng)建等號(hào)按鈕 */
Button btnEqual = new Button("=");
btnEqual.addActionListener(new MyMonitor(num1, num2, num3));
/* 給等號(hào)按鈕加上監(jiān)聽(tīng),讓點(diǎn)擊按鈕后有響應(yīng)事件發(fā)生 */
Label lblPlus = new Label("+");
/* “+”是一個(gè)靜態(tài)文本,所以使用Label類創(chuàng)建一個(gè)靜態(tài)文本對(duì)象 */
setLayout(new FlowLayout());
/* 把Frame默認(rèn)的BorderLayout布局改成FlowLayout布局 */
add(num1);
add(lblPlus);
add(num2);
add(btnEqual);
add(num3);
pack();
setVisible(true);
}
}
class MyMonitor implements ActionListener {
TextField num1, num2, num3;
/*
* 為了使對(duì)按鈕的監(jiān)聽(tīng)能夠?qū)ξ谋究蛞财鹱饔茫?
* 所以在自定義類MyMonitor里面定義三個(gè)TextField類型的對(duì)象 num1,num2,num3,
* 并且定義了MyMonitor類的一個(gè)構(gòu)造方法 這個(gè)構(gòu)造方法帶有三個(gè)TextField類型的參數(shù),
* 用于接收 從TFFrame類里面?zhèn)鬟f過(guò)來(lái)的三個(gè)TextField類型的參數(shù)
* 然后把接收到的三個(gè)TextField類型的參數(shù)賦值給在本類中聲明的 三個(gè)TextField類型的參數(shù)num1,num2,num3 然后再在actionPerformed()方法里面處理num1,num2,num3
*/
public MyMonitor(TextField num1, TextField num2, TextField num3) {
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
}
public void actionPerformed(ActionEvent e) {
/* 事件的相關(guān)信息都封裝在了對(duì)象e里面,通過(guò)對(duì)象e的相關(guān)方法就可以獲取事件的相關(guān)信息 */
int n1 = Integer.parseInt(num1.getText());/* num1對(duì)象調(diào)用getText()方法取得自己顯示的文本字符串 */
int n2 = Integer.parseInt(num2.getText());/* num2對(duì)象調(diào)用getText()方法取得自己顯示的文本字符串 */
num3.setText("" + (n1 + n2));/* num3對(duì)象調(diào)用setText()方法設(shè)置自己的顯示文本 */
num1.setText("");
/* 計(jì)算結(jié)束后清空num1,num2文本框里面的內(nèi)容 */
num2.setText("");
// num3.setText(String.valueOf((n1+n2)));
/* 字符串與任意類型的數(shù)據(jù)使用“+”連接時(shí)得到的一定是字符串,
* 這里使用一個(gè)空字符串與int類型的數(shù)連接,這樣就可以直接把(n1+n2)得到的int類型的數(shù)隱式地轉(zhuǎn)換成字符串了,
* 這是一種把別的基礎(chǔ)數(shù)據(jù)類型轉(zhuǎn)換成字符串的一個(gè)小技巧。
* 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和轉(zhuǎn)換成字符串
*/
}
}
JAVA里面的經(jīng)典用法:在一個(gè)類里面持有另外一個(gè)類的引用
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestMath1 {
public static void main(String args[]) {
new TTMyFrame().launchFrame();
/* 創(chuàng)建出TTMyFrame對(duì)象后調(diào)用lauchFrame()方法把計(jì)算器窗體顯示出來(lái) */
}
}
/* 做好計(jì)算器的窗體界面 */
class TTMyFrame extends Frame {
/* 把設(shè)計(jì)計(jì)算器窗體的代碼封裝成一個(gè)方法 */
TextField num1, num2, num3;
public void launchFrame() {
num1 = new TextField(10);
num2 = new TextField(15);
num3 = new TextField(15);
Label lblPlus = new Label("+");
Button btnEqual = new Button("=");
btnEqual.addActionListener(new MyMonitorbtnEqual(this));
setLayout(new FlowLayout());
add(num1);
add(lblPlus);
add(num2);
add(btnEqual);
add(num3);
pack();
setVisible(true);
}
}
/*
* 這里通過(guò)取得TTMyFrame類的引用,然后使用這個(gè)引用去訪問(wèn)TTMyFrame類里面的成員變量
* 這種做法比上一種直接去訪問(wèn)TTMyFrame類里面的成員變量要好得多,
* 因?yàn)楝F(xiàn)在不需要知道 TTMyFrame類里面有哪些成員變量了,
* 現(xiàn)在要訪問(wèn)TTMyFrame類里面的成員變量,直接使用 TTMyFrame類對(duì)象的引用去訪問(wèn)即可,
* 這個(gè)TTMyFrame類的對(duì)象好比是一個(gè)大管家, 而我告訴大管家,我要訪問(wèn)TTMyFrame類里面的那些成員變量,
* 大管家的引用就會(huì)去幫我找,不再需要我自己去找了。
* 這種在一個(gè)類里面持有另一個(gè)類的引用的用法是一種非常典型的用法
* 使用獲取到的引用就可以在一個(gè)類里面訪問(wèn)另一個(gè)類的所有成員了
*/
class MyMonitorbtnEqual implements ActionListener {
TTMyFrame ttmf = null;
public MyMonitorbtnEqual(TTMyFrame ttmf) {
this.ttmf = ttmf;
}
public void actionPerformed(ActionEvent e) {
int n1 = Integer.parseInt(ttmf.num1.getText());
int n2 = Integer.parseInt(ttmf.num2.getText());
ttmf.num3.setText("" + (n1 + n2));
ttmf.num1.setText("");
ttmf.num2.setText("");
}
}
運(yùn)行結(jié)果如下:

三、內(nèi)部類

內(nèi)部類的使用范例:
package cn.javastudy.summary;
import java.awt.*;
import java.awt.event.*;
public class TestMath3 {
public static void main(String args[]) {
new MyMathFrame().launchFrame();
}
}
class MyMathFrame extends Frame {
TextField num1, num2, num3;
public void launchFrame() {
num1 = new TextField(10);
num2 = new TextField(15);
num3 = new TextField(15);
Label lblPlus = new Label("+");
Button btnEqual = new Button("=");
btnEqual.addActionListener(new MyMonitor());
setLayout(new FlowLayout());
add(num1);
add(lblPlus);
add(num2);
add(btnEqual);
add(num3);
pack();
setVisible(true);
}
/*
* 這個(gè)MyMonitor類是內(nèi)部類,它在MyFrame類里面定義 MyFrame類稱為MyMonitor類的包裝類
*/
/*
* 使用內(nèi)部類的好處:
* 第一個(gè)巨大的好處就是可以暢通無(wú)阻地訪問(wèn)外部類(即內(nèi)部類的包裝類)的所有成員變量和方法
* 如這里的在MyFrame類(外部類)定義的三個(gè)成員變量num1,num2,num3,
* 在MyMonitor(內(nèi)部類)里面就可以直接訪問(wèn)
* 這相當(dāng)于在創(chuàng)建外部類對(duì)象時(shí)內(nèi)部類對(duì)象默認(rèn)就擁有了一個(gè)外部類對(duì)象的引用
*/
private class MyMonitor implements ActionListener {
public void actionPerformed(ActionEvent e) {
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
num3.setText("" + (n1 + n2));
num1.setText("");
num2.setText("");
}
}
}
內(nèi)部類帶來(lái)的巨大好處是:
- 可以很方便地訪問(wèn)外部類定義的成員變量和方法
- 當(dāng)某一個(gè)類不需要其他類訪問(wèn)的時(shí)候就把這個(gè)類聲明為內(nèi)部類。
四、Graphics 類

測(cè)試代碼:
package cn.javastudy.summary;
import java.awt.*;
public class TestPaint{
public static void main(String args[]){
new MyPaint().launchFrame();
/*在main()方法里面并沒(méi)有顯示調(diào)用paint(Graphics g)方法
可是當(dāng)創(chuàng)建出Frame窗體后卻可以看到Frame窗體上畫(huà)出了
圓和矩形,這是因?yàn)閜aint()方法是一個(gè)比較特殊的方法
在創(chuàng)建Frame窗體時(shí)會(huì)自動(dòng)隱式調(diào)用
當(dāng)我們把Frame窗體最小化又再次打開(kāi)時(shí),又會(huì)再次調(diào)用
paint()方法重新把圓和矩形在Frame窗體上畫(huà)出來(lái)
即每次需要重畫(huà)Frame窗體的時(shí)候就會(huì)自動(dòng)調(diào)用paint()方法*/
}
}
class MyPaint extends Frame{
public void launchFrame(){
setBounds(200,200,640,480);
setVisible(true);
}
public void paint(Graphics g){
/*paint(Graphics g)方法有一個(gè)Graphics類型的參數(shù)g
我們可以把這個(gè)g當(dāng)作是一個(gè)畫(huà)家,這個(gè)畫(huà)家手里拿著一只畫(huà)筆
我們通過(guò)設(shè)置畫(huà)筆的顏色與形狀來(lái)畫(huà)出我們想要的各種各樣的圖像*/
/*設(shè)置畫(huà)筆的顏色*/
g.setColor(Color.red);
g.fillOval(100,100,100,100);/*畫(huà)一個(gè)實(shí)心橢圓*/
g.setColor(Color.green);
g.fillRect(150,200,200,200);/*畫(huà)一個(gè)實(shí)心矩形*/
/*這下面的兩行代碼是為了寫(xiě)程序的良好編程習(xí)慣而寫(xiě)的
前面設(shè)置了畫(huà)筆的顏色,現(xiàn)在就應(yīng)該把畫(huà)筆的初始顏色恢復(fù)過(guò)來(lái)
就相當(dāng)于是畫(huà)家用完畫(huà)筆之后把畫(huà)筆上的顏色清理掉一樣*/
Color c = g.getColor();
g.setColor(c);
}
}
運(yùn)行結(jié)果:

五、鼠標(biāo)事件適配器

測(cè)試代碼:
package cn.galc.test;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class MyMouseAdapter{
public static void main(String args[]) {
new MyFrame("drawing...");
}
}
class MyFrame extends Frame {
ArrayList points = null;
MyFrame(String s) {
super(s);
points = new ArrayList();
setLayout(null);
setBounds(300,300,400,300);
this.setBackground(new Color(204,204,255));
setVisible(true);
this.addMouseListener(new Monitor());
}
public void paint(Graphics g) {
Iterator i = points.iterator();
while(i.hasNext()){
Point p = (Point)i.next();
g.setColor(Color.BLUE);
g.fillOval(p.x,p.y,10,10);
}
}
public void addPoint(Point p){
points.add(p);
}
}
class Monitor extends MouseAdapter {
public void mousePressed(MouseEvent e) {
MyFrame f = (MyFrame)e.getSource();
f.addPoint(new Point(e.getX(),e.getY()));
f.repaint();
}
}
六、window事件

測(cè)試代碼:
package cn.galc.test;
import java.awt.*;
import java.awt.event.*;
public class TestWindowClose{
public static void main(String args[]){
new WindowFrame("關(guān)閉WindowFrame");
}
}
class WindowFrame extends Frame{
public WindowFrame(String s){
super(s);
setBounds(200,200,400,300);
setLayout(null);
setBackground(new Color(204,204,255));
setVisible(true);
this.addWindowListener(new WindowMonitor());
/*監(jiān)聽(tīng)本窗體的動(dòng)作,把所有的動(dòng)作信息封裝成一個(gè)對(duì)象傳遞到監(jiān)聽(tīng)類里面*/
this.addWindowListener(
/*在一個(gè)方法里面定義一個(gè)類,這個(gè)類稱為局部類,也叫匿名的內(nèi)部類,
這里的{……代碼……}里面的代碼很像一個(gè)類的類體,只不過(guò)這個(gè)類沒(méi)有名字,所以叫匿名類
在這里是把這個(gè)匿名類當(dāng)成WindowAdapter類來(lái)使用,語(yǔ)法上這樣寫(xiě)的本質(zhì)意義是相當(dāng)于這個(gè)匿名類
從WindowAdapter類繼承,現(xiàn)在new了一個(gè)匿名類的對(duì)象出來(lái)然后把這個(gè)對(duì)象當(dāng)成WindowAdapter來(lái)使用
這個(gè)匿名類出了()就沒(méi)有人認(rèn)識(shí)了*/
new WindowAdapter(){
public void windowClosing(WindowEvent e){
setVisible(false);
System.exit(-1);
}
}
);
}
/*這里也是將監(jiān)聽(tīng)類定義為內(nèi)部類*/
class WindowMonitor extends WindowAdapter{
/*WindowAdapter(Window適配器)類實(shí)現(xiàn)了WindowListener監(jiān)聽(tīng)接口
重寫(xiě)了WindowListener接口里面的所有方法
如果直接使用自定義WindowMonitor類直接去
實(shí)現(xiàn)WindowListener接口,那么就得要重寫(xiě)WindowListener接口
里面的所有方法,但現(xiàn)在只需要用到這些方法里面的其中一個(gè)方法
所以采用繼承實(shí)現(xiàn)WindowListener監(jiān)聽(tīng)接口的一個(gè)子類
并重寫(xiě)這個(gè)子類里面需要用到的那個(gè)方法即可
這種做法比直接實(shí)現(xiàn)WindowListener監(jiān)聽(tīng)接口要重寫(xiě)很多個(gè)用不到的方法要簡(jiǎn)潔方便得多*/
/*重寫(xiě)需要用到的windowClosing(WindowEvent e)方法*/
public void windowClosing(WindowEvent e){
setVisible(false);/*將窗體設(shè)置為不顯示,即可實(shí)現(xiàn)窗體關(guān)閉*/
System.exit(0);/*正常退出*/
}
}
}
七、鍵盤響應(yīng)事件——KeyEvent
測(cè)試代碼:
package cn.galc.test;
import java.awt.*;
import java.awt.event.*;
public class TestKeyEvent{
public static void main(String args[]){
new KeyFrame("鍵盤響應(yīng)事件");
}
}
class KeyFrame extends Frame{
public KeyFrame(String s){
super(s);
setBounds(200,200,400,300);
setLayout(null);
setVisible(true);
addKeyListener(new KeyMonitor());
}
/*把自定義的鍵盤的監(jiān)聽(tīng)類定義為內(nèi)部類
這個(gè)監(jiān)聽(tīng)類從鍵盤適配器KeyAdapter類繼承
從KeyAdapter類繼承也是為了可以簡(jiǎn)潔方便
只需要重寫(xiě)需要用到的方法即可,這種做法比
直接實(shí)現(xiàn)KeyListener接口要簡(jiǎn)單方便,如果
直接實(shí)現(xiàn)KeyListener接口就要把KeyListener
接口里面的所有方法重寫(xiě)一遍,但真正用到的
只有一個(gè)方法,這樣重寫(xiě)其他的方法但又用不到
難免會(huì)做無(wú)用功*/
class KeyMonitor extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keycode = e.getKeyCode();
/*使用getKeyCode()方法獲取按鍵的虛擬碼*/
/*如果獲取到的鍵的虛擬碼等于up鍵的虛擬碼
則表示當(dāng)前按下的鍵是up鍵
KeyEvent.VK_UP表示取得up鍵的虛擬碼
鍵盤中的每一個(gè)鍵都對(duì)應(yīng)有一個(gè)虛擬碼
這些虛擬碼在KeyEvent類里面都被定義為靜態(tài)常量
所以可以使用“類名.靜態(tài)常量名”的形式訪問(wèn)得到這些靜態(tài)常量*/
if(keycode == KeyEvent.VK_UP){
System.out.println("你按的是up鍵");
}
}
}
}
/*鍵盤的處理事件是這樣的:每一個(gè)鍵都對(duì)應(yīng)著一個(gè)虛擬的碼,
當(dāng)按下某一個(gè)鍵時(shí),系統(tǒng)就會(huì)去找這個(gè)鍵對(duì)應(yīng)的虛擬的碼,以此來(lái)確定當(dāng)前按下的是那個(gè)鍵
*/
通過(guò)這篇文章和大家一起學(xué)習(xí)了GUI編程,希望大家對(duì)GUI編程有了更全面的認(rèn)識(shí),關(guān)于GUI編程遠(yuǎn)不止這些,還需要大家繼續(xù)學(xué)習(xí)。
相關(guān)文章
Mybatis-Plus中的selectByMap使用實(shí)例
Mybatis-Plus來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查時(shí),將里面的函數(shù)試了個(gè)遍,接下來(lái)我就將使用selectByMap函數(shù)的簡(jiǎn)單測(cè)試實(shí)例寫(xiě)出來(lái),方便沒(méi)有使用過(guò)的朋友們快速上手,感興趣的可以了解一下2021-11-11
Java中基于Shiro,JWT實(shí)現(xiàn)微信小程序登錄完整例子及實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了Java中基于Shiro,JWT實(shí)現(xiàn)微信小程序登錄完整例子 ,實(shí)現(xiàn)了小程序的自定義登陸,將自定義登陸態(tài)token返回給小程序作為登陸憑證。需要的朋友可以參考下2018-11-11
Mybatis中自定義TypeHandler處理枚舉的示例代碼
typeHandler,是 MyBatis 中的一個(gè)接口,用于處理數(shù)據(jù)庫(kù)中的特定數(shù)據(jù)類型,下面簡(jiǎn)單介紹創(chuàng)建自定義 typeHandler 來(lái)處理枚舉類型的示例,感興趣的朋友跟隨小編一起看看吧2024-01-01
基于Beanutils.copyProperties()的用法及重寫(xiě)提高效率
這篇文章主要介紹了Beanutils.copyProperties( )的用法及重寫(xiě)提高效率的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
基于spring cloud多個(gè)消費(fèi)端重復(fù)定義feign client的問(wèn)題
這篇文章主要介紹了spring cloud多個(gè)消費(fèi)端重復(fù)定義feign client的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Java基于代理模式解決紅酒經(jīng)銷問(wèn)題詳解
這篇文章主要介紹了Java基于代理模式解決紅酒經(jīng)銷問(wèn)題,詳細(xì)描述了代理模式的概念、原理并結(jié)合實(shí)例形式分析了java基于代理模式解決紅酒經(jīng)銷問(wèn)題的相關(guān)步驟、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2018-04-04
elasticsearch+logstash并使用java代碼實(shí)現(xiàn)日志檢索
這篇文章主要介紹了elasticsearch+logstash并使用java代碼實(shí)現(xiàn)日志檢索,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02

