JavaGUI——Java图形用户界面

1、Java GUI 概述

GUI(Graphical User Interface,简称 GUI,图形用户界面)是指采用图形方式显示的计算机操作用户界面,与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受。
Java GUI主要有两个核心库,分别是AWT(java.awt:Abstract Windows ToolKit(抽象窗口工具包))和Swing(javax.swing:AWT的扩展),AWT需要调用本地系统方法来实现功能,属重量级控件,而Swing是在AWT的基础上,建立的一套图像界面系统,其中提供了更多的组件,而且完全由Java实现,增强了移植性,属轻量级组件。

2、容器

容器(Container)是组件(Component)的子类,一个容器可以容纳多个组件,并使他们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面,所有的组件都可以通过add()方法加入容器中。容器共有四种类型,分别是窗口(JFrame)、弹窗(JDialog)、面板(JPanel)、滚动面板(JScrollPanel)。

2、1 窗口

Frame或JFrame类用于创建一个具有标题栏的框架窗口作为程序的主要界面,它不依赖其他容器可以单独存在。

public class JFrameUse {
    public static void main(String[] args) {
        // 初始化窗口
        JFrame jFrame = new JFrame("这个是窗口的标题");
        // 设置窗口的位置和大小
        jFrame.setBounds(400, 300, 500, 500);
        // 设置窗口的背景颜色
        jFrame.setBackground(new Color(175, 114, 114));
        // 设置窗口是否可见
        jFrame.setVisible(true);
        // 设置窗口是否可以缩放
        jFrame.setResizable(false);
        /**
         * 设置窗口的相对位置。
         * 如果 comp 整个显示区域在屏幕内, 则将窗口放置到 comp 的中心;
         * 如果 comp 显示区域有部分不在屏幕内, 则将该窗口放置在最接近 comp 中心的一侧;
         * comp 为 null, 表示将窗口放置到屏幕中心。
         */
        jFrame.setLocationRelativeTo(null);
        /**
         * 设置窗口关闭按钮点击后的默认操作, 参考值:
         *     WindowConstants.DO_NOTHING_ON_CLOSE: 不执行任何操作。
         *     WindowConstants.HIDE_ON_CLOSE: 隐藏窗口(不会结束进程), 再次调用 setVisible(true) 将再次显示。
         *     WindowConstants.DISPOSE_ON_CLOSE: 销毁窗口, 如果所有可显示的窗口都被 DISPOSE, 则可能会自动结束进程。
         *     WindowConstants.EXIT_ON_CLOSE: 退出进程。
         */
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

2、2 弹窗和对话框

JDialog,对话框,使用 JDialog 类可以创建自定义有的对话框,或者调用 JOptionPane 中的多个静态方法快速创建各种标准的对话框。
JOptionPane是JavaSwing内部已实现好的,以静态方法的形式提供调用,能够快速方便的弹出要求用户提供值或向其发出通知的标准对话框。主要具有以下几种那类型:

  • showMessageDialog:消息对话框,向用户展示一个消息,没有返回值。
  • showConfirmDialog:确认对话框,询问一个问题是否执行。
  • showInputDialog:输入对话框,要求用户提供某些输入。
  • showOptionDialog:选项对话框,上述三项的大统一,自定义按钮文本,询问用户需要点击哪个按钮。

上述四个类型的方法(包括其若干重载)的参数遵循一致的模式,下面介绍各参数的含义:

  • parentComponent: 对话框的父级组件,决定对话框显示的位置,对话框的显示会尽量紧靠组件的中心,如果传 null,则显示在屏幕的中心。
  • title: 对话框标题。
  • message: 消息内容。
  • optionType: 选项按钮的类型。
  • selectionValues、initialSelectionValue: 提供的输入选项,以及默认选中的选项。
  • icon: 自定义的对话框图标,如果传 null,则图标类型由 messageType 决定。
  • messageType: 消息类型,主要是提供默认的对话框图标。可能的值为:JOptionPane.PLAIN_MESSAGE 简单消息(不使用图标)JOptionPane.INFORMATION_MESSAGE 信息消息(默认)JOptionPane.QUESTION_MESSAGE 问题消息JOptionPane.WARNING_MESSAGE 警告消息JOptionPane.ERROR_MESSAGE 错误消息

对话框

class JOptionPaneUse {
    public JOptionPaneUse() {
        final JFrame jf = new JFrame("测试窗口");
        jf.setSize(400, 400);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        /*
         * 1. 消息对话框(信息消息)
         */
        JButton btn01 = new JButton("showMessageDialog(信息消息)");
        btn01.addActionListener(e -> {
            // 消息对话框无返回, 仅做通知作用
            JOptionPane.showMessageDialog(jf, "通知信息", "消息标题", JOptionPane.INFORMATION_MESSAGE
            );
        });

        /*
         * 2. 消息对话框(警告消息)
         */
        JButton btn02 = new JButton("showMessageDialog(警告消息)");
        btn02.addActionListener(e -> {
            // 消息对话框无返回, 仅做通知作用
            JOptionPane.showMessageDialog(jf, "警告信息", "消息标题", JOptionPane.WARNING_MESSAGE);
        });

        /*
         * 3. 确认对话框
         */
        JButton btn03 = new JButton("showConfirmDialog");
        btn03.addActionListener(e -> {
            /*
             * 返回用户点击的选项, 值为下面三者之一:
             *     是:   JOptionPane.YES_OPTION
             *     否:   JOptionPane.NO_OPTION
             *     取消: JOptionPane.CANCEL_OPTION
             *     关闭: JOptionPane.CLOSED_OPTION
             */
            int result = JOptionPane.showConfirmDialog(jf, "确认删除?", "提示", JOptionPane.YES_NO_CANCEL_OPTION);
            System.out.println("选择结果: " + result);
        });

        /*
         * 4. 输入对话框(文本框输入)
         */
        JButton btn04 = new JButton("showInputDialog(文本框输入)");
        btn04.addActionListener(e -> {
            // 显示输入对话框, 返回输入的内容
            String inputContent = JOptionPane.showInputDialog(jf, "输入你的名字:", "默认内容");
            System.out.println("输入的内容: " + inputContent);
        });

        /*
         * 5. 输入对话框(下拉框选择)
         */
        JButton btn05 = new JButton("showInputDialog(下拉框选择)");
        btn05.addActionListener(e -> {
            Object[] selectionValues = new Object[]{"香蕉", "雪梨", "苹果"};
            // 显示输入对话框, 返回选择的内容, 点击取消或关闭, 则返回null
            Object inputContent = JOptionPane.showInputDialog(jf, "选择一项: ", "标题",
                    JOptionPane.PLAIN_MESSAGE, null, selectionValues, selectionValues[0]);
            System.out.println("输入的内容: " + inputContent);
        });

        /*
         * 6. 选项对话框
         */
        JButton btn06 = new JButton("showOptionDialog");
        btn06.addActionListener(e -> {
            // 选项按钮
            Object[] options = new Object[]{"香蕉", "雪梨", "苹果"};
            // 显示选项对话框, 返回选择的选项索引, 点击关闭按钮返回-1
            int optionSelected = JOptionPane.showOptionDialog(jf, "请点击一个按钮选择一项", "对话框标题",
                    JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE, null,
                    options,    // 如果传null, 则按钮为 optionType 类型所表示的按钮(也就是确认对话框)
                    options[0]
            );
            if (optionSelected >= 0) {
                System.out.println("点击的按钮: " + options[optionSelected]);
            }
        });

        // 垂直排列按钮
        Box vBox = Box.createVerticalBox();
        vBox.add(btn01);
        vBox.add(btn02);
        vBox.add(btn03);
        vBox.add(btn04);
        vBox.add(btn05);
        vBox.add(btn06);

        JPanel panel = new JPanel();
        panel.add(vBox);

        jf.setContentPane(panel);
        jf.setVisible(true);
    }
}
折叠 

自定义弹窗

class JDialogUse {
    public JDialogUse() {
        final JFrame jf = new JFrame("测试窗口");
        jf.setSize(300, 300);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JButton btn = new JButton("显示自定义对话框");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showCustomDialog(jf, jf);
            }
        });

