如何在java中有效地使用cardlayout以便使用各种面板构造函数中的按钮从面板切换 [英] How to effectively use cardlayout in java in order to switch from panel using buttons inside various panel constructors

查看:32
本文介绍了如何在java中有效地使用cardlayout以便使用各种面板构造函数中的按钮从面板切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是使用 cardlayout 的新手,我有一些关于如何实施它的问题.我首先想知道实现 cardlayout 的最佳方法,以便我可以在面板之间切换.我的主要问题是如何使用面板构造函数中的按钮在面板之间切换.我今天刚刚开始研究这个项目,所以你会看到一些没有完成或没有意义的代码.我首先尝试让我的所有类扩展 JFrame,但这导致了多个不需要的窗口.如果我能得到一些关于如何有效使用 cardlayout 以及如何使用其他面板构造函数中的按钮切换面板的示例.我尝试使用 cardlayout 仅适用于我在 gui 类中创建的按钮,但这不是我想要的结果.如果可以,请提供帮助,并提前致谢.

I am new to using cardlayout and I have a few questions on how to implement it. I first would like to know the best way to implement cardlayout so that I can switch from panel to panel. My main question is how to use buttons inside the constructors of my panels to switch from panel to panel. I just started working on this project today so you will see some code that is not finished or that does not make sense. I first tried to make all my classes to extend JFrame but that led to multiple unwanted windows. If I can get some sort of example on how to effectively use cardlayout and how to switch panels using the buttons within my other panel constructors. My attempts on using cardlayout only worked for buttons that I created in my gui class however that is not the result I want. Please help if you can and thanks in advance.

这是我的主要课程.

public class controller{
    public static void main(String[] args){

        new Gui();


    }
}

这是我的 gui 类.

This is my gui class.

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class Gui extends JFrame{
    homePage home = new homePage();
    public JPanel loginPanel = new textEmailLog(), 
    registerPanel = new Register(),
    homePanel = new homePage(), viewPanel  = new emailView(),
    loadPanel = new loadEmail(), contentPanel = new JPanel(new CardLayout());
    CardLayout cardLayout = new CardLayout();


    public Gui(){
        super("Email Database Program");
        setSize(700,700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        contentPanel.setLayout(cardLayout);

        contentPanel.add(loginPanel, "Login");
        contentPanel.add(registerPanel, "Register");
        contentPanel.add(homePanel, "Home");
        contentPanel.add(viewPanel, "View");
        contentPanel.add(loadPanel, "Load");
        this.setContentPane(contentPanel);

        cardLayout.show(contentPanel, "Login");


        setVisible(true);


    }

我的登录面板类

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

//panel has been added
public class textEmailLog extends JPanel{
        JPanel logGui = null;
        JButton registerBut, logBut;
        JTextField Login;

    public textEmailLog(){
        //default characteristics
        setSize(700,700);
        setName("Email Database");
        //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        //Labels for username and password
        JLabel userLab = new JLabel("Username");
        JLabel pwLab = new JLabel("Password");

        //textfields for username and password
        Login = new JTextField("", 15);
        JPasswordField Password = new JPasswordField("", 15);
        Password.setEchoChar('*');

        //login button that confirms username and password
        logBut = new JButton("Login");
        logBut.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                //needs regex checks prior to logging in 

                if(e.getSource() == logBut){
                    /* Change the panel to the homepage
                    if(Login.getText().equals() && Password.getText().equals()){

                    }
                */  
                    new homePage();
                }


            }
        });

        registerBut = new JButton("Register");
        registerBut.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == registerBut){
                    //Change the panel to the register panel
                }
            }

        });

        //Box layout for organization of jcomponents
        Box verticalContainer = Box.createVerticalBox();
        Box horizontalContainer = Box.createHorizontalBox();
        Box mergerContainer = Box.createVerticalBox();


        //add to panel
        verticalContainer.add(Box.createVerticalStrut(300));//begin relative to the center
        verticalContainer.add(userLab);//Login label and text
        verticalContainer.add(Login);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(pwLab);//password label and text
        verticalContainer.add(Password);
        verticalContainer.add(Box.createVerticalStrut(5));
        horizontalContainer.add(registerBut);//register button
        horizontalContainer.add(Box.createHorizontalStrut(5));
        horizontalContainer.add(logBut);//login button

        //combines both the vertical and horizontal container
        mergerContainer.add(verticalContainer);
        mergerContainer.add(horizontalContainer);
        add(mergerContainer);
        //this.add(logGui);
        setVisible(true);

    }

}

