整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Java-GUI編程之Swing組件

          組件設置邊框

          很多情況下,我們常常喜歡給不同的組件設置邊框,從而讓界面的層次感更明顯,swing中提供了Border對象來代表一個邊框,下圖是Border的繼承體系圖:



          特殊的Border:

          1. TitledBorder:它的作用并不是直接為其他組件添加邊框,而是為其他邊框設置標題,創建該類的對象時,需要傳入一個其他的Border對象;
          2. ComoundBorder:用來組合其他兩個邊框,創建該類的對象時,需要傳入其他兩個Border對象,一個作為內邊框,一個座位外邊框

          給組件設置邊框步驟:

          1. 使用BorderFactory或者XxxBorder創建Border的實例對象;
          2. 調用Swing組件的setBorder(Border b)方法為組件設置邊框;

          案例:

          ? 請使用Border實現下圖效果:
          ?



          演示代碼:

          import javax.swing.*;
          import javax.swing.border.*;
          import java.awt.*;
          
          public class BorderTest {
          
              JFrame jf  = new JFrame("測試邊框");
          
              public void init(){
                  //設置Jframe為網格布局
                  jf.setLayout(new GridLayout(2,4));
          
                  //創建凸起的斜邊框,分別設置四條邊的顏色
                  Border bb = BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.RED,Color.GREEN,Color.BLUE,Color.GRAY);
                  jf.add(getPanelWithBorder(bb,"BevelBorder"));
          
          
                  //創建LineBorder
                  Border lb = BorderFactory.createLineBorder(Color.ORANGE, 10);
                  jf.add(getPanelWithBorder(lb,"LineBorder"));
          
                  //創建EmptyBorder,會在組件的四周留白
                  Border eb = BorderFactory.createEmptyBorder(20, 5, 10, 30);
                  jf.add(getPanelWithBorder(eb,"EmptyBorder"));
          
                  //創建EtchedBorder,
                  Border etb = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);
                  jf.add(getPanelWithBorder(etb,"EtchedBorder"));
          
                  //創建TitledBorder,為原有的Border添加標題
                  TitledBorder tb = new TitledBorder(lb,"測試標題",TitledBorder.LEFT,TitledBorder.BOTTOM,new Font("StSong",Font.BOLD,18),Color.BLUE);
                  jf.add(getPanelWithBorder(tb,"TitledBorder"));
          
                  //直接創建MatteBorder,它是EmptyBorder的子類,EmptyBorder是留白,而MatteBorder可以給留空的區域填充顏色
                  MatteBorder mb = new MatteBorder(20,5,10,30,Color.GREEN);
                  jf.add(getPanelWithBorder(mb,"MatteBorder"));
          
                  //直接創創建CompoundBorder,將兩個邊框組合成新邊框
                  CompoundBorder cb = new CompoundBorder(new LineBorder(Color.RED,8),tb);
                  jf.add(getPanelWithBorder(cb,"CompoundBorder"));
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
          
              }
              public JPanel getPanelWithBorder(Border border,String borderName){
                  JPanel jPanel = new JPanel();
          
                  jPanel.add(new JLabel(borderName));
          
                  //為panel設置邊框
                  jPanel.setBorder(border);
          
                  return jPanel;
              }
              public static void main(String[] args) {
                  new BorderTest().init();
              }
          }
          

          使用JToolBar創建工具條

          Swing 提供了JToolBar類來創建工具條,并且可以往JToolBar中添加多個工具按鈕。

          JToolBar API:

          方法名稱

          方法功能

          JToolBar( String name , int orientation)

          創建一個名字為name,方向為orientation的工具條對象,其orientation的是取值可以是SwingConstants.HORIZONTAL或SwingConstants.VERTICAL

          JButton add(Action a)

          通過Action對象為JToolBar工具條添加對應的工具按鈕

          addSeparator( Dimension size )

          向工具條中添加指定大小的分隔符

          setFloatable( boolean b )

          設定工具條是否可以被拖動

          setMargin(Insets m)

          設置工具條與工具按鈕的邊距

          setOrientation( int o )

          設置工具條的方向

          setRollover(boolean rollover)

          設置此工具條的rollover狀態

          add(Action a)方法:

          ? 上述API中add(Action a)這個方法比較難理解,為什么呢,之前說過,Action接口是ActionListener的一個子接口,那么它就代表一個事件監聽器,而這里add方法是在給工具條添加一個工具按鈕,為什么傳遞的是一個事件監聽器呢?

          ? 首先要明確的是不管是菜單條中的菜單項還是工具條中的工具按鈕,最終肯定是需要點擊來完成一些操作,所以JToolBar以及JMenu都提供了更加便捷的添加子組件的方法add(Action a),在這個方法的內部會做如下幾件事:

          1. 創建一個適用于該容器的組件(例如,在工具欄中創建一個工具按鈕);
          2. 從 Action 從對象中獲得對應的屬性來設置該組件(例如,通過 name 來設置文本,通過 lcon 來設置圖標) ;
          3. 把Action監聽器注冊到剛才創建的組件上;

          案例:

          ? 使用JToolBar組件完成下圖效果:

          演示代碼:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class JToolBarTest {
          
              JFrame jf = new JFrame("測試工具條");
          
              JTextArea jta = new JTextArea(6, 35);
              // 創建工具條
              JToolBar jtb = new JToolBar();
          
              // 創建"上一曲"Action,該Action用于創建工具按鈕
              Action pre = new AbstractAction("上一曲", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\pre.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("上一曲.\n");
                  }
              };
          
              // 創建"暫停" Action
              Action pause = new AbstractAction("暫停", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\pause.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("暫停播放.\n");
                  }
              };
          
              // 創建"下一曲" Action
              Action next = new AbstractAction("下一曲", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\next.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("下一曲.\n");
                  }
              };
          
              public void init() {
          
                  // 給JTextArea添加滾動條
                  jf.add(new JScrollPane(jta));
          
                  // 以Action的形式創建按鈕,并將按鈕添加到Panel中
                  JButton preBtn = new JButton(pre);
                  JButton pauseBtn = new JButton(pause);
                  JButton nextBtn = new JButton(next);
          
                  // 往工具條中添加Action對象,該對象會轉換成工具按鈕
                  jtb.add(preBtn);
                  jtb.addSeparator();
                  jtb.add(pauseBtn);
                  jtb.addSeparator();
                  jtb.add(nextBtn);
          
                  // 向窗口中添加工具條
                  jf.add(jtb, BorderLayout.NORTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JToolBarTest().init();
              }
          }
          

          JColorChooser和JFileChooser

          Swing提供了JColorChooser和JFileChooser這兩種對話框,可以很方便的完成顏色的選擇和本地文件的選擇。

          JColorChooser

          JColorChooser 用于創建顏色選擇器對話框 , 該類的用法非常簡單,只需要調用它的靜態方法就可以快速生成一個顏色選擇對話框:

          public static Color showDialog(Component component, String title,Color initialColor)
              
          /*
          	參數:
          		componet:指定當前對話框的父組件
          		title:當前對話框的名稱
          		initialColor:指定默認選中的顏色
          		
          	返回值:
          		返回用戶選中的顏色
          */
          

          案例:

          ? 使用顏色選擇器,完成下圖功能:

          ? 點擊按鈕,改變文本域的背景色

          演示代碼:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class JColorChooserDemo {
          
              JFrame jFrame = new JFrame("測試顏色選擇器");
          
              JTextArea jta = new JTextArea("快關注我",6,30);
          
              JButton button = new JButton(new AbstractAction("改變文本框的本景色"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      //彈出顏色選擇器
                      Color result = JColorChooser.showDialog(jFrame, "顏色選擇器", Color.WHITE);
                      jta.setBackground(result);
                  }
              });
          
              public void init(){
                  jFrame.add(jta);
          
                  jFrame.add(button,BorderLayout.SOUTH);
          
                  jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jFrame.pack();
                  jFrame.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JColorChooserDemo().init();
              }
          
          }
          
          

          JFileChooser

          ? JFileChooser 的功能與AWT中的 FileDialog 基本相似,也是用于生成"打開文件"、"保存文件 "對話框。與 FileDialog 不同的是 , JFileChooser 無須依賴于本地平臺的 GUI , 它由 100%純 Java 實現 , 在所有平臺 上具有完全相同的行為,并可以在所有平臺上具有相同的外觀風格。

          JFileChooser使用步驟:

          1. 創建JFileChooser對象:
          JFileChooser chooser = new JFileChooser("D:\\a");//指定默認打開的本地磁盤路徑
          
          1. 調用JFileChooser的一系列可選方法,進行初始化
          setSelectedFile(File file)/setSelectedFiles(File[] selectedFiles):設定默認選中的文件
          setMultiSelectionEnabled(boolean b):設置是否允許多選,默認是單選
          setFileSelectionMode(int mode):設置可以選擇內容,例如文件、文件夾等,默認只能選擇文件
          
          1. 打開文件對話框
          showOpenDialog(Component parent):打開文件加載對話框,并指定父組件
          showSaveDialog(Component parent):打開文件保存對話框,并指定父組件
          
          1. 獲取用戶選擇的結果
          File getSelectedFile():獲取用戶選擇的一個文件
          File[] getSelectedFiles():獲取用戶選擇的多個文件
          

          案例:

          ? 使用JFileChooser完成下圖效果:

          演示代碼:

          import javax.imageio.ImageIO;
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          import java.awt.image.BufferedImage;
          import java.io.File;
          import java.io.IOException;
          
          public class JFileChooserDemo {
          
              //創建窗口對象
              JFrame jf = new JFrame("測試JFileChooser");
          
              //創建打開文件對話框
              JFileChooser chooser = new JFileChooser(".");
          
              //創建菜單條
              JMenuBar jmb = new JMenuBar();
              //創建菜單
              JMenu jMenu = new JMenu("文件");
              //創建菜單項
              JMenuItem open = new JMenuItem(new AbstractAction("打開"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      chooser.showOpenDialog(jf);
                      File imageFile = chooser.getSelectedFile();
                      try {
                          image = ImageIO.read(imageFile);
                          drawArea.repaint();
                      } catch (IOException e1) {
                          e1.printStackTrace();
                      }
                  }
              });
          
              JMenuItem save = new JMenuItem(new AbstractAction("另存為"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                      chooser.showSaveDialog(jf);
                      File dir = chooser.getSelectedFile();
                      try {
                          ImageIO.write(image,"jpeg",new File(dir,"a.jpg"));
                      } catch (Exception e1) {
                          e1.printStackTrace();
                      }
                  }
              });
          
              //用來記錄用戶選擇的圖片
              BufferedImage image;
          
              //顯示圖片
              class MyCanvas extends JPanel{
                  @Override
                  public void paint(Graphics g) {
                      if (image!=null){
                          g.drawImage(image,0,0,null);
                      }
                  }
              }
          
              JPanel drawArea = new MyCanvas();
          
              public void init(){
                  //設置圖片顯示區域大小
                  drawArea.setPreferredSize(new Dimension(500,300));
                  jf.add(drawArea);
          
                  //組裝并設置菜單條
                  jMenu.add(open);
                  jMenu.add(save);
                  jmb.add(jMenu);
                  jf.setJMenuBar(jmb);
          
                  //顯示jf
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JFileChooserDemo().init();
              }    
                
          }
          

          JOptionPane

          基本概述

          通過 JOptionPane 可以非常方便地創建一些簡單的對話框, Swing 已經為這些對話框添加了相應的組件,無須程序員手動添加組件 。 JOptionPane 提供了如下 4 個方法來創建對話框 。

          方法名稱

          方法功能

          showMessageDialog/showInternalMessageDialog

          消息對話框 ,告知用戶某事己發生 , 用戶只能單擊"確定"按鈕 , 類似于 JavaScript 的 alert 函數 。

          showConfirmDialog/showInternalConfirmDialog

          確認對話框,向用戶確認某個問題,用戶可以選擇 yes 、 no ~ cancel 等選項 。 類似于 JavaScript 的 comfirm 函數 。該方法返回用戶單擊了 哪個按鈕

          showInputDialog/showInternalInputDialog

          輸入對話框,提示要求輸入某些信息,類似于 JavaScript的 prompt 函數。該方法返回用戶輸入的字符串 。

          showOptionDialog/showInternalOptionDialog

          自定義選項對話框 ,允許使用自 定義選項 ,可以取代showConfirmDialog 所產生的對話框,只是用起來更復雜 。

          上述方法都有都有很多重載形式,選擇其中一種最全的形式,參數解釋如下:

          showXxxDialog(Component parentComponent,
          		Object message, 
          		String title, 
          		int optionType, 
          		int messageType,
                  	Icon icon,
          		Object[] options, 
          		Object initialValue)
          --參數解釋:
          parentComponent:當前對話框的父組件
          message:對話框上顯示的信息,信息可以是字符串、組件、圖片等
          title:當前對話框的標題
          optionType:當前對話框上顯示的按鈕類型:DEFAULT_OPTION、YES_NO_OPTION、YES_NO_CANCEL_OPTION、OK_CANCEL_OPTION
          messageType:當前對話框的類型:ERROR_MESSAGE、INFORMATION_MESSAGE、WARNING_MESSAGE、QUESTION_MESSAGE、PLAIN_MESSAGE
          icon:當前對話框左上角的圖標
          options:自定義下拉列表的選項
          initialValue:自定義選項中的默認選中項
          

          當用戶與對話框交互結束后,不同類型對話框的返回值如下:

          • showMessageDialog: 無返回值 。
          • showlnputDialog: 返回用戶輸入或選擇的字符串 。
          • showConfirmDialog: 返回 一個整數代表用戶選擇的選項 。
          • showOptionDialog : 返回 一個整數代表用戶選擇的選項,如果用戶選擇第一項,則返回 0; 如果選擇第二項,則返回1……依此類推 。

          對 showConfirmDialog 所產生的對話框,有如下幾個返回值:

          • YES OPTION: 用戶 單擊了 "是"按鈕后返回 。
          • NO OPTION: 用 戶單擊了"否"按鈕后返回 。
          • CANCEL OPTION: 用戶單擊了"取消"按鈕后返回 。
          • OK OPTION : 用戶單擊了"確定"按鈕后返回 。
          • CLOSED OPTION: 用戶 單擊了對話框右上角的 " x" 按鈕后返回。

          四種對話框演示

          消息對話框:

          import cn.itcast.swing.util.ImagePathUtil;
          
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class MessageDialogTest {
          
              JFrame jf = new JFrame("測試消息對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出消息對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.ERROR_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.INFORMATION_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.WARNING_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.QUESTION_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.PLAIN_MESSAGE);
                      JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.WARNING_MESSAGE, new ImageIcon(ImagePathUtil.getRealPath("2\\female.png")));
          
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new MessageDialogTest().init();
              }
          
          }
          
          

          確認對話框:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class ConfirmDialogTest {
          
          
              JFrame jf = new JFrame("測試確認對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出確認對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      int result = JOptionPane.showConfirmDialog(jf, jta.getText(), "確認對話框",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                      if (result == JOptionPane.YES_OPTION){
                          jta.append("\n用戶點擊了確定按鈕");
                      }
          
                      if (result==JOptionPane.NO_OPTION){
                          jta.append("\n用戶點擊了取消按鈕");
                      }
          
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new ConfirmDialogTest().init();
              }
          
          }
          

          ?

          輸入對話框:

          ?



          ?

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class InputDialogTest {
          
              JFrame jf = new JFrame("測試輸入對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出輸入對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
          
                     /* String result = JOptionPane.showInputDialog(jf, "請填寫您的銀行賬號:", "輸入對話框", JOptionPane.INFORMATION_MESSAGE);
                      if(result!=null){
                          jta.append(result.toString());
                      }
                      */
          
                      Object result = JOptionPane.showInputDialog(jf, "", "輸入對話框", JOptionPane.DEFAULT_OPTION, null, new String[]{"柳巖", "舒淇", "龔玥菲"}, "舒淇");
                      if (result!=null){
                          jta.append(result.toString());
                      }
                  }
              });
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new InputDialogTest().init();
              }
          
          }
          
          

          選項對話框:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class OptionDialogTest {
          
              JFrame jf = new JFrame("測試選項對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出選項對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      int result = JOptionPane.showOptionDialog(jf, "請選擇尿不濕號碼", "選項對話框",JOptionPane.DEFAULT_OPTION,JOptionPane.INFORMATION_MESSAGE,
                              null,new String[]{"大號","中號","小號"},"中號");
          
                      switch (result){
                          case 0:
                              jta.setText("用戶選擇了大號");
                              break;
                          case 1:
                              jta.setText("用戶選擇了中號");
                              break;
                          case 2:
                              jta.setText("用戶選擇了小號");
                              break;
                      }
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new OptionDialogTest().init();
              }
          
          }
          



          如果本文對你有幫助,別忘記給我個3連 ,點贊,轉發,評論,,咱們下期見。

          收藏 等于白嫖,點贊才是真情。







          原文 https://www.cnblogs.com/kohler21/p/16219066.html

          組件設置邊框

          很多情況下,我們常常喜歡給不同的組件設置邊框,從而讓界面的層次感更明顯,swing中提供了Border對象來代表一個邊框,下圖是Border的繼承體系圖:



          特殊的Border:

          1. TitledBorder:它的作用并不是直接為其他組件添加邊框,而是為其他邊框設置標題,創建該類的對象時,需要傳入一個其他的Border對象;
          2. ComoundBorder:用來組合其他兩個邊框,創建該類的對象時,需要傳入其他兩個Border對象,一個作為內邊框,一個座位外邊框

          給組件設置邊框步驟:

          1. 使用BorderFactory或者XxxBorder創建Border的實例對象;
          2. 調用Swing組件的setBorder(Border b)方法為組件設置邊框;

          案例:

          ? 請使用Border實現下圖效果:
          ?



          演示代碼:

          import javax.swing.*;
          import javax.swing.border.*;
          import java.awt.*;
          
          public class BorderTest {
          
              JFrame jf  = new JFrame("測試邊框");
          
              public void init(){
                  //設置Jframe為網格布局
                  jf.setLayout(new GridLayout(2,4));
          
                  //創建凸起的斜邊框,分別設置四條邊的顏色
                  Border bb = BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.RED,Color.GREEN,Color.BLUE,Color.GRAY);
                  jf.add(getPanelWithBorder(bb,"BevelBorder"));
          
          
                  //創建LineBorder
                  Border lb = BorderFactory.createLineBorder(Color.ORANGE, 10);
                  jf.add(getPanelWithBorder(lb,"LineBorder"));
          
                  //創建EmptyBorder,會在組件的四周留白
                  Border eb = BorderFactory.createEmptyBorder(20, 5, 10, 30);
                  jf.add(getPanelWithBorder(eb,"EmptyBorder"));
          
                  //創建EtchedBorder,
                  Border etb = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);
                  jf.add(getPanelWithBorder(etb,"EtchedBorder"));
          
                  //創建TitledBorder,為原有的Border添加標題
                  TitledBorder tb = new TitledBorder(lb,"測試標題",TitledBorder.LEFT,TitledBorder.BOTTOM,new Font("StSong",Font.BOLD,18),Color.BLUE);
                  jf.add(getPanelWithBorder(tb,"TitledBorder"));
          
                  //直接創建MatteBorder,它是EmptyBorder的子類,EmptyBorder是留白,而MatteBorder可以給留空的區域填充顏色
                  MatteBorder mb = new MatteBorder(20,5,10,30,Color.GREEN);
                  jf.add(getPanelWithBorder(mb,"MatteBorder"));
          
                  //直接創創建CompoundBorder,將兩個邊框組合成新邊框
                  CompoundBorder cb = new CompoundBorder(new LineBorder(Color.RED,8),tb);
                  jf.add(getPanelWithBorder(cb,"CompoundBorder"));
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
          
              }
              public JPanel getPanelWithBorder(Border border,String borderName){
                  JPanel jPanel = new JPanel();
          
                  jPanel.add(new JLabel(borderName));
          
                  //為panel設置邊框
                  jPanel.setBorder(border);
          
                  return jPanel;
              }
              public static void main(String[] args) {
                  new BorderTest().init();
              }
          }
          

          使用JToolBar創建工具條

          Swing 提供了JToolBar類來創建工具條,并且可以往JToolBar中添加多個工具按鈕。

          JToolBar API:

          方法名稱

          方法功能

          JToolBar( String name , int orientation)

          創建一個名字為name,方向為orientation的工具條對象,其orientation的是取值可以是SwingConstants.HORIZONTAL或SwingConstants.VERTICAL

          JButton add(Action a)

          通過Action對象為JToolBar工具條添加對應的工具按鈕

          addSeparator( Dimension size )

          向工具條中添加指定大小的分隔符

          setFloatable( boolean b )

          設定工具條是否可以被拖動

          setMargin(Insets m)

          設置工具條與工具按鈕的邊距

          setOrientation( int o )

          設置工具條的方向

          setRollover(boolean rollover)

          設置此工具條的rollover狀態

          add(Action a)方法:

          ? 上述API中add(Action a)這個方法比較難理解,為什么呢,之前說過,Action接口是ActionListener的一個子接口,那么它就代表一個事件監聽器,而這里add方法是在給工具條添加一個工具按鈕,為什么傳遞的是一個事件監聽器呢?

          ? 首先要明確的是不管是菜單條中的菜單項還是工具條中的工具按鈕,最終肯定是需要點擊來完成一些操作,所以JToolBar以及JMenu都提供了更加便捷的添加子組件的方法add(Action a),在這個方法的內部會做如下幾件事:

          1. 創建一個適用于該容器的組件(例如,在工具欄中創建一個工具按鈕);
          2. 從 Action 對象中獲得對應的屬性來設置該組件(例如,通過 name 來設置文本,通過 lcon 來設置圖標) ;
          3. 把Action監聽器注冊到剛才創建的組件上;

          案例:

          ? 使用JToolBar組件完成下圖效果:

          演示代碼:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class JToolBarTest {
          
              JFrame jf = new JFrame("測試工具條");
          
              JTextArea jta = new JTextArea(6, 35);
              // 創建工具條
              JToolBar jtb = new JToolBar();
          
              // 創建"上一曲"Action,該Action用于創建工具按鈕
              Action pre = new AbstractAction("上一曲", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\pre.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("上一曲.\n");
                  }
              };
          
              // 創建"暫停" Action
              Action pause = new AbstractAction("暫停", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\pause.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("暫停播放.\n");
                  }
              };
          
              // 創建"下一曲" Action
              Action next = new AbstractAction("下一曲", new ImageIcon("D:\\files\\Java-GUI\\src\\layout\\next.png")) {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      jta.append("下一曲.\n");
                  }
              };
          
              public void init() {
          
                  // 給JTextArea添加滾動條
                  jf.add(new JScrollPane(jta));
          
                  // 以Action的形式創建按鈕,并將按鈕添加到Panel中
                  JButton preBtn = new JButton(pre);
                  JButton pauseBtn = new JButton(pause);
                  JButton nextBtn = new JButton(next);
          
                  // 往工具條中添加Action對象,該對象會轉換成工具按鈕
                  jtb.add(preBtn);
                  jtb.addSeparator();
                  jtb.add(pauseBtn);
                  jtb.addSeparator();
                  jtb.add(nextBtn);
          
                  // 向窗口中添加工具條
                  jf.add(jtb, BorderLayout.NORTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JToolBarTest().init();
              }
          }
          

          JColorChooser和JFileChooser

          Swing提供了JColorChooser和JFileChooser這兩種對話框,可以很方便的完成顏色的選擇和本地文件的選擇。

          JColorChooser

          JColorChooser 用于創建顏色選擇器對話框 , 該類的用法非常簡單,只需要調用它的靜態方法就可以快速生成一個顏色選擇對話框:

          public static Color showDialog(Component component, String title,Color initialColor)
              
          /*
          	參數:
          		componet:指定當前對話框的父組件
          		title:當前對話框的名稱
          		initialColor:指定默認選中的顏色
          		
          	返回值:
          		返回用戶選中的顏色
          */
          

          案例:

          ? 使用顏色選擇器,完成下圖功能:

          ? 點擊按鈕,改變文本域的背景色

          演示代碼:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class JColorChooserDemo {
          
              JFrame jFrame = new JFrame("測試顏色選擇器");
          
              JTextArea jta = new JTextArea("快關注我",6,30);
          
              JButton button = new JButton(new AbstractAction("改變文本框的本景色"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      //彈出顏色選擇器
                      Color result = JColorChooser.showDialog(jFrame, "顏色選擇器", Color.WHITE);
                      jta.setBackground(result);
                  }
              });
          
              public void init(){
                  jFrame.add(jta);
          
                  jFrame.add(button,BorderLayout.SOUTH);
          
                  jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jFrame.pack();
                  jFrame.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JColorChooserDemo().init();
              }
          
          }
          
          

          JFileChooser

          ? JFileChooser 的功能與AWT中的 FileDialog 基本相似,也是用于生成"打開文件"、"保存文件 "對話框。與 FileDialog 不同的是 , JFileChooser 無須依賴于本地平臺的 GUI , 它由 100%純 Java 實現 , 在所有平臺 上具有完全相同的行為,并可以在所有平臺上具有相同的外觀風格。

          JFileChooser使用步驟:

          1. 創建JFileChooser對象:
          JFileChooser chooser = new JFileChooser("D:\\a");//指定默認打開的本地磁盤路徑
          
          1. 調用JFileChooser的一系列可選方法,進行初始化
          setSelectedFile(File file)/setSelectedFiles(File[] selectedFiles):設定默認選中的文件
          setMultiSelectionEnabled(boolean b):設置是否允許多選,默認是單選
          setFileSelectionMode(int mode):設置可以選擇內容,例如文件、文件夾等,默認只能選擇文件
          
          1. 打開文件對話框
          showOpenDialog(Component parent):打開文件加載對話框,并指定父組件
          showSaveDialog(Component parent):打開文件保存對話框,并指定父組件
          
          1. 獲取用戶選擇的結果
          File getSelectedFile():獲取用戶選擇的一個文件
          File[] getSelectedFiles():獲取用戶選擇的多個文件
          

          案例:

          ? 使用JFileChooser完成下圖效果:

          演示代碼:

          import javax.imageio.ImageIO;
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          import java.awt.image.BufferedImage;
          import java.io.File;
          import java.io.IOException;
          
          public class JFileChooserDemo {
          
              //創建窗口對象
              JFrame jf = new JFrame("測試JFileChooser");
          
              //創建打開文件對話框
              JFileChooser chooser = new JFileChooser(".");
          
              //創建菜單條
              JMenuBar jmb = new JMenuBar();
              //創建菜單
              JMenu jMenu = new JMenu("文件");
              //創建菜單項
              JMenuItem open = new JMenuItem(new AbstractAction("打開"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      chooser.showOpenDialog(jf);
                      File imageFile = chooser.getSelectedFile();
                      try {
                          image = ImageIO.read(imageFile);
                          drawArea.repaint();
                      } catch (IOException e1) {
                          e1.printStackTrace();
                      }
                  }
              });
          
              JMenuItem save = new JMenuItem(new AbstractAction("另存為"){
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                      chooser.showSaveDialog(jf);
                      File dir = chooser.getSelectedFile();
                      try {
                          ImageIO.write(image,"jpeg",new File(dir,"a.jpg"));
                      } catch (Exception e1) {
                          e1.printStackTrace();
                      }
                  }
              });
          
              //用來記錄用戶選擇的圖片
              BufferedImage image;
          
              //顯示圖片
              class MyCanvas extends JPanel{
                  @Override
                  public void paint(Graphics g) {
                      if (image!=null){
                          g.drawImage(image,0,0,null);
                      }
                  }
              }
          
              JPanel drawArea = new MyCanvas();
          
              public void init(){
                  //設置圖片顯示區域大小
                  drawArea.setPreferredSize(new Dimension(500,300));
                  jf.add(drawArea);
          
                  //組裝并設置菜單條
                  jMenu.add(open);
                  jMenu.add(save);
                  jmb.add(jMenu);
                  jf.setJMenuBar(jmb);
          
                  //顯示jf
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new JFileChooserDemo().init();
              }    
                
          }
          

          JOptionPane

          基本概述

          通過 JOptionPane 可以非常方便地創建一些簡單的對話框, Swing 已經為這些對話框添加了相應的組件,無須程序員手動添加組件 。 JOptionPane 提供了如下 4 個方法來創建對話框 。

          方法名稱

          方法功能

          showMessageDialog/showInternalMessageDialog

          消息對話框 ,告知用戶某事己發生 , 用戶只能單擊"確定"按鈕 , 類似于 JavaScript 的 alert 函數 。

          showConfirmDialog/showInternalConfirmDialog

          確認對話框,向用戶確認某個問題,用戶可以選擇 yes 、 no ~ cancel 等選項 。 類似于 JavaScript 的 comfirm 函數 。該方法返回用戶單擊了 哪個按鈕

          showInputDialog/showInternalInputDialog

          輸入對話框,提示要求輸入某些信息,類似于 JavaScript的 prompt 函數。該方法返回用戶輸入的字符串 。

          showOptionDialog/showInternalOptionDialog

          自定義選項對話框 ,允許使用自 定義選項 ,可以取代showConfirmDialog 所產生的對話框,只是用起來更復雜 。

          上述方法都有都有很多重載形式,選擇其中一種最全的形式,參數解釋如下:

          showXxxDialog(Component parentComponent,
          		Object message, 
          		String title, 
          		int optionType, 
          		int messageType,
                  	Icon icon,
          		Object[] options, 
          		Object initialValue)
          --參數解釋:
          parentComponent:當前對話框的父組件
          message:對話框上顯示的信息,信息可以是字符串、組件、圖片等
          title:當前對話框的標題
          optionType:當前對話框上顯示的按鈕類型:DEFAULT_OPTION、YES_NO_OPTION、YES_NO_CANCEL_OPTION、OK_CANCEL_OPTION
          messageType:當前對話框的類型:ERROR_MESSAGE、INFORMATION_MESSAGE、WARNING_MESSAGE、QUESTION_MESSAGE、PLAIN_MESSAGE
          icon:當前對話框左上角的圖標
          options:自定義下拉列表的選項
          initialValue:自定義選項中的默認選中項
          

          當用戶與對話框交互結束后,不同類型對話框的返回值如下:

          • showMessageDialog: 無返回值 。
          • showlnputDialog: 返回用戶輸入或選擇的字符串 。
          • showConfirmDialog: 返回 一個整數代表用戶選擇的選項 。
          • showOptionDialog : 返回 一個整數代表用戶選擇的選項,如果用戶選擇第一項,則返回 0; 如果選擇第二項,則返回1……依此類推 。

          對 showConfirmDialog 所產生的對話框,有如下幾個返回值:

          • YES OPTION: 用戶 單擊了 "是"按鈕后返回 。
          • NO OPTION: 用 戶單擊了"否"按鈕后返回 。
          • CANCEL OPTION: 用戶單擊了"取消"按鈕后返回 。
          • OK OPTION : 用戶單擊了"確定"按鈕后返回 。
          • CLOSED OPTION: 用戶 單擊了對話框右上角的 " x" 按鈕后返回。

          四種對話框演示

          消息對話框:

          import cn.itcast.swing.util.ImagePathUtil;
          
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class MessageDialogTest {
          
              JFrame jf = new JFrame("測試消息對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出消息對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.ERROR_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.INFORMATION_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.WARNING_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.QUESTION_MESSAGE);
                      //JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.PLAIN_MESSAGE);
                      JOptionPane.showMessageDialog(jf, jta.getText(), "消息對話框", JOptionPane.WARNING_MESSAGE, new ImageIcon(ImagePathUtil.getRealPath("2\\female.png")));
          
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new MessageDialogTest().init();
              }
          
          }
          
          

          確認對話框:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class ConfirmDialogTest {
          
          
              JFrame jf = new JFrame("測試確認對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出確認對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      int result = JOptionPane.showConfirmDialog(jf, jta.getText(), "確認對話框",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                      if (result == JOptionPane.YES_OPTION){
                          jta.append("\n用戶點擊了確定按鈕");
                      }
          
                      if (result==JOptionPane.NO_OPTION){
                          jta.append("\n用戶點擊了取消按鈕");
                      }
          
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new ConfirmDialogTest().init();
              }
          
          }
          

          ?

          輸入對話框:

          ?



          ?

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class InputDialogTest {
          
              JFrame jf = new JFrame("測試輸入對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出輸入對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
          
                     /* String result = JOptionPane.showInputDialog(jf, "請填寫您的銀行賬號:", "輸入對話框", JOptionPane.INFORMATION_MESSAGE);
                      if(result!=null){
                          jta.append(result.toString());
                      }
                      */
          
                      Object result = JOptionPane.showInputDialog(jf, "", "輸入對話框", JOptionPane.DEFAULT_OPTION, null, new String[]{"柳巖", "舒淇", "龔玥菲"}, "舒淇");
                      if (result!=null){
                          jta.append(result.toString());
                      }
                  }
              });
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new InputDialogTest().init();
              }
          
          }
          
          

          選項對話框:

          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.ActionEvent;
          
          public class OptionDialogTest {
          
              JFrame jf = new JFrame("測試選項對話框");
          
              JTextArea jta = new JTextArea(6, 30);
          
              JButton btn = new JButton(new AbstractAction("彈出選項對話框") {
          
                  @Override
                  public void actionPerformed(ActionEvent e) {
          
                      int result = JOptionPane.showOptionDialog(jf, "請選擇尿不濕號碼", "選項對話框",JOptionPane.DEFAULT_OPTION,JOptionPane.INFORMATION_MESSAGE,
                              null,new String[]{"大號","中號","小號"},"中號");
          
                      switch (result){
                          case 0:
                              jta.setText("用戶選擇了大號");
                              break;
                          case 1:
                              jta.setText("用戶選擇了中號");
                              break;
                          case 2:
                              jta.setText("用戶選擇了小號");
                              break;
                      }
                  }
              });
          
          
              public void init(){
                  jf.add(jta);
                  jf.add(btn, BorderLayout.SOUTH);
          
                  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  jf.pack();
                  jf.setVisible(true);
              }
          
              public static void main(String[] args) {
                  new OptionDialogTest().init();
              }
          
          }
          


          文章來自https://www.cnblogs.com/kohler21/p/16219066.html

          ava自身提供了swing程序化控制接口,即Java Access Bridge(jab)。百度上有很多相關的資料,但是總是存在一些問題導致無法控制。

          一. 安裝jab

          jab下載地址

          https://www.oracle.com/java/technologies/javase-jab-2-0-2-downloads.html

          Oracle官方jab安裝教程(推薦直接閱讀官方安裝教程)

          https://docs.oracle.com/javase/accessbridge/2.0.2/setup.htm

          解壓下載的jab壓縮文件,并將文件復制到相應的文件夾中(此處是重點,很多網址中沒有這一步)。java7之后就已經集成了JAB,如果安裝的目錄中含有對應需要安裝的文件,可以不用覆蓋。

          當jab安裝好了以后,隨意打開一個java swing程序。然后打開JavaMonkey-64.exe(如果安裝的是64位java,打開JavaMonkey.exe沒有效果),會出現當前窗口所有控件的屬性結構圖,表明jab安裝成功。

          二. 安裝pyjab

          pip install pyjab

          也可以訪問pyjab github源碼

          https://github.com/gaozhao1989/pyjab

          于是在python中也可以像selenium操控網頁一樣操控java swing了。由于pyjab項目處于新生狀態,可能存在部分bug。

          很感謝pyjab的作者分享,這樣我們就不用重復造輪子也不用去面對底層api。

          三. 后記

          1. 根據pyjab官方示例,JABDriver需要輸入title。但是有些java swing僅有class,title為空。
          class JABDriver(Service, ActorScheduler):
              """Controls a Java application by Java Access Bridge.
              Args:
                  Service ([type]): Host system to initialize the JAB and load JAB dll file.
                  ActorScheduler ([type]): Set message pump to interacte with windows system.
              """
              def __init__(
                  self,
                  title: str = "",
                  bridge_dll: str = "",
                  hwnd: HWND = None,
                  vmid: c_long = None,
                  accessible_context: JOBJECT64 = None,
                  timeout: int = TIMEOUT,
              ) -> None:
          

          于是可以使用pywin32獲取到窗口的句柄,然后傳入JABDriver中。但是此時會報錯

          FileNotFoundError: WindowsAccessBridge dll not found, please set correct path for environment variable, or check the passed customized WindowsAccessBridge dll.

          需要將WindowsAccessBridge的絕對路徑傳進去,例如:

          handle = win32gui.FindWindow('SunAwtDialog', None)
          # Create a JABDriver object.
          jabdriver = JABDriver(bridge_dll=r'C:\Windows\SysWOW64\WindowsAccessBridge-32.dll', hwnd=handle)
          
          1. 雖然pyjab支持xpath語法,但是很多語法支持程度不夠。目前已知的支持的元素類型如下
          """
          The By implementation.
          """
          class By(object):
              """
              Set of supported locator strategies.
              """
              XPATH = "xpath"
              NAME = "name"
              ROLE = "role"
              STATES = "states"
              OBJECT_DEPTH = "object_depth"
              CHILDREN_COUNT = "children_count"
              INDEX_IN_PARENT = "index_in_parent"
          
          1. 推薦一款java swing元素定位工具access-bridge-explorer

          https://github.com/google/access-bridge-explorer

          1. 若元素采用win32接口方式點擊, simulate=True

          此處源碼中并沒有計算屏幕縮放,應在點擊前(DOWN動作之前),計算屏幕縮放比例。

          def click(self, simulate: bool = False) -> None:
              """Simulates clicking to JABElement.
          
              Default will use JAB Accessible Action.
              Set parameter 'simulate' to True if internal action does not work.
          
              Args:
                  simulate (bool, optional): Simulate user click action by mouse event. Defaults to False.
          
              Raises:
                  ValueError: Raise ValueError when JABElement width or height is 0.
          
              Use this to send simple mouse events or to click form fields::
          
                  form_button = driver.find_element_by_name('button')
                  form_button.click()
                  form_button.click(simulate=True)
              """
              if simulate:
                  self.win32_utils._set_window_foreground(hwnd=self.hwnd.value)
                  self.set_element_information()
                  x = self.bounds.get("x")
                  y = self.bounds.get("y")
                  width = self.bounds.get("width")
                  height = self.bounds.get("height")
                  if width == 0 or height == 0:
                      raise ValueError("element width or height is 0")
                  position_x = round(x + width / 2)
                  position_y = round(y + height / 2)
                  self.win32_utils._click_mouse(x=position_x, y=position_y)
              else:
                  self._do_accessible_action(action="click")
                  
          
          def _click_mouse(self, x: int, y: int, hold: int = 0) -> None:
              win32api.SetCursorPos((x, y))
              win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
              if hold:
                  time.sleep(hold)
              win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)        
          

          計算屏幕縮放比例可參考如下,從百度中復制,并未驗證


          主站蜘蛛池模板: 国产麻豆精品一区二区三区v视界| 狠狠色成人一区二区三区| 日韩国产免费一区二区三区| 中文字幕精品一区二区日本| 超清无码一区二区三区| 少妇无码一区二区三区免费| 精品国产一区二区三区久| 国产精品主播一区二区| 久久精品国产一区| 性色AV一区二区三区| 无码精品人妻一区二区三区人妻斩 | 国产精品一区不卡| 中文字幕日韩人妻不卡一区| 麻豆视传媒一区二区三区| 亚洲av无码不卡一区二区三区| 国产精品综合一区二区| 无码日韩精品一区二区免费| 日韩人妻精品无码一区二区三区 | 一区二区三区伦理高清| 国产视频一区在线观看| 日韩精品一区二区三区不卡 | 国产萌白酱在线一区二区| 日韩好片一区二区在线看| 日韩在线不卡免费视频一区| 午夜福利一区二区三区高清视频| 中文字幕一区日韩在线视频 | 国产一区二区三区免费观在线 | 国产精品亚洲午夜一区二区三区 | 视频一区在线播放| 动漫精品第一区二区三区| 麻豆视传媒一区二区三区| 一区二区三区在线免费观看视频 | 国产精品亚洲一区二区在线观看| 亚洲码欧美码一区二区三区| 亚洲国产AV一区二区三区四区| 亚洲国产一区二区三区在线观看 | 亚洲AV无一区二区三区久久| 久久久国产精品一区二区18禁| 亚洲av无码一区二区三区天堂古代| 亚洲一区二区影视| 亚洲高清毛片一区二区|