        JPanel panel = new JPanel();
        panel.add(btn);

        jf.setContentPane(panel);
        jf.setVisible(true);
    }

    /**
     * 显示一个自定义的对话框
     *
     * @param owner           对话框的拥有者
     * @param parentComponent 对话框的父级组件
     */
    private static void showCustomDialog(Frame owner, Component parentComponent) {
        // 创建一个模态对话框
        final JDialog dialog = new JDialog(owner, "提示", true);
        // 设置对话框的宽高
        dialog.setSize(250, 150);
        // 设置对话框大小不可改变
        dialog.setResizable(false);
        // 设置对话框相对显示的位置
        dialog.setLocationRelativeTo(parentComponent);

        // 创建一个标签显示消息内容
        JLabel messageLabel = new JLabel("对话框消息内容");

        // 创建一个按钮用于关闭对话框
        JButton okBtn = new JButton("确定");
        okBtn.addActionListener(e -> {
            // 关闭对话框
            dialog.dispose();
        });

        // 创建对话框的内容面板, 在面板内可以根据自己的需要添加任何组件并做任意是布局
        JPanel panel = new JPanel();

        // 添加组件到面板
        panel.add(messageLabel);
        panel.add(okBtn);

        // 设置对话框的内容面板
        dialog.setContentPane(panel);
        // 显示对话框
        dialog.setVisible(true);
    }
}
折叠 

2、3 面板

面板也是一个容器,但是它不能单独存在,只能存在于窗口中,一个面板对象代表了一个长方形的区域,在这个区域中可以容纳其他组件,在程序中通常会使面板来实现一些特殊的布局。

普通面板

public class JPanelUse {
    public static void main(String[] args) {
        // 初始化窗口
        JFrame jFrame = new JFrame("面板窗口");
        jFrame.setVisible(true);
        jFrame.setSize(400, 400);
        jFrame.setLocationRelativeTo(null);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        // 初始化面板:采用默认的流式布局或指定布局
        JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        // 设置面板大小
        jPanel.setSize(100, 100);
        // 设置面板背景颜色
        jPanel.setBackground(new Color(164, 24, 24));
        // 将面板添加到窗口
        jFrame.add(jPanel);
    }
}

滚动面板

JScrollPane,滚动面板,支持水平和垂直滚动视图。文本区域、表格等需要显示较多数据而空间又有限时,通常使用 JScrollPane 进行包裹以实现滚动显示。

public class JScrollPaneUse {
    public JScrollPaneUse() {
        JFrame jFrame = new JFrame("面板窗口");

        // 创建文本区域组件
        JTextArea textArea = new JTextArea("这是一个文本");
        // 自动换行
        textArea.setLineWrap(true);
        // 设置字体
        textArea.setFont(new Font(null, Font.PLAIN, 18));

        // 初始化滚动面板面板
        /**
         * 全参构造参数说明:
         *     view: 需要滚动显示的视图组件
         *     vsbPolicy: 垂直滚动条的显示策略
         *         ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED    // 需要时显示(默认)
         *         ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER        // 从不显示
         *         ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS       // 总是显示
         *     hsbPolicy: 水平滚动条的显示策略
         *         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED  // 需要时显示(默认)
         *         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER      // 从不显示
         *         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS     // 总是显示
         * 常用方法
         *     设置滚动显示视图内容组件:setViewportView(Component view)
         *     设置垂直滚动条的显示策略:setVerticalScrollBarPolicy(int policy)
         *     设置水平滚动条的显示策略:setHorizontalScrollBarPolicy(int policy)
         */
        JScrollPane jScrollPane = new JScrollPane(
                textArea,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
        );
        jFrame.setContentPane(jScrollPane);

        // 窗口设置为公共代码,后面全部省略
        jFrame.setVisible(true);
        jFrame.setSize(400, 400);
        jFrame.setLocationRelativeTo(null);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

分隔面板

JSplitPane,分隔面板,用于分隔两个(只能两个)组件,两个组件通过水平/垂直分隔条分别 左右 或 上下 显示,并且可以拖动分隔条调整两个组件显示区域的大小。

class JSplitPaneUse{
    public JSplitPaneUse() {
        JFrame jFrame = new JFrame("分隔面板窗口");

        /**
         * 全参构造参数说明
         *      orientation: 分隔的方向(默认水平),HORIZONTAL_SPLIT:水平左右分隔;VERTICAL_SPLIT:垂直上下分隔
         *      continuousLayout: 拖动分隔条时,是否连续重绘组件,如果为flase,则拖动分隔条停止后才重绘组件。
         *      leftComponent: 左边/上面 显示的组件
         *      rightComponent: 右边/下面 显示的组件
         * 常用方法
         *    setOrientation(int orientation): 设置分隔的方向,水平(左右) 或 垂直(上下) 分隔
         *    setLeftComponent(Component comp):设置 左边/上面 显示的组件
         *    setRightComponent(Component comp):设置 左边/下面 显示的组件
         *    setContinuousLayout(boolean continuousLayout): 设置 拖动分隔条 时是否 连续重绘 组件
         *    setOneTouchExpandable(boolean newValue):分隔条上是否显示快速 折叠/展开 两边组件的小按钮
         *    setDividerSize(int newSize):设置分隔条的大小(宽度)
         *    setDividerLocation(int location):设置分隔条的位置,相对于 左边/顶部 的像素长度
         */
        JSplitPane jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JButton("左边按钮"), new JButton("右边按钮"));
        jSplitPane.setDividerLocation(200);

        jFrame.setContentPane(jSplitPane);
        // 省略公共代码
    }
}

选项卡面板

JTabbedPane,选项卡面板。它允许用户通过点击给定标题或图标的选项卡,在一组组件之间进行切换显示。

class JTabbedPaneUse {
    public JTabbedPaneUse() {
        JFrame jFrame = new JFrame("选项卡面板窗口");

        /**
         * 全参构造参数说明:
         *     tabPlacement: 选项卡标题的位置, 值为 JTabbedPane.TOP/BOTTOM/LEFT/RIGHT, 默认为 TOP
         *     tabLayoutPolicy: 选项卡位置不能放入所有的选项卡时,放置选项卡的策略,值JTabbedPane.WRAP_TAB_LAYOUT/SCROLL_TAB_LAYOUT
         * 常用方法
         *     addTab(String 标题, Icon 图标, Component 内容组件, String 提示文本):添加选择项卡
         *     insertTab(String title, Icon icon, Component component, String tip, int index):在指定位置插入选项卡
         *     remove(Component component):移除指定内容控件的选项卡
         *     remove(int index):移除指定位置的选项
         *     setSelectedIndex(int index):设置当前选中的选项卡
         *     getSelectedIndex():获取当前选中的选项卡索引
         *     getSelectedComponent():获取当前选中的选项卡对应的内容组件
         *     setTitleAt(int index, String title):设置 index 位置的选项卡的标题
         *     setIconAt(int index, Icon icon):设置 index 位置的选项卡的图标
         *     setEnabledAt(int index, boolean enabled):设置 index 位置的选项卡是否可用
         *     setComponentAt(int index, Component component):将 index 位置的内容组件设置为 component
         */
        // 初始化一个选项面板,默认选项卡在顶部,放不下了换行
        JTabbedPane jTabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);