我的注册面板类

    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.Box;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    import javax.swing.JTextField;

    //No Panel addition
    public class Register extends JPanel{
            JButton submit, previous;
            JLabel firstLab, lastLab, userLab, passwordLab, repassLab, address, emailAdd, errorLabel;
            JTextField firstText, lastText, userText, addText, emailAddText;
            JPasswordField passwordText, repassText;

        public Register(){
            setSize(700,700);
            //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


            //register values and their labels and textfields
            firstLab = new JLabel("First Name: ");
            firstText = new JTextField("", 25);
            lastLab = new JLabel("Last Name: ");
            lastText = new JTextField("", 40);
            userLab = new JLabel("Username: ");
            userText = new JTextField("", 25);
            passwordLab = new JLabel("Password: ");
            passwordText = new JPasswordField("", 25);
            passwordText.setEchoChar('*');
            repassLab = new JLabel("Confirm Password");
            repassText = new JPasswordField("", 25);
            repassText.setEchoChar('*');
            address = new JLabel("Address: ");
            addText = new JTextField("", 50);
            emailAdd = new JLabel("Email Address: ");
            emailAddText = new JTextField("", 50);

            //error message for reigstration issues
            errorLabel = new JLabel();
            errorLabel.setForeground(Color.red);

            submit = new JButton("Submit");

            submit.addActionListener(new ActionListener(){

                @SuppressWarnings("deprecation")
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    if(e.getSource() == submit){
                        //confirm with regex methods and if statements that have been created and need to be created
                        if(firstText.getText().length() == 0){
                            errorLabel.setText("*You have not entered a first name!");
                        }else
                        if(lastText.getText().length() == 0){
                            errorLabel.setText("*You have not entered a last name!");
                        }else
                        if(userText.getText().length() == 0){
                            errorLabel.setText("*You have not entered a username!");
                        }else
                        if(passwordText.toString().length() == 0){
                            errorLabel.setText("*You have not entered a Password!");
                        }else
                        if(repassText.toString().length() == 0){    
                            errorLabel.setText("*You have not matched your password!");
                        }
                        if(addText.getText().length() == 0){
                            errorLabel.setText("*You have not entered an address!");
                        }else
                        if(emailAddText.getText().length() == 0){
                            errorLabel.setText("*You have not entered an Email address!");
                        }else
                        if(userText.getText().length() < 8){
                            errorLabel.setText("*Username is too short!");
                        }
                        else
                        if(!(passwordText.toString().matches(repassText.toString()))){
                            errorLabel.setText("Passwords do not match!");
                        }
                        else
                        if(!isValidEmailAddress(emailAddText.getText())){
                            errorLabel.setText("*Invalid Email!");
                        }
                        else
                        if(!isValidAddress(addText.getText())){
                            errorLabel.setText("*Invalid Address!");
                        }
                    }
                }

            });
            //returns to the previous page
            previous = new JButton("Previous Page");
            previous.addActionListener(new ActionListener(){

                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    if(e.getSource() == previous){
                        //card.show(login panel);
                    }
                }

            });
            Box verticalContainer = Box.createVerticalBox();
            Box horizontalContainer = Box.createHorizontalBox();
            Box mergerContainer = Box.createVerticalBox();

            verticalContainer.add(Box.createVerticalStrut(150));
            verticalContainer.add(firstLab);
            verticalContainer.add(firstText);
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(lastLab);
            verticalContainer.add(lastText);
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(userLab);
            verticalContainer.add(userText);
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(passwordLab);
            verticalContainer.add(passwordText);
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(repassLab); 
            verticalContainer.add(repassText);  
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(address); 
            verticalContainer.add(addText);
            verticalContainer.add(Box.createVerticalStrut(5));
            verticalContainer.add(emailAdd);
            verticalContainer.add(emailAddText);    
            verticalContainer.add(Box.createVerticalStrut(5));

            //horizontal
            verticalContainer.add(Box.createVerticalStrut(5));
            horizontalContainer.add(submit);
            horizontalContainer.add(Box.createHorizontalStrut(5));
            horizontalContainer.add(previous);

            //merger
            mergerContainer.add(verticalContainer);
            mergerContainer.add(horizontalContainer);

            add(mergerContainer);
            setVisible(true);
        }

        //regex check for valid Email
    public boolean isValidEmailAddress(String email){
            java.util.regex.Pattern p = java.util.regex.Pattern.compile("[A-Za-z0-9._\%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}");
            java.util.regex.Matcher m = p.matcher(email);
            return m.matches();

        }
    //regex check for valid Address
    public boolean isValidAddress(String address){
        java.util.regex.Pattern p = java.util.regex.Pattern.compile("\d{1,3}.?\d{0,3}\s[a-zA-Z]{2,30}\s[a-zA-Z]{2,15}");
        java.util.regex.Matcher m = p.matcher(address);
        return m.matches();

    }
    }

首页面板类

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

//NO Panel Yet
@SuppressWarnings("serial")
public class homePage extends JPanel{

        JButton uploadEmail, viewEmail;
    public homePage(){
        setSize(700,700);
        uploadEmail = new JButton("Upload Your Email");
        uploadEmail.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == uploadEmail){
                    new loadEmail();
                }
            }

        });
        viewEmail = new JButton("View An Email");
        viewEmail.addActionListener(new ActionListener(){       

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == viewEmail){
                    new emailView();
                }
            }

        });

        add(uploadEmail);
        add(viewEmail);
        setVisible(true);
    }
}

我的查看电子邮件面板

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class emailView extends JPanel{
        JPanel viewPanel;
        JButton logout, delete, homepage;
        JTable emailList;

        //Cannot be edited or may be in a new panel
        /*
        JLabel fileLab, toLab, fromLab, subjectLab,topicLab, emailLab, notesLab, attachLab;
        JTextField fileText, toText, fromText, subjectText, topicText;
        JTextArea emailText, notesText, attachText;
        */
    public emailView(){
        setSize(700,700);
        setVisible(true);

        emailList = new JTable();
        logout = new JButton("Logout");
        logout.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == logout){
                    new textEmailLog();
                }
            }

        });
        delete = new JButton("Delete");
        delete.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == delete){

                }
            }

        });
        homepage = new JButton("HomePage");
        homepage.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == homepage){
                    new homePage();
                }

            }

        });
        Box horizontalContainer = Box.createHorizontalBox();
        Box verticalContainer = Box.createVerticalBox();
        Box mergerContainer = Box.createVerticalBox();

        horizontalContainer.add(logout);
        horizontalContainer.add(Box.createHorizontalStrut(5));
        horizontalContainer.add(homepage);
        horizontalContainer.add(Box.createHorizontalStrut(5));
        horizontalContainer.add(delete);
        horizontalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(emailList);
        mergerContainer.add(horizontalContainer);
        mergerContainer.add(verticalContainer);
        add(mergerContainer);

        setVisible(true);
    }
}