        // 创建选项卡
        jTabbedPane.addTab("选项卡1", new JButton("测试按钮"));
        jTabbedPane.addTab("选项卡2", new JButton("测试按钮"));
        jFrame.setContentPane(jTabbedPane);

        // 省略公共代码
    }
}

3、布局

3.1、流式布局

FlowLayout,流式布局管理器,按水平方向依次排列放置组件,排满一行,换下一行继续排列。排列方向(左到右 或 右到左)取决于容器的componentOrientation属性(该属性属于Component),它可能的值如下:

  • ComponentOrientation.LEFT_TO_RIGHT(默认)
  • ComponentOrientation.RIGHT_TO_LEFT

同一行(水平方向)的组件的对齐方式由 FlowLayout 的align属性确定,它可能的值如下:

  • FlowLayout.LEFT : 左对齐
  • FlowLayout.CENTER : 居中对齐(默认)
  • FlowLayout.RIGHT : 右对齐
  • FlowLayout.LEADING : 与容器方向的开始边对齐,例如,对于从左到右的方向,则与左边对齐
  • FlowLayout.TRAILING : 与容器方向的结束边对齐,例如,对于从左到右的方向,则与右边对齐。
class FlowLayoutUse {
    public FlowLayoutUse() {
        JFrame jFrame = new JFrame("流式布局窗口");

        // 创建面板并指定为流式布局
        JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        // 创建两个按钮
        JButton jButton1 = new JButton("按钮1");
        JButton jButton2 = new JButton("按钮2");
        // 将按钮添加到面板中
        jPanel.add(jButton1);
        jPanel.add(jButton2);
        // 将面板添加到窗口中
        jFrame.setContentPane(jPanel);

        // 省略公共代码
    }
}

3.2、网格布局

GridLayout,网格布局管理器,它以矩形网格形式对容器的组件进行布置,把容器按行列分成大小相等的矩形网格,一个网格中放置一个组件,组件宽高自动撑满网格。
以行数和总数优先: 通过构造方法或 setRows 和 setColumns 方法将行数和列数都设置为非零值时,指定的列数将被忽略。列数通过指定的行数和布局中的组件总数来确定。因此,例如,如果指定了三行和两列,在布局中添加了九个组件,则它们将显示为三行三列。仅当将行数设置为零时,指定列数才对布局有效。

class GridLayoutUse {
    public GridLayoutUse() {
        JFrame jFrame = new JFrame("网格布局窗口");

        // 创建一个面板并使用网格布局
        JPanel jPanel = new JPanel(new GridLayout(2, 2));
        // 创建五个按钮,测试2行2列超出效果
        JButton jButton1 = new JButton("按钮1");
        JButton jButton2 = new JButton("按钮2");
        JButton jButton3 = new JButton("按钮3");
        JButton jButton4 = new JButton("按钮4");
        JButton jButton5 = new JButton("按钮5");
        jPanel.add(jButton1);
        jPanel.add(jButton2);
        jPanel.add(jButton3);
        jPanel.add(jButton4);
        jPanel.add(jButton5);
        jFrame.setContentPane(jPanel);

        // 省略公共代码
    }
}

3.3、边框布局

BorderLayout,边界布局管理器,它把 Container 按方位分为 5 个区域(东、西、南、北、中),每个区域放置一个组件。

class BorderLayoutUse {
    public BorderLayoutUse() {
        JFrame jFrame = new JFrame("网格布局窗口");

        // 创建一个面板并使用边框布局
        JPanel jPanel = new JPanel(new BorderLayout());
        // 创建五个按钮,测试2行2列超出效果
        JButton jButton1 = new JButton("东");
        JButton jButton2 = new JButton("西");
        JButton jButton3 = new JButton("南");
        JButton jButton4 = new JButton("北");
        JButton jButton5 = new JButton("中");
        jPanel.add(jButton1, BorderLayout.EAST);
        jPanel.add(jButton2, BorderLayout.WEST);
        jPanel.add(jButton3, BorderLayout.SOUTH);
        jPanel.add(jButton4, BorderLayout.NORTH);
        jPanel.add(jButton5, BorderLayout.CENTER);
        jFrame.setContentPane(jPanel);

        // 省略公共代码
    }
}

4、组件

4.1、基本组件

标签

JLabel,标签,主要用于展示文本图片,也可以同时显示文本和图片。

class JLabelUse {
    public JLabelUse() {
        JFrame jFrame = new JFrame("标签窗口");
        JPanel jPanel = new JPanel();

        // 只显示文本的标签
        JLabel textLabel = new JLabel("只显示文本的标签");
        textLabel.setFont(new Font(null, Font.PLAIN, 25));
        jPanel.add(textLabel);

        // 只显示图片的标签
        JLabel imgLabel = new JLabel(new ImageIcon("bj.jpg"));
        jPanel.add(imgLabel);

        // 同时显示文本和图片的标签:水平方向文本在图片中心
        JLabel jLabel = new JLabel("显示文本", new ImageIcon("bj.jpg"), SwingConstants.CENTER);
        jPanel.add(jLabel);
		
        jFrame.setContentPane(jPanel);
        // 省略公共代码
    }
}

按钮