我的上传电子邮件面板

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class loadEmail extends JPanel{
        JPanel loadPanel;
        JLabel fileLab, toLab, fromLab, subjectLab, topicLab, emailLab, notesLab, attachLab;
        JTextField fileText, toText, fromText, subjectText, topicText;
        JTextArea emailText, notesText, attachText; //attachment text will be changed
        JButton cancel, complete, enter;//enter may not be necessary
    public loadEmail(){
        setSize(700,700);

        fileLab = new JLabel("Enter a new File: ");
        fileText = new JTextField();
        enter = new JButton("Enter");
        enter.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == enter){
                    //opens file directory window
                }
            }

        });
        toLab = new JLabel("To: ");
        toText = new JTextField();
        toText.setSize(5, 30);
        fromLab = new JLabel("From: ");
        fromText = new JTextField();
        subjectLab = new JLabel("Subject: ");
        subjectText = new JTextField();
        topicLab = new JLabel("Topic: ");
        topicText = new JTextField();
        emailLab = new JLabel("Email Content: ");
        emailText = new JTextArea();
        notesLab = new JLabel("Comments: ");
        notesText = new JTextArea();
        attachLab = new JLabel("Attachments");
        attachText = new JTextArea();
        cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == cancel){
                    //dispose page
                }
            }

        });
        complete = new JButton("Complete");
        complete.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(e.getSource() == complete){
                    //store in database, prompt user for new email to enter in other wise return to homepage

                }
            }

        });

        Box verticalContainer = Box.createVerticalBox();
        Box horizontalContainer = Box.createHorizontalBox();
        Box mergerContainer = Box.createVerticalBox();

        verticalContainer.add(fileLab);
        verticalContainer.add(fileText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(Box.createHorizontalStrut(50));
        verticalContainer.add(enter);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(toLab);
        verticalContainer.add(toText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(fromLab);
        verticalContainer.add(fromText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(subjectLab);
        verticalContainer.add(subjectText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(topicLab);
        verticalContainer.add(topicText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(emailLab);
        verticalContainer.add(emailText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(notesLab);
        verticalContainer.add(notesText);
        verticalContainer.add(Box.createVerticalStrut(5));
        verticalContainer.add(attachLab);
        verticalContainer.add(attachText);
        verticalContainer.add(Box.createVerticalStrut(5));

        horizontalContainer.add(cancel);
        horizontalContainer.add(Box.createHorizontalStrut(5));
        horizontalContainer.add(complete);

        mergerContainer.add(verticalContainer);
        mergerContainer.add(horizontalContainer);
        add(mergerContainer);
        setVisible(true);

    }

}

推荐答案

简短的回答是不要.这样做的原因是你将不得不将父容器和 CardLayout 暴露给你的所有子组件,这不仅使你的应用程序的某些部分暴露于潜在的误用,而且它与导航紧密耦合,使其变得困难将来添加/删除步骤...

The short answer is don't. The reasons for this is you'll end having to expose the parent container and CardLayout to ALL your sub components, which not only exposes portions of your application to potential mistreatment, it tightly couples the navigation making it difficult to add/remove steps in the future...

更好的解决方案是设计某种控制器interface,它定义了每个视图可以做什么(例如showHomenextView, previousView),然后将这个接口的实现传递给每个视图.然后,每个视图将使用此接口根据需要请求更改.

A better solution would be to devise some kind of controller interface, which defines what each view could do (for example showHome, nextView, previousView), you would then pass an implementation of this interface to each view. Each view would then use this interface to request a change as the needed to.

控制器会知道诸如当前视图、主视图以及如何根据需要在某些视图(下一个/上一个)之间移动.

The controller would know things like, the current view, the home view and how to move between certain views (next/previous) as required.

更新了简单的例子

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerAdapter;
import java.awt.event.ContainerEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AllYouViewBelongToMe {

    public static void main(String[] args) {
        new AllYouViewBelongToMe();
    }

    public AllYouViewBelongToMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface ViewContoller {

        public void goHome();

        public void nextView();

        public void previousView();

    }

    public static class DefaultViewController implements ViewContoller {

        public static final String HOME = "home";

        private Component currentView = null;
        private List<Component> views;
        private Map<Component, String> mapNames;

        private Container parent;
        private CardLayout cardLayout;

        public DefaultViewController(Container parent, CardLayout cardLayout) {
            this.parent = parent;
            this.cardLayout = cardLayout;
            views = new ArrayList<>(25);
            mapNames = new HashMap<>(25);
        }

        public CardLayout getCardLayout() {
            return cardLayout;
        }

        public Container getParent() {
            return parent;
        }

        public void addView(Component comp, String name) {
            if (!HOME.equals(name)) {
                views.add(comp);
            }
            mapNames.put(comp, name);
            getParent().add(comp, name);
        }

        public void removeView(Component comp, String name) {
            views.remove(comp);
            mapNames.remove(comp);
            getParent().remove(comp);
        }

        @Override
        public void goHome() {
            currentView = null;
            getCardLayout().show(getParent(), HOME);
        }

        @Override
        public void nextView() {
            if (views.size() > 0) {
                String name = null;
                if (currentView == null) {
                    currentView = views.get(0);
                    name = mapNames.get(currentView);
                } else {
                    int index = views.indexOf(currentView);
                    index++;
                    if (index >= views.size()) {
                        index = 0;
                    }
                    currentView = views.get(index);
                    name = mapNames.get(currentView);
                }
                getCardLayout().show(getParent(), name);
            }
        }

        @Override
        public void previousView() {
            if (views.size() > 0) {
                String name = null;
                if (currentView == null) {
                    currentView = views.get(views.size() - 1);
                    name = mapNames.get(currentView);
                } else {
                    int index = views.indexOf(currentView);
                    index--;
                    if (index < 0) {
                        index = views.size() - 1;
                    }
                    currentView = views.get(index);
                    name = mapNames.get(currentView);
                }
                getCardLayout().show(getParent(), name);
            }
        }

    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());

            CardLayout cardLayout = new CardLayout();
            JPanel view = new JPanel(cardLayout);

            final DefaultViewController controller = new DefaultViewController(view, cardLayout);
            controller.addView(createPane("home"), DefaultViewController.HOME);
            controller.addView(createPane("Page #1"), "View1");
            controller.addView(createPane("Page #2"), "View2");
            controller.addView(createPane("Page #3"), "View3");
            controller.addView(createPane("Page #4"), "View4");

            controller.goHome();

            JPanel controls = new JPanel();
            JButton btnPrev = new JButton("<");
            JButton btnHome = new JButton("Home");
            JButton btnNext = new JButton(">");

            controls.add(btnPrev);
            controls.add(btnHome);
            controls.add(btnNext);

            btnNext.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    controller.nextView();
                }
            });
            btnPrev.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    controller.previousView();
                }
            });
            btnHome.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    controller.goHome();
                }
            });

            add(view);
            add(controls, BorderLayout.SOUTH);

        }

        protected JPanel createPane(String name) {

            JPanel panel = new JPanel(new GridBagLayout());
            panel.add(new JLabel(name));

            return panel;

        }
    }

}

这篇关于如何在java中有效地使用cardlayout以便使用各种面板构造函数中的按钮从面板切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