class JButtonAndRadioAndCheckBox {
    public JButtonAndRadioAndCheckBox() {
        JFrame jFrame = new JFrame("标签窗口");
        JPanel jPanel = new JPanel();

        /**
         * 普通图片按钮
         */
        JButton jButton = new JButton("图片按钮", new ImageIcon("bj.jpg"));
        jButton.addActionListener(e -> {
            System.out.println("图片按钮被点击了");
        });
        jPanel.add(jButton);

        /**
         * 单选按钮
         */
        // 创建按钮组,将单选按钮添加到该组,确保只能选择其一
        ButtonGroup buttonGroup = new ButtonGroup();
        // 创建单选按钮
        JRadioButton man = new JRadioButton("男");
        JRadioButton woman = new JRadioButton("女");
        // 设置第一个被选中
        man.setSelected(true);
        // 将按钮添加到按钮组中
        buttonGroup.add(man);
        buttonGroup.add(woman);
        // 将按钮添加到面板中
        jPanel.add(man);
        jPanel.add(woman);

        /**
         * 多选按钮
         */
        // 添加多选按钮
        JCheckBox jCheckBox1 = new JCheckBox("香蕉");
        JCheckBox jCheckBox2 = new JCheckBox("苹果");
        JCheckBox jCheckBox3 = new JCheckBox("梨子");
        JCheckBox jCheckBox4 = new JCheckBox("黄瓜");
        // 添加事件监听,添加第一个复选框的状态被改变的监听(其他复选框如果需要监听状态改变,则可按此方法添加监听)
        jCheckBox1.addChangeListener(e -> {
            // 获取事件源(即复选框本身)
            JCheckBox jCheckBox = (JCheckBox) e.getSource();
            System.out.println(jCheckBox.getText() + " 是否选中: " + jCheckBox.isSelected());
        });
        jCheckBox1.setSelected(true);
        jPanel.add(jCheckBox1);
        jPanel.add(jCheckBox2);
        jPanel.add(jCheckBox3);
        jPanel.add(jCheckBox4);


        jFrame.setContentPane(jPanel);
       // 省略公共代码
    }
}
折叠 

列表

JComboBox,下拉框。JComboBox以下列列表的形式展示多个选项,用户可以从下拉列表中选择一个值。如果设置JComboBox为可编辑状态,除了选择指定的选项值外,还允许用户自行输入值(自行输入的值索引为-1)。

JList,列表框。JList 以列表的形式展示多个选项,允许用户选择一个或多个选项。其中的选项内容由一个 ListModel 实例来维护。JList 不实现直接滚动,需要滚动显示,可以结合 JScrollPane 实现滚动效果。

class JComboBoxAndJList {
    public JComboBoxAndJList() {
        JFrame jFrame = new JFrame("列表窗口");
        JPanel jPanel = new JPanel();
        JLabel jLabel = new JLabel("水果");

        /**
         * 下拉框:这里的数组列表可以使用Vector<String>集合进行
         */
        final JComboBox<String> jComboBox = new JComboBox<>(new String[]{"香蕉", "雪梨", "苹果", "荔枝"});
        // 添加条目选中状态改变的监听器
        jComboBox.addItemListener(e -> {
            // 只处理选中的状态
            if (e.getStateChange() == ItemEvent.SELECTED) {
                System.out.println("选中: " + jComboBox.getSelectedIndex() + " = " + jComboBox.getSelectedItem());
            }
        });
        jPanel.add(jLabel);
        jPanel.add(jComboBox);

        /**
         * 列表框
         */
        final JList<String> jList = new JList<>();
        // 设置一下首选大小
        jList.setPreferredSize(new Dimension(200, 100));
        // 允许可间断的多选
        jList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        // 设置选项数据(内部将自动封装成 ListModel ),这里的数组列表可以使用Vector<String>集合进行
        jList.setListData(new String[]{"香蕉", "雪梨", "苹果", "荔枝"});
        // 添加选项选中状态被改变的监听器
        jList.addListSelectionListener(e -> {
            // 获取所有被选中的选项索引
            int[] indices = jList.getSelectedIndices();
            // 获取选项数据的 ListModel
            ListModel<String> listModel = jList.getModel();
            // 输出选中的选项
            for (int index : indices) {
                System.out.println("选中: " + index + " = " + listModel.getElementAt(index));
            }
            System.out.println();
        });
        jPanel.add(jList);

        jFrame.setContentPane(jPanel);
      // 省略公共代码
    }
}
折叠 

文本框

JTextField,文本框。JTextField 用来编辑单行的文本。

JPasswordField,密码框。JPasswordField 继承自 JTextField,只是显示输入的内容时用特定的字符替换显示(例如 * 或 ●),用法和 JTextField 基本一致。

JTextArea,文本区域。JTextArea 用来编辑多行的文本。JTextArea 除了允许多行编辑外,其他基本用法和 JTextField 基本一致。

class JTextFieldAndJPasswordFieldAndJTextAreaUse {
    public JTextFieldAndJPasswordFieldAndJTextAreaUse() {
        JFrame jFrame = new JFrame("列表窗口");
        JPanel jPanel = new JPanel(new GridLayout(3,1));

        /**
         * 文本框
         */
        final JTextField jTextField = new JTextField(10);
        jTextField.setFont(new Font(null, Font.PLAIN, 20));
        jPanel.add(new JLabel("用户名"));
        jPanel.add(jTextField);

        /**
         * 密码框
         */
        final JPasswordField jPasswordField = new JPasswordField(32);
        jPanel.add(new JLabel("密 码"));
        jPanel.add(jPasswordField);

        /**
         * 文本域
         */
        // 创建一个 5 行 10 列的文本区域
        JTextArea jTextArea = new JTextArea(5, 10);
        // 自动换行
        jTextArea.setLineWrap(true);
        jPanel.add(new JLabel("文本域"));
        jPanel.add(jTextArea);

        jFrame.setContentPane(jPanel);
        // 省略公共代码
    }
}

进度条和滑块

JProgressBar,进度条。以可视化形式显示某些任务进度的组件,进度条中心可显示进度百分比的文本表示形式。一个任务的进度长度未知时,可将进度条设置为不确定模式。不确定模式的进度条持续地显示动画来表示正进行的操作。当可以确定任务长度和进度量时,则可设置进度条的最大最小值,以及更新进度条的进度值,将其切换回确定模式。

JSlider,滑块。以图形方式在有界区间内通过移动滑块来选择值的组件。滑块可以显示主刻度标记以及主刻度之间的次刻度标记。刻度标记之间的值的个数由 setMajorTickSpacing(int) 和 setMinorTickSpacing(int) 来控制。刻度标记的绘制由 setPaintTicks(boolean) 控制。滑块也可以在固定时间间隔(或在任意位置)沿滑块刻度打印文本标签。标签的绘制由 setLabelTable(Dictionary) 和 setPaintLabels(boolean) 控制。
PS: 当滑块获得焦点后,按键盘上的 上下左右键 也可以滑动滑块。

class JProgressBarAndJSliderUse {
    public JProgressBarAndJSliderUse() {
        JFrame jFrame = new JFrame("列表窗口");
        JPanel jPanel = new JPanel(new GridLayout(3, 1));

        /**
         * 进度条:
         *     全参构造参数说明:JProgressBar(int orient, int min, int max)
         *         orient: 进度条的方向,SwingConstants.VERTICAL 或 SwingConstants.HORIZONTAL,默认为水平方向
         *         min: 最小进度值;max: 最大进度值
         *     常用方法:
         *         设置最小进度值、最大进度值和当前进度值:setMinimum(int min),setMaximum(int max),setValue(int n)
         *         获取当前进度值:getValue()
         *         获取当前进度的百分比:getPercentComplete()
         *         是否绘制百分比文本(进度条中间显示的百分数):setStringPainted(boolean b)
         *         设置进度条进度是否为不确定模式:setIndeterminate(boolean newValue)
         *         设置进度条的方向,SwingConstants.VERTICAL 或 SwingConstants.HORIZONTAL:setOrientation(int newOrientation)
         *         添加进度条的进度改变监听器:addChangeListener(ChangeListener l)
         */
        JProgressBar jProgressBar = new JProgressBar(0, 100);
        jProgressBar.setValue(20);
        jProgressBar.addChangeListener(e -> {
            System.out.println("当前进度值: " + jProgressBar.getValue() + "; " +
                    "进度百分比: " + jProgressBar.getPercentComplete());
        });
        jPanel.add(jProgressBar);

        /**
         * 滑块:
         *     全参构造参数说明:JSlider(int orientation, int min, int max, int value)
         *         orientation: 滑块的方向,SwingConstants.VERTICAL 或 SwingConstants.HORIZONTAL,默认为水平方向
         *         min: 滑块的最小值; max: 滑块的最大值
         *         value: 滑块的初始值(默认为 最小值 和 最大值 之间的 中间值)
         *     常用方法:
         *         设置滑块的最小值、最大值、当前值:setMinimum(int min),setMaximum(int max),setValue(int n)
         *         获取滑块的当前值:getValue()
         *         设置主刻度标记间隔:setMajorTickSpacing(int n)
         *         设置单个主刻度内的次刻度标记间隔:setMinorTickSpacing(int n)
         *         设置是否绘制刻度线:setPaintTicks(boolean b)
         *         设置是否绘制刻度标签(刻度值文本):setPaintLabels(boolean b)
         *         设置是否绘制滑道:setPaintTrack(boolean b)
         *         设置是否颠倒刻度值(刻度值从大到小):setInverted(boolean b)
         *         设置滑块是否对齐到刻度。设置为 true,则滑块最终只能在有刻度的位置取值,即滑块取值不连续:setSnapToTicks(boolean b)
         *         添加滑块的值改变监听器:addChangeListener(ChangeListener l)
         */
        JSlider jSlider = new JSlider(0, 20, 10);
        // 设置主刻度间隔
        jSlider.setMajorTickSpacing(5);
        // 设置次刻度间隔
        jSlider.setMinorTickSpacing(1);
        // 绘制刻度和标签
        jSlider.setPaintTicks(true);
        jSlider.setPaintLabels(true);
        jSlider.addChangeListener(e -> {
            System.out.println("当前值: " + jSlider.getValue());
        });
        jPanel.add(jSlider);

        jFrame.setContentPane(jPanel);
        // 省略公共代码
    }
}
折叠 

4.2、复杂组件

文件和颜色选择器

JFileChooser,文件选取器。JFileChooser为用户选择文件提供了一种简单的机制,包括打开文件和保存文件。
构造方法和常用方法如下:

方法

功能

JFileChooser(String currentDirectoryPath)

currentDirectoryPath: 打开文件选取器时默认显示的文件夹(默认为用户文件夹)

JFileChooser(File currentDirectory)

currentDirectory: 打开文件选取器时默认显示的文件夹(默认为用户文件夹)

void setCurrentDirectory(File dir)

设置默认显示的文件夹

void setFileSelectionMode(int mode)

设置文件选择模式,FILES_AND_DIRECTORIES: 文件和文件夹都可以选,其他的二选一

void setMultiSelectionEnabled(boolean b)

设置是否允许同时选择多个(默认为不允许)

void addChoosableFileFilter(FileFilter filter)

添加可供用户选择的文件过滤器

void setFileFilter(FileFilter filter)

设置默认使用的文件过滤器

void setSelectedFile(File file)

设置默认被选中的文件

File[] getSelectedFiles()

获取选择的文件(一般在用户选择完文件点击了确认或保存后通过该方法获取选中的文件)

class FileSelectedUse {
    public FileSelectedUse() {
        JFrame jFrame = new JFrame();
        JPanel jPanel = new JPanel();

        /**
         * 显示 打开文件 或 保存文件 的对话框(线程将被阻塞, 直到选择框被关闭):showOpenDialog(Component parent), showSaveDialog(Component parent)
         *     参数:
         *         parent: 文件选取器对话框的父组件, 对话框将会尽量显示在靠近 parent 的中心; 如果传 null, 则显示在屏幕中心。
         *     返回值:
         *         JFileChooser.CANCEL_OPTION: 点击了取消或关闭
         *         JFileChooser.APPROVE_OPTION: 点击了确认或保存
         *         JFileChooser.ERROR_OPTION: 出现错误
         */
        final JTextArea jTextArea = new JTextArea(10, 30);
        jTextArea.setLineWrap(true);
        jPanel.add(jTextArea);

        JButton openBtn = new JButton("打开");
        openBtn.addActionListener(e -> showFileOpenDialog(jFrame, jTextArea));
        jPanel.add(openBtn);

        JButton saveBtn = new JButton("保存");
        saveBtn.addActionListener(e -> showFileSaveDialog(jFrame, jTextArea));
        jPanel.add(saveBtn);

        jFrame.setContentPane(jPanel);
        // 省略公共代码
    }

    /**
     * 打开文件
     * @param parent 组件
     * @param msgTextArea 文本域
     */
    private static void showFileOpenDialog(Component parent, JTextArea msgTextArea) {
        // 创建一个默认的文件选取器
        JFileChooser fileChooser = new JFileChooser();
        // 设置默认显示的文件夹为当前文件夹
        fileChooser.setCurrentDirectory(new File("."));
        // 设置文件选择的模式(只选文件、只选文件夹、文件和文件均可选)
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        // 设置是否允许多选
        fileChooser.setMultiSelectionEnabled(true);
        // 添加可用的文件过滤器(FileNameExtensionFilter 的第一个参数是描述, 后面是需要过滤的文件扩展名 可变参数)
        fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("zip(*.zip, *.rar)", "zip", "rar"));
        // 设置默认使用的文件过滤器
        fileChooser.setFileFilter(new FileNameExtensionFilter("image(*.jpg, *.png, *.gif)", "jpg", "png", "gif"));
        // 打开文件选择框(线程将被阻塞, 直到选择框被关闭)
        int result = fileChooser.showOpenDialog(parent);
        if (result == JFileChooser.APPROVE_OPTION) {
            // 如果点击了"确定", 则获取选择的文件路径
            File file = fileChooser.getSelectedFile();
            // 如果允许选择多个文件, 则通过下面方法获取选择的所有文件
            msgTextArea.append("打开文件: " + file.getAbsolutePath() + "\n\n");
        }
    }

    /**
     * 选择文件保存路径
     * @param parent 组件
     * @param msgTextArea 文本域
     */
    private static void showFileSaveDialog(Component parent, JTextArea msgTextArea) {
        // 创建一个默认的文件选取器
        JFileChooser fileChooser = new JFileChooser();
        // 设置打开文件选择框后默认输入的文件名
        fileChooser.setSelectedFile(new File("测试文件.zip"));
        // 打开文件选择框(线程将被阻塞, 直到选择框被关闭)
        int result = fileChooser.showSaveDialog(parent);
        if (result == JFileChooser.APPROVE_OPTION) {
            // 如果点击了"保存", 则获取选择的保存路径
            File file = fileChooser.getSelectedFile();
            msgTextArea.append("保存到文件: " + file.getAbsolutePath() + "\n\n");
        }
    }
}
折叠 

JColorChooser,颜色选取器。JColorChooser提供一个用于允许用户操作和选择颜色的控制器对话框。

class ColorSelectedUse {
    public ColorSelectedUse() {
        JFrame jFrame = new JFrame();
        JPanel jPanel = new JPanel();
        final JLabel jLabel = new JLabel();
        jLabel.setPreferredSize(new Dimension(150, 150));
        jLabel.setOpaque(true);
        jPanel.add(jLabel);

        JButton jButton = new JButton("选择颜色");
        jButton.addActionListener(e -> {
            /**
             * 显示一个颜色选取器对话框(线程将被阻塞, 直到对话框被关闭)
             *     参数说明:
             *          component: 对话框的父组件, 对话框将紧靠 component 的中心显示; 如果传 null, 则对话框显示在屏幕中心。
             *          title: 对话框标题。
             *          initialColor: 初始选中的颜色; 如果传 null, 则默认为非透明白色。
             *      返回值:
             *          返回选择的颜色; 如果点击了取消或关闭, 则返回 null。
             */
            Color color = JColorChooser.showDialog(jFrame, "选取颜色", null);
            // 如果用户取消或关闭窗口, 则返回的 color 为 null
            if (color == null) {
                return;
            }
            // 把选取的颜色设置为标签的背景
            jLabel.setBackground(color);
            // 获取颜色的 ARGB 各个分量值
            int alpha = color.getAlpha();
            int red = color.getRed();
            int green = color.getGreen();
            int blue = color.getBlue();
            jLabel.setText("A=" + String.format("%02x", alpha) + ", " +
                    String.format("#%02x%02x%02x", red, green, blue));
        });
        jPanel.add(jButton);

        jFrame.setContentPane(jPanel);
        // 省略公共代码
    }
}

菜单栏和工具栏

JMenuBar,菜单栏。菜单栏组件添加到 JFrame 窗口后,在窗口的内容显示区域的顶部出现。实现一个菜单栏主要涉及三种类:

  • JMenuBar:表示一个菜单栏。
  • JMenu:表示菜单栏上的一个一级菜单。
  • JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem:表示一级菜单下的一个子菜单项,三者分别表示 普通的子菜单、带复选框的子菜单、带单选按钮的子菜单。

PS: JMenu 继承自 JMenuItem,所以一个 JMenu 也可以当做是一个二级子菜单项,通过 JMenu 和 JMenuItem 之间的嵌套,可实现多级子菜单效果。
构造参数和常用方法如下

方法

功能

JMenuItem

void setText(String text)

设置菜单显示的文本

JMenuItem

void setIcon(Icon defaultIcon)

设置菜单显示的图标

全参构造

JMenuItem(String text, Icon icon)

text: 菜单显示的文本,icon: 菜单显示的图标

JMenuItem

void setMnemonic(int mnemonic)

设置菜单的键盘助记符

JMenuItem

void setAccelerator(KeyStroke keyStroke)

设置修改键,使用键盘快捷键直接触发菜单项的动作

JMenuItem

void addActionListener(ActionListener l)

添加菜单被点击的监听器

JMenuItem

void setActionCommand(String actionCommand)

可以再监听器回调时通过命令名称区别是哪个菜单项触发的动作。

JMenu

JMenuItem add(JMenuItem menuItem)

添加子菜单到JMenu中

JMenu

void addSeparator()

添加一个子菜单分割线

class JMenuBarUse{
    public JMenuBarUse() {
        JFrame jFrame = new JFrame();
        JPanel jPanel = new JPanel();

        // 创建一个菜单栏
        JMenuBar jMenuBar = new JMenuBar();
        
        // 创建一级菜单
        JMenu fileMenu = new JMenu("文件");
        JMenu editMenu = new JMenu("编辑");
        // 将一级菜单添加到菜单栏
        jMenuBar.add(fileMenu);
        jMenuBar.add(editMenu);
        
        // 创建文件菜单的子菜单
        JMenuItem openMenuItem  = new JMenuItem("打开");
        JMenuItem newMenuItem  = new JMenuItem("新建");
        fileMenu.add(newMenuItem);
        fileMenu.add(openMenuItem);

        jPanel.add(jMenuBar);
        // 省略公共代码
    }
}

JToolBar,工具栏。JToolBar 提供了一个用来显示常用控件的容器组件。
对于大多数的外观,用户可以将工具栏拖到其父容器四“边”中的一边,并支持在单独的窗口中浮动显示。为了正确执行拖动,建议将 JToolBar 实例添加到容器四“边”中的一边(其中容器的布局管理器为 BorderLayout),并且不在其他四“边”中添加任何子级。
构造方法和常用方法如下:

方法

功能

JToolBar(String name, int orientation)

name: 工具栏名称,悬浮显示时为悬浮窗口的标题。orientation: 工具栏方向,默认水平

Component add(Component comp)

添加 工具组件 到 工具栏

void addSeparator(Dimension size)

添加 分隔符组件 到 工具栏

Component getComponentAtIndex(int index)

获取工具栏中指定位置的组件(包括分隔符)

void setFloatable(boolean b)

设置工具栏是否可拖动

void setOrientation(int o)

设置工具栏方向,值为 SwingConstants.HORIZONTAL 或 SwingConstants.VERTICAL

void setMargin(Insets m)

设置工具栏边缘和其内部工具组件之间的边距(内边距)

void setBorderPainted(boolean b)

是否需要绘制边框

class JToolBarUse{
    public JToolBarUse() {
        JFrame jFrame = new JFrame();
        JPanel jPanel = new JPanel();

        // 创建一个工具栏
        JToolBar jToolBar = new JToolBar("测试工具栏");
        JButton jButton = new JButton("按钮");
        jToolBar.add(jButton);

        jPanel.add(jToolBar);
        // 省略公共代码
    }
}

5、事件

5.1、鼠标监听事件

class MouseListenerUse {
    public MouseListenerUse() {
        JFrame jFrame = new JFrame("鼠标监听");
        JPanel jPanel = new JPanel();

        /**
         * 鼠标监听器
         */
        jPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("鼠标进入组件区域");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("鼠标离开组建区域");
            }

            @Override
            public void mousePressed(MouseEvent e) {
                // 获取按下的坐标(相对于组件)
                System.out.println("相对组件" + e.getPoint() + ",横坐标:" + e.getX() + ", 纵坐标:" + e.getY());
                // 获取按下的坐标(相对于屏幕)
                System.out.println("相对屏幕" + e.getLocationOnScreen() + ",横坐标:" + e.getXOnScreen() + ", 纵坐标:" + e.getYOnScreen());
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("鼠标释放");
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                // 鼠标在组件区域内按下并释放(中间没有移动光标)才识别为被点击
                System.out.println("鼠标点击");
            }
        });

        /**
         * 鼠标移动/拖动监听器
         */
        jPanel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // 鼠标保持按下状态移动即为拖动
                System.out.println("鼠标拖动");
            }
            @Override
            public void mouseMoved(MouseEvent e) {
                System.out.println("鼠标移动");
            }
        });


        /**
         * 鼠标滚轮监听器
         */
        jPanel.addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                // e.getWheelRotation() 为滚轮滚动多少的度量
                System.out.println("mouseWheelMoved: " + e.getWheelRotation());
            }
        });

       // 省略公共代码
    }
}
折叠 

5.2、键盘监听事件

组件监听键盘的按键,该组件必须要获取到焦点。

如果一个窗口内没有可获取焦点的组件,一般打开窗口后焦点为窗口所有,可以把键盘监听器设置到窗口(JFrame)身上。

如果窗口内还有其他组件可获取焦点(例如按钮、文本框),窗口打开后焦点会被内部组件获得,如果想要在窗口打开期间都能监听键盘按键,可以为所有可获得焦点的组件都设置一个键盘监听器。

class KeyListenerUse{
    public KeyListenerUse() {
        JFrame jFrame = new JFrame("键盘监听");
        jFrame.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                // 获取键值,和 KeyEvent.VK_XXXX 常量比较确定所按下的按键
                System.out.println("按下: " + e.getKeyCode() + ",键值为:" + e.getKeyCode());
            }

            @Override
            public void keyTyped(KeyEvent e) {
                // e.getKeyChar() 获取键入的字符
                System.out.println("键入: " + e.getKeyChar());
            }

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("释放: " + e.getKeyCode());
            }
        });
        jFrame.setVisible(true);
    }
}

5.3、窗口监听事件

窗口监听器只有窗口类组件支持,例如 JFrame、JDialog。目前经过测试,使用最多的莫过于窗口关闭和窗口激活。

class WindowListenerUse{
    public WindowListenerUse() {
        JFrame jFrame = new JFrame("窗口监听");
        jFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("窗口被关闭了");
            }

            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("窗口被激活了");
            }
        });
        jFrame.setVisible(true);
    }
}
本文链接:https://www.dzdvip.com/35218.html 版权声明:本文内容均来源于互联网。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 395045033@qq.com,一经查实,本站将立刻删除。
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年7月17日 00:16
下一篇 2022年7月17日 11:16

相关推荐

  • 手机副屏有什么用(哪款手机有副屏)

    曾经的手机只有一块小小的屏幕,甚至不能触摸,随着科技的发展我们逐渐拥抱大屏,仿佛越大越高端,能获取的信息就越多。而如今,另一种小屏也在高端机圈中流行起来,那就是“后置副屏”,这种“1+1”模式的兴起,到底有什么原因呢? 今天非大家推荐几款带有副屏的手机,每一款都是极品。 vivoNEX双屏版。已经是vivo的老旗舰机型了。外观方面,正面是一块6.39英寸全面屏幕,背面则为5.49英寸非全面屏,两者都是AMOLED屏幕,画质上有着不错的表现;背面副屏可以用来阅读,通知或充当游戏按键等时短暂使用。 努比亚X。外观方面。颜值很高,前后双屏的设计,正面6.26英寸LCD屏幕,背面OLED材质的5.1英寸屏幕。性能方面,高通骁龙845处理器系统不够人性化,虽然在续航时间上有一定的进步但是充电时间很长,然而努比亚虽然很努力但是无奈小众,用时间久了各种问题接踵而至, 后续新机也没有了双屏的设计。 魅族Pro7。魅族Pro7的背后有个小屏“智窗”称之为画屏,可以显示时间、天气,可以用来自拍,还可以关机用小屏听音乐。很多老魅族玩家都觉得很鸡肋,不仅是因为这块视窗,还是由于魅族没有跟上当年全面屏的大趋势,一味地认为自己小而美的设计,这款手机毁誉参半。 1.0时代:魅族首创腰斩 说到后置副屏,就不得不提魅族 Pro7了。早在2017年7月份,魅族推出了第一款带有副屏的智能手机。当时魅族 Pro7的起步价为2880元起,Pro7 Plus则高达4080元。但这款手机生不逢时,出于当时技术有限等种种原因,发布后不到三个月就价格腰斩以至失败告终,如今该机型在各大电商已无新货,只见转转等平台还有二手,价格已跃至三、四百元作为古董的存在。 2.0时代:小米冲击高端 没想到在当年魅族 Pro7首创副屏熄火的四年后,随着小米11 Ultra超大杯副屏设计的面世,“副屏”似乎又开始成为了热点。去年这个时间,小米的这款副屏成功刷新了全世界的眼球,也多次斩获设计大奖,成功的冲击了高端市场,一度成为安卓机皇。虽说可能用处不大,但是足够玩味,这次的副屏更加智能化,开始支持消息预览,辅助拍摄,小米11 Ultra探索出了副屏的更多可能。 3.0时代:副屏或成标配 来到2022年的当下,据最新消息爆料,魅族19Pro将再次回归副屏,vivoX80Pro+也将搭载“云窗副屏”,三星Galaxy F53将推出“后置副屏…

    2022年4月16日
    107
  • 如何搭建社群实现被动成交?

    首先思考一下,谁去看你的朋友圈?,是你微信朋友圈的每个好友和粉丝,这些人每天在弹指一挥间,通过朋友圈的每一个字,每一个符号,每一个颜色,每一张图片,每一个视频很多东西,他们到底在看什么呢?

    2021年5月26日
    12
  • HarmonyOS3.0正式版升级 华为鸿蒙3.0正式版有什么功能

    随着时间的推移,从最初的Beta测试版到正式版的推送有一段时间了。早已尝过HarmonyOS3.0版本的功能以及新玩法。现在,正式版已经推送,可以选择升级了。虽然目前不是所有手机都可以升级,但是,可升级的型号还是比较多的。 即使不能升级正式版,还可以选择公测版。所以,看下你的手机是否在这次正式版的升级行列。如果还没有,那选择公测版,这个也涵盖了众多的型号。体验起来其实与正式版也没太大的差别。 在本次升级之后,新增了5个变化,这里我们可以一起聊聊,充分发掘这个版本的细微变化。毕竟,更新之后的功能变得更加的好用。 跨设备剪贴板 在手机设置里面超级终端,进入之后可以看到新增地块设备剪贴板。顾名思义,就是可以把手机上面复制的内容粘贴到平板或者电脑上面。在日常的工作学习中,我们会经常用到复制粘贴,这个功能可以跨设备实现,省去了很多传送的麻烦。使用这个功能之前,需要在各个设备上面登录同一华为账号,使用同一个局域网才可以操作。 状态栏增加显示运营商名称 刚升级到Harmony3.0是没有这个功能的。在这次版本里面重新增加了,可以在手机设置里面打开通知和状态栏,进入状态栏主页设置开启。开启之后,在手机左上角位置会显示运营商名称。 锁屏语音技能 手机在锁屏之后也可以使用智慧语音功能了。在设置里面打开智慧助手,选择智慧语音,设置开启锁屏语音技能。开启之后,锁屏状态的情况下可以唤醒智慧语音,然后使用语音来控制手机。在这里可以设置语音控制的功能。 语音控制闹钟 手机设置了闹钟,时间到了闹铃响起来,还需要我们手动来控制关闭。现在,可以通过智慧语音来关闭闹钟。省去了手动的麻烦,尤其是对于比较懒的人来说,只需要动动嘴就可以关闭闹钟。 智慧屏招一招 家里如果有华为智慧屏,需要把智慧屏的服务流转到手机上面,这里只需要摆动手机就可以将智慧屏服务流转到手机上面。具体操作方法:打开手机上面的辅助功能,在快捷启动及手势设置里面开启智慧屏招一招。 这些新增的功能都是在本次版本更新之后发现的。这些功能提升了手机与其他设备协同功能,如果有多个设备,可以更好地运用到工作中,提升了可操作性以及省去了一些繁杂的操作。效率显而易见得到提升。所以,存在及合理,功能虽小但实用。说到这里,你的手机都有这些功能吗。

    2022年10月30日
    44
  • iPad Pro2021究竟什么人用最合适?

    前几期发了一篇文章在介绍如何选择iPad话题,很多人都在讨论一个问题:我买iPad Pro2021到底合不合适? 那么好,在回答这个问题之前,我想问你一个问题:“你是从事什么工作,买来干什么的呢?”是学生、工作者、还是剪辑师呢?手机买来看爱奇艺、打游戏、轻微办公还是重度办公呢?很多人都有一个不成熟地想法:买来一定当一部生产力工具,但其实大多数人花了七八千块钱买一个顶级平板就为了看个爱奇艺,你说这又是何必呢,如果你想在最节省的预算得到一个相对稳定的性能,又何必是iPad pro2021?(家里有矿当我没说);首先我先摆明观点:非重度中度工作者强烈建议别买!别买!别买!✨当然不是这个平板性能不足,而是它的性能太强大了,你如果买来只是打打游戏轻度的办公学习,或者只当个爱奇艺播放器观看的话,那我觉得这就是大材小用,小题大做。如果你不能当成一个生产力工具使用,我觉得这就是在荒废平板的价值!我们都讲一句话:花钱花在刀刃上!在这个性能过剩的年代,为什么就要追求最极致的性能呢?适合自己才是最重要!有那个去买这么贵的平板,不如去外面吃顿烧烤,撸个串吃个猪脚饭它不香吗?  

    2021年9月9日
    31
  • 微信回应反复读相册(微信回应在后台反复读取用户相册)

    近日,有消息称微信在后台反复读取用户相册。10月8日晚,腾讯对此回应,iOS 系统为APP开发者提供相册更新通知标准能力,相册发生内容更新时会通知到APP,提醒APP可以提前做准备,APP的该准备行为会被记录成读取系统相册。 当用户授权微信可以读取“系统相册权限”的前提后,为便于用户在微信聊天中按“+”时可以快速发图,微信使用了该系统能力,使用户发送图片体验更快速流畅。上述行为均仅在手机本地完成,最新版本中微信将取消对该系统能力的使用,优化快速发图功能。 10月8日,针对微信在后台反复读取用户相册一事,微信方面回应新浪科技称,iOS系统为App开发者提供相册更新通知标准能力,相册发生内容更新时会通知到App,提醒App可以提前做准备,App的该准备行为会被记录成读取系统相册。 当用户授权微信可以读取“系统相册权限”的前提后,为便于用户在微信聊天中按“+”时可以快速发图,微信使用了该系统能力,使用户发送图片体验更快速流畅。上述行为均仅在手机本地完成,最新版本中我们将取消对该系统能力的使用,优化快速发图功能。 近日,有网友爆料称微信在后台反复读取用户相册。该网友开启iOS 15的隐私新特性 “ 记录 App活动 ”,对所有App隐私读取行为进行7天监控,并使用App Privacy Insights对记录进行读取发现,微信在用户未主动激活App的情况下,在后台数次读取用户相册,每次读取时间长达1分钟。

    2021年12月23日
    11
  • cps结算是什么意思?cps推广如何赚钱

    广告联盟cps的意思就是通过销售产品来按分成来获得佣金,是直接投放的广告模式。其中大家最所熟知的应该就是淘宝联盟了,通过注册淘宝联盟成为淘宝客,获取专属的产品推广链接,用户通过推广链接下单,淘宝客获得佣金。 淘宝联盟 现在很多广告商都喜欢用cps这种模式来给推广者推广,一方面因为这种能直接给广告商带来利用,而不用怕像cpc,cpa这类推广模式会有作弊和效果不佳的情况出现。另一方面,cps模式对于有实力的推广者来说,佣金是可以比cpa,cpc等模式高很多倍,是值得选择扩大利润的一种模式。 讲到这里那么大家都基本知道了cps结算是什么意思,那么接下来给大家讲讲cps推广如何赚钱 一:电商广告联盟 电商广告联盟最出名的两个代表就是京东联盟和淘宝联盟了,我们可以从网上查到数据淘宝联盟目前有400多万的活跃淘客,400多万证明了这是个很大的市场了,并且远远还没有到完全饱和的状态。 主要还是玩法一直在变,如果跟不上变化的淘宝客就会被抛弃。就像现在有抖音淘客,知乎淘客等等 像京东联盟,关于这个也有一个公司推出的芬香做的挺火的,主要原因是因为在微信群发推广链接不会被微信屏蔽,而且还能微信内完成购买。而淘宝客则要注意这个问题,像上个月微信对凡是微信名字带有返利都进行了大规模的封号。所以一时间芳香推广的很火,但个人还是不很看好,因为淘宝联盟的习惯已经深入各个用户的行为了,再去改变的话也不是说没效果,只是说要付出更多的成本和时间。 京东联盟 二:去寻找更多的电商平台 其实这里有一个思路,既然刚刚说了,国内的用户大多习惯淘宝购买了,但大多数都是买国内的产品。 那么如果去推广国外的产品呢,国外的产品也不全能在淘宝可以去购买到的,这时候就去寻找这类电商平台,据我所知有很多这类也有cps推广模式的平台。 像国外的产品都是按美金来算的,那么自然佣金也会高很多,但这类的流量获取比淘宝用户难度大,但价值高也是可以去尝试了。 所以cps推广一直是可以能做的一个结算模式,主要盈利核心还是要打造一个能让信任的ip(品牌/个人形象),只有让用户信任你了,才会通过你的链接去下单,这样才能盈利,而且喜欢购物的用户,能为你带来源源不断的价值

    2021年6月24日
    51