idea插件开发(5)-Swing图形化设计

     Java-GUI提供了两套设计AWT和Swing,其中Swing是基于AWT开发的,两者在功能上基本一样。发展至今天,最大的区别就是在显示样式上,AWT会匹配当前操作系统的UI而在不同平台下表现出不同的样式,但Swing不会。所以建议插件开发时采用Swing-GUI

一、Idea-UI开发基础

1、UI控件架构

        Idea的图形界面是基于Swing开发的,官方文档也有推荐,详细的UI控件可查看官方文档IntelliJ Platform UI Guidelines ,虽说Swing内容比较多,但相对来讲比较简单。 所有GUI开发基本都遵循如下关系来设计:

idea插件开发(5)-Swing图形化设计_第1张图片

2、Swing体系

        idea控件开发只要了解这一张图即可,开发时参考此图再查相应的API文档。不需要太高深的技术(Canvas开发除外,那个涉及很多图形方面的专业知识。

idea插件开发(5)-Swing图形化设计_第2张图片

 二、Swing容器

        本章会从容器、布局、复杂控件几个方式给出一些示例。

1、JFrame

        显示一个空白窗口

public class Windowsdemo {
    public static void main(String[] args) {
        //1.创建一个窗口对象
        JFrame frame = new JFrame("window窗口演示");
        //2.指定窗口的位置,大小
        frame.setLocation(100,100);
        frame.setSize(500,300);
        //3.设置窗口对象可见
        frame.setVisible(true);
    }
}

idea插件开发(5)-Swing图形化设计_第3张图片

2、JDialog

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

        JFrame frame = new JFrame("这里测试Dialog");
        JDialog d1 = new JDialog(frame, "模式对话框", true);

        //2.通过setBounds方法设置Dialog的位置以及大小
        d1.setBounds(20,30,300,200);
        //3.创建两个按钮
        JButton b1 = new JButton("打开模式对话框");

        //4.给这两个按钮添加点击后的行为
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d1.setVisible(true);
            }
        });

        //5.把按钮添加到frame中
        frame.add(b1, BorderLayout.NORTH);

        //设置frame最佳大小并可见
        frame.pack();
        frame.setVisible(true);
    }
}

 idea插件开发(5)-Swing图形化设计_第4张图片

3、MessageDialog

        简化版本的弹出窗口确定框,注意这些Dialog全是模态化的。

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) {
            //弹出一个消息对话框,并且显示  文本域中输入的内容
            String text = jta.getText();

            //参数:int messageType  指定消息对话框的类型: 错误消息,警告消息,问题消息...
            //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.ERROR_MESSAGE);
            //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.INFORMATION_MESSAGE);
            //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE);
            //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.QUESTION_MESSAGE);
            //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.PLAIN_MESSAGE);

            JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE,new ImageIcon("E:\\GUISwing\\img\\component\\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();
    }

idea插件开发(5)-Swing图形化设计_第5张图片

4、为容器添加工具栏

Frame菜单

        菜单分为两种:一种是嵌入到Frame中的,另一种是右键。

public class SimpleMenu {
    //创建窗口
    private JFrame frame = new JFrame("这里测试菜单相关组件");

    //创建菜单条
    JMenuBar menuBar = new JMenuBar();

    //创建菜单组件
    JMenu fileMenu = new JMenu("文件");
    JMenu editMenu = new JMenu("编辑");

    //菜单项组件
    JMenuItem copy = new JMenuItem("复制");
    JMenuItem paste = new JMenuItem("粘贴");

    public void init(){
        //组装编辑菜单
        editMenu.add(copy);
        editMenu.add(paste);

        //组装菜单条
        menuBar.add(fileMenu);
        menuBar.add(editMenu);

        //把菜单条放入到Frame中
        frame.setJMenuBar(menuBar);

        //设置frame最佳大小并可见
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new SimpleMenu().init();
    }
}

idea插件开发(5)-Swing图形化设计_第6张图片

Toolbar工具栏

        这个工具栏是可以拖动的。

public class JToolBarTest {

    JFrame jf = new JFrame("测试工具条");
    JTextArea jta = new JTextArea(6,35);

    //声明工具条相关内容
    JToolBar jToolBar = new JToolBar("播放工具条",SwingConstants.HORIZONTAL);

    //创建3个Action对象
    //传递的参数,name和icon,最终在添加到工具条中时,会被拿出来作为按钮的名称和图标
    Action pre = new AbstractAction("上一曲",new ImageIcon("E:\\GUISwing\\img\\component\\上一曲16.png")) {
        @Override
        public void actionPerformed(ActionEvent e) {
            jta.append("上一曲.\n");
        }
    };


    public void init(){
        //通过Action对象来创建JButton
        JButton preBtn = new JButton(pre);

        jToolBar.add(preBtn);
        jToolBar.addSeparator();

        //让工具条可以拖动
        jToolBar.setFloatable(true);
        jf.add(jToolBar, BorderLayout.NORTH);

        //把一个组件设置到JScrollPane中,那么该组件就支持滚动条了
        JScrollPane jScrollPane = new JScrollPane(jta);

        jf.add(jScrollPane);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        new JToolBarTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第7张图片

5、特殊容器

 JSplitPane-可调整大小的面板

public class SplitPaneTest {

    Book[] books = {new Book("java自学宝典",  "国内关于 Java 编程最全面的图书 \n 看得懂 , 学得会"),
            new Book("轻量级的JAVAEE企业应用实战", "SSM整合开发的经典图书,值的拥有"),

    };

    JFrame jf = new JFrame("测试JSplitPane");

    //声明程序中用到的组件
    JList bookJList = new JList<>(books);
    JLabel bookCover = new JLabel();
    JTextArea bookDesc = new JTextArea();

    public void init(){
        //组装视图
        //设定组件大小
        bookJList.setPreferredSize(new Dimension(150,400));
        bookCover.setPreferredSize(new Dimension(220,270));
        bookDesc.setPreferredSize(new Dimension(220,130));

        //为jList设置条目选中监听器
        bookJList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                //获取当前选中的是哪个条目
                Book book = bookJList.getSelectedValue();
                //把书籍的图片用bookCover展示
                bookDesc.setText(book.getDesc());
            }
        });

        //组装左边区域
        JSplitPane left = new JSplitPane(JSplitPane.VERTICAL_SPLIT,bookCover,new JScrollPane(bookDesc));
        left.setOneTouchExpandable(true);//一触即展

        //组装整体
        JSplitPane hole = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,left,bookJList);

        //支持连续布局
        hole.setContinuousLayout(true);
        hole.setDividerSize(10);
        jf.add(hole);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

    }

    public static void main(String[] args) {
        new SplitPaneTest().init();
    }

}

@Data
@AllArgsConstructor
class Book {
    private String name;

    private String desc;
}

idea插件开发(5)-Swing图形化设计_第8张图片

 TabbedPane-标签页面板

public class JTabbedPaneTest {
    JFrame jf = new JFrame("测试JTabbedPane");

    JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.LEFT,JTabbedPane.SCROLL_TAB_LAYOUT);

    public void init(){

        //添加标签
        tabbedPane.addTab("用户管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList(new String[]{"用户一","用户二","用户三"}));
        tabbedPane.addTab("商品管理",new JList(new String[]{"商品一","商品二","商品三"}));
        tabbedPane.addTab("订单管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList(new String[]{"订单一","订单二","订单三","订单四"}));

        //完成设置
        tabbedPane.setEnabledAt(0,false);//禁用用户管理
        tabbedPane.setSelectedIndex(1);//默认商品管理

        //监听当前标签面板的选中情况
        tabbedPane.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int selectedIndex = tabbedPane.getSelectedIndex();
                JOptionPane.showMessageDialog(jf,"当前选中了第 "+(selectedIndex+1)+"个标签");
            }
        });

        jf.add(tabbedPane);
        jf.setBounds(400,400,400,400);
        jf.setResizable(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        new JTabbedPaneTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第9张图片

三、Swing布局

1、BorderLayout

        其中边上的4个方向可以不设置,这样就可以实现列和行布局模式了。

public class BorderLayoutTest extends JFrame {  //0.继承JFrame

    public BorderLayoutTest() {
        //1. 创建组件
        JButton jButton = new JButton("中间");
        JButton jButton2 = new JButton("北间");
        JButton jButton3 = new JButton("西间");
        JButton jButton4 = new JButton("东间");
        JButton jButton5 = new JButton("南间");

        //2. 添加各个组件
        this.add(jButton, BorderLayout.CENTER);  //布局的中间
        this.add(jButton2, BorderLayout.NORTH);  //布局的北边
        this.add(jButton3, BorderLayout.WEST);   //布局的西边
        this.add(jButton4, BorderLayout.EAST);   //布局的东边
        this.add(jButton5, BorderLayout.SOUTH);  //布局的南边

        //3. 设置窗体属性
        this.setTitle("演示边界布局管理器");
        this.setSize(300, 200);
        this.setLocation(200, 200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new BorderLayoutTest();
    }
}

idea插件开发(5)-Swing图形化设计_第10张图片

 2、FlowLayout

        一种流布局模式,控件会按添加顺序依次摆放,如果超过容器大小会自动换行。

public class FlowLayoutTest extends JFrame {  //0.继承JFrame

    public FlowLayoutTest() {
        //1. 创建组件
        JButton jButton1 = new JButton("A");
        JButton jButton2 = new JButton("B");
        JButton jButton3 = new JButton("C");
        JButton jButton4 = new JButton("D");
        JButton jButton5 = new JButton("E");

        //2. 添加各个组件
        this.add(jButton1);
        this.add(jButton2);
        this.add(jButton3);
        this.add(jButton4);
        this.add(jButton5);
        //设置流布局
        this.setLayout(new FlowLayout(FlowLayout.LEFT));


        //4. 设置窗体属性
        this.setTitle("演示流布局管理器"); //设置标题
        this.setSize(300, 200);       //设置
        this.setLocation(200, 200);   //设置窗体出现的位置
        this.setVisible(true);        //设置窗体可见
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体关闭的同时关闭jvm
        this.setResizable(false);  //Resizable:可调整大小的,设置窗体大小不可变
    }
    public static void main(String[] args) {
        new FlowLayoutTest();
    }
}

idea插件开发(5)-Swing图形化设计_第11张图片

 3、GridLayout

        网格模式,适合比较复杂的布局方式。

public class GridLayoutTest extends JFrame {
    //定义组件
    int size = 9;
    //定义按钮数组
    JButton jButton[] = new JButton[size];

    //构造函数
    public GridLayoutTest() {
        //创建组件
        for(int i = 0; i

idea插件开发(5)-Swing图形化设计_第12张图片

4、BoxLayout

        可指定BoxLayout参数控制容器内的元素是按行还是按列排列。

public class BoxLayoutTest {
    public static void main(String[] args) {
        Frame frame = new Frame("这里测试BoxLayout");
        //1.基于frame容器,创建一个BoxLayout对象,并且,该对象存放组件是垂直存放
        //BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);

        BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);//水平排列

        //2.把BoxLayout对象设置给Frame
        frame.setLayout(boxLayout);

        //3.往frame中添加两个按钮组件
        frame.add(new Button("按钮1"));
        frame.add(new Button("按钮2"));

        frame.pack();
        frame.setVisible(true);
    }
}

idea插件开发(5)-Swing图形化设计_第13张图片

  四、Swing事件

        事件的类型比较多,一个简单的示例如下,有两种方式绑定事件。允许一个事件源绑定多个事件,也允许绑定多个同类型的事件。在内部会形成一个事件链依次执行。

1、定制侦听器

public class EventDemo1 {
    Frame  frame = new Frame("这里测试事件处理");

    TextField tf = new TextField(30);
    //事件源
    Button ok = new Button("确定");

    public void init(){//组装视图

        //注册监听
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("ok按钮被点击了...");
                tf.setText("Hello World");
            }
        });

        //把tf和ok放入到Frame中
        frame.add(tf, BorderLayout.NORTH);
        frame.add(ok);

        frame.pack();
        frame.setVisible(true);

    }


    public static void main(String[] args) {
        new EventDemo1().init();
    }
}

2、共享侦听器

public class EventDemo1 {
    Frame  frame = new Frame("这里测试事件处理");
    TextField tf = new TextField(30);
    Button ok = new Button("确定");

    public void init(){//组装视图
        //监听器,这种写法适合公共监听器,后面多个摈控件通过addActionListener()来共享
        MyListener myListener = new MyListener();
        ok.addActionListener(myListener);

        //把tf和ok放入到Frame中
        frame.add(tf, BorderLayout.NORTH);
        frame.add(ok);

        frame.pack();
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        new EventDemo1().init();
    }
}

class MyListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("ok按钮被点击了...");
    }
}

五、Swing进度条

        主要使用JProgressBar、ProgressMonitor、BoundedRangeModel实现进度条。

1、主线程内的进度条

        这种耗时操作放在主线程的话,会导致执行耗时操作时,用户无法再进行任何操作,因此最好将耗时操作放入子线程中。

public class JProgressTest {
    JFrame jf = new JFrame("测试进度条");


    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);

    public void init(){
        //组装视图
        Box vBox = Box.createVerticalBox();

        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //通过循环模拟修改进度条的进度
        for (int i = 0; i <= 100; i++) {
            //修改已经完成的工作量,也就是百分比
            bar.setValue(i);

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new JProgressTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第14张图片

 2、线程内的进度条(推荐)

public class JProgressTest2 {

    JFrame jf = new JFrame("测试进度条");

    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);


    public void init(){
        //组装视图
        Box vBox = Box.createVerticalBox();

        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //开启子线程,模拟耗时操作
        SimulaterActivity simulaterActivity = new SimulaterActivity();
        simulaterActivity.setAmount(bar.getMaximum());
        new Thread(simulaterActivity).start();

        //设置一个定时任务
        Timer timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取线程任务对象的当前完成量,设置给进度条
                int current = simulaterActivity.getCurrent();
                bar.setValue(current);
            }
        });
        timer.start();

        //监听进度条的任务变化
        bar.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int value = bar.getValue();
                if (value == simulaterActivity.getAmount()){
                    timer.stop();
                }
            }
        });
    }

    @Data
    private class SimulaterActivity implements  Runnable{
        //记录任务总量
        private int amount;

        //记录当前任务的完成量
        private volatile int current;

        @Override
        public void run() {
            //子线程的任务  模拟耗时操作
            while(current

idea插件开发(5)-Swing图形化设计_第15张图片

 3、获取进度条数据

        Swing组件大都将外观显示和内部数据分离,JProgressBar也不例外,JProgressBar组件有一个内置的用于保存其状态数据的Model对象,这个对象由BoundedRangeModel对象表示,程序调用JProgressBar对象的方法完成进度百分比的设置,监听进度条的数据变化,其实都是通过
它内置的BoundedRangeModel对象完成的。下面的代码是对之前代码的改进,通过BoundedRangeModel完成数据的设置,获取和监听。

public class JProgressTest3 {

    JFrame jf = new JFrame("测试进度条");

    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);

    //获取处进度条内置的数据模型对象
    BoundedRangeModel model = bar.getModel();

    public void init(){
        //组装视图
        Box vBox = Box.createVerticalBox();

        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //开启子线程,模拟耗时操作
        SimulaterActivity simulaterActivity = new SimulaterActivity();
        simulaterActivity.setAmount(bar.getMaximum());
        new Thread(simulaterActivity).start();

        //设置一个定时任务
        Timer timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取线程任务对象的当前完成量,设置给进度条
                int current = simulaterActivity.getCurrent();
                model.setValue(current);
            }
        });
        timer.start();

        //监听进度条的任务变化
        model.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int value = model.getValue();
                if (value == simulaterActivity.getAmount()){
                    timer.stop();
                }
            }
        });


    }

    @Data
    private class SimulaterActivity implements  Runnable{
        //记录任务总量
        private int amount;

        //记录当前任务的完成量
        private volatile int current;

        @Override
        public void run() {
            //子线程的任务  模拟耗时操作
            while(current

4、ProgressMonitor

        使用ProgressMonitor创建的对话框里包含的进度条是非常固定的,程序甚至不能设置该进度条是否包含边框(总是包含边框),不能设置进度不确定,不能改变进度条的方向(总是水平方向)。

public class ProgressMonitorTest {
    Timer timer;
    public void init(){
        //创建进度对话框
        ProgressMonitor monitor = new ProgressMonitor(null,"等待任务完成","已完成",0,100);

        SimulaterActivity simulaterActivity = new SimulaterActivity(100);
        new Thread(simulaterActivity).start();


        //设置定时任务
        timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取当前任务量,修改进度
                int current = simulaterActivity.getCurrent();
                monitor.setProgress(current);

                //判断用户是否点击了取消按钮,停止定时任务,关闭对话框,退出程序
                if (monitor.isCanceled()){
                    timer.stop();
                    monitor.close();
                    System.exit(0);
                }

            }
        });
        timer.start();

    }

    public static void main(String[] args) {
        new ProgressMonitorTest().init();
    }

    //定义一个线程任务,模拟耗时操作
    @Data
    private class SimulaterActivity implements Runnable{
        //内存可见
        private volatile int current = 0;
        private int amount;

        public SimulaterActivity(int amount) {
            this.amount = amount;
        }

        @Override
        public void run() {
            //通过循环,不断的修改current的值,模拟任务完成量
            while(current

六、Swing下拉列表

1、简单列表

public class ListTest {
    JFrame jf = new JFrame("列表框测试");
    String[] books = {"java自学宝典","轻量级javaEE企业应用实战","Android基础教程","jQuery实战教程","SpringBoot企业级开发"};

    //定义 布局选择按钮 所在的面板
    JPanel layoutPanel = new JPanel();
    ButtonGroup layoutGroup = new ButtonGroup();

    //定义 选择模式按钮 所在面板
    JPanel selectModePanel = new JPanel();
    ButtonGroup selectModeGroup = new ButtonGroup();

    //用一个字符串数组来创建一个JList对象
    JList bookList ;
    JComboBox bookSelector;

    public void init(){
        //组装视图

        //组装Jlist相关内容
        bookList = new JList<>(books);

        addBtn2LayoutPanel("纵向滚动",JList.VERTICAL);
        addBtn2LayoutPanel("纵向换行",JList.VERTICAL_WRAP);
        addBtn2LayoutPanel("横向换行",JList.HORIZONTAL_WRAP);

        addBtn2SelectModelPanel("无限制",ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        addBtn2SelectModelPanel("单选",ListSelectionModel.SINGLE_SELECTION);
        addBtn2SelectModelPanel("单范围",ListSelectionModel.SINGLE_INTERVAL_SELECTION);

        //对JList做设置
        bookList.setVisibleRowCount(3);
        bookList.setSelectionInterval(2,4);

        //处理条目选中事件
        bookList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                //获取当前选中的条目
                java.util.List selectedValuesList = bookList.getSelectedValuesList();
                //把当前条目的内容设置到文本域中。
            }
        });

        Box bookListVBox = Box.createVerticalBox();
        bookListVBox.add(new JScrollPane(bookList));
        bookListVBox.add(layoutPanel);
        bookListVBox.add(selectModePanel);

        //组装JComboBox
        Vector vector = new Vector<>();
        for (int i = 0; i < books.length; i++) {
            vector.add(books[i]);
        }

        bookSelector = new JComboBox<>(vector);
        bookSelector.setEditable(true);
        bookSelector.setMaximumRowCount(4);

        //组装顶部的左右两部分
        Box topBox = Box.createHorizontalBox();
        topBox.add(bookListVBox);
        JPanel bookSelectPanel = new JPanel();
        bookSelectPanel.add(bookSelector);
        topBox.add(bookSelectPanel);

        //组装底部
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BorderLayout());

        //组装整体
        Box holeBox = Box.createVerticalBox();
        holeBox.add(topBox);
        holeBox.add(bottomPanel);

        jf.add(holeBox);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }

    //封装方法,往layoutPanel中添加单选按钮
    public void addBtn2LayoutPanel(String name,int layoutType){
        //设置标题边框
        layoutPanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选项布局"));
        //创建单选按钮
        JRadioButton button = new JRadioButton(name);
        layoutPanel.add(button);

        //让第一个按钮默认选中
        if (layoutGroup.getButtonCount()==0){
            button.setSelected(true);
        }

        layoutGroup.add(button);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                bookList.setLayoutOrientation(layoutType);
            }
        });
    }

    //封装方法,给selectModelPanel添加按钮
    public void addBtn2SelectModelPanel(String name,int selectionModel){
        //设置标题边框
        selectModePanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选择模式"));
        //创建单选按钮
        JRadioButton button = new JRadioButton(name);
        selectModePanel.add(button);

        //让第一个按钮默认选中
        if (selectModeGroup.getButtonCount()==0){
            button.setSelected(true);
        }

        selectModeGroup.add(button);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                bookList.setSelectionMode(selectionModel);
            }
        });
    }
    public static void main(String[] args) {
        new ListTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第16张图片

 2、固定值的列表

public class NumberListModel extends AbstractListModel {
    BigDecimal start;
    BigDecimal end;
    BigDecimal step;

    public NumberListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
        this.start = start;
        this.end = end;
        this.step = step;
    }


    @Override
    public int getSize() {
        int floor = (int) Math.floor(end.subtract(start).divide(step,2, RoundingMode.HALF_DOWN).doubleValue());
        return floor+1;
    }

    @Override
    public BigDecimal getElementAt(int index) {
        BigDecimal ele = new BigDecimal(index).multiply(step).add(start).setScale(2, RoundingMode.HALF_DOWN);
        return ele;
    }
}
public class NumberComboBoxListModel extends NumberListModel implements ComboBoxModel {
    //当前选中条目的索引
    private int selectedId;


    public NumberComboBoxListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
        super(start, end, step);
    }

    @Override
    public void setSelectedItem(Object anItem) {

        if (anItem instanceof BigDecimal){
            BigDecimal curr = (BigDecimal) anItem;
            selectedId = curr.subtract(super.start).divide(super.step,2, RoundingMode.HALF_DOWN).intValue();
        }
    }

    @Override
    public Object getSelectedItem() {

        BigDecimal item = new BigDecimal(selectedId).multiply(super.step).add(super.start).setScale(1, RoundingMode.HALF_DOWN);

        return item;
    }
}
public class ListModelTest {
    JFrame jf = new JFrame("测试ListModel");
    JList jList = new JList<>(new NumberListModel(new BigDecimal(1),new BigDecimal(21),new BigDecimal(2)));

    JComboBox jComboBox = new JComboBox<>(new NumberComboBoxListModel(new BigDecimal(0.1),new BigDecimal(1.2),new BigDecimal(0.1)));

    JLabel label = new JLabel("您选择的值是:");

    JTextField jTextField = new JTextField(15);

    public void init(){
        //组装视图

        //组装顶部
        jList.setVisibleRowCount(4);
        jList.setSelectionInterval(2,4);

        jList.setFixedCellWidth(90);
        jList.setFixedCellHeight(30);

        jList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                java.util.List selectedValuesList = jList.getSelectedValuesList();
                jTextField.setText("");
                for (BigDecimal item : selectedValuesList) {
                    jTextField.setText(jTextField.getText()+item.toString()+",");
                }
            }
        });

        jComboBox.setMaximumRowCount(4);
        jComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                Object selectedItem = jComboBox.getSelectedItem();
                jTextField.setText(selectedItem.toString());
            }
        });

        Box hBox = Box.createHorizontalBox();
        hBox.add(new JScrollPane(jList));

        JPanel tempPanel = new JPanel();
        tempPanel.add(jComboBox);
        hBox.add(tempPanel);
        jf.add(hBox);

        //组装底部
        JPanel bottomPanel = new JPanel();
        bottomPanel.add(label);
        bottomPanel.add(jTextField);

        jf.add(bottomPanel, BorderLayout.SOUTH);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

    }

    public static void main(String[] args) {
        new ListModelTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第17张图片

 3、动态改变列表的值

public class DefaultListModelTest {

    JFrame jf = new JFrame("测试DefaultListModel");

    JTextField bookName = new JTextField(20);

    JButton removeBtn = new JButton("删除选中图书");

    JButton addBtn = new JButton("添加指定图书");

    //创建JList
    JList bookList;

    DefaultListModel model = new DefaultListModel<>();

    public void init(){
        //组装视图
        model.addElement("java自学宝典");
        model.addElement("轻量级JavaEE企业应用实战");
        model.addElement("Android基础教程");
        model.addElement("JQuery实战教程");

        bookList = new JList<>(model);

        //设置Jlist
        bookList.setVisibleRowCount(4);
        //设置单选
        bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        jf.add(new JScrollPane(bookList));

        //组装底部
        addBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String name = bookName.getText();
                if (!name.trim().equals("")){//不是空字符串才添加
                    model.addElement(name);
                }
            }
        });

        removeBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedIndex = bookList.getSelectedIndex();

                if (selectedIndex>=0){
                    model.remove(selectedIndex);
                }
            }
        });


        JPanel bottomPanel = new JPanel();
        bottomPanel.add(bookName);
        bottomPanel.add(addBtn);
        bottomPanel.add(removeBtn);

        jf.add(bottomPanel, BorderLayout.SOUTH);


        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

    }

    public static void main(String[] args) {
        new DefaultListModelTest().init();
    }

}

idea插件开发(5)-Swing图形化设计_第18张图片

 4、改变列表控件外观

public class ListCellRendererTest {

    private JFrame mainWin = new JFrame("好友列表");

    private String[] friends = {
            "李清照",
            "苏格拉底",
            "李白",
            "弄玉",
            "虎头"
    };

    //定义一个JList对象
    JList friendsList = new JList(friends);

    public void init() {
        //组装视图
        //给JList设置ListCellRenderer对象,指定列表项绘制的组件
        friendsList.setCellRenderer(new MyRenderer());

        mainWin.add(friendsList);

        mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainWin.pack();
        mainWin.setVisible(true);

    }

    private class MyRenderer extends JPanel implements ListCellRenderer{
        private String name;
        private ImageIcon icon;

        //记录背景色
        private Color backGround;
        //记录前景色:文字的颜色
        private Color forceGround;


        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            //重置成员变量的值
            this.name = value.toString();
            this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+name+".gif");

            this.backGround = isSelected? list.getSelectionBackground() : list.getBackground();
            this.forceGround = isSelected? list.getSelectionForeground() : list.getForeground();

            return this;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(60,80);
        }

        //绘制列表项的内容
        @Override
        public void paint(Graphics g) {
            int imageWidth = icon.getImage().getWidth(null);
            int imageHeight = icon.getImage().getHeight(null);

            //填充背景矩形
            g.setColor(backGround);
            g.fillRect(0,0,getWidth(),getHeight());

            //绘制头像
            g.drawImage(icon.getImage(),this.getWidth()/2 -imageWidth/2 ,10,null);

            //绘制昵称
            g.setColor(forceGround);
            g.setFont(new Font("StSong",Font.BOLD,18));
            g.drawString(this.name,this.getWidth()/2 - this.name.length()*20/2,imageHeight+30);

        }
    }


    public static void main(String[] args) {
        new ListCellRendererTest().init();
    }

}

七、Swing表格

1、简单表格

public class SimpleTable {

    JFrame jf = new JFrame("简单表格");

    //创建一维数组,存储标题
    Object[] titles = {"姓名","年龄","性别"};

    //创建二维数组,存储数据
    Object[][] data = {
            {"李清照",29,"女"},
            {"苏格拉底",56,"男"},
            {"李白",35,"男"},
            {"弄玉",18,"女"},
            {"虎头",2,"男"}

    };

    public void init(){
        //组装视图
        JTable jTable = new JTable(data,titles);

        jf.add(new JScrollPane(jTable));
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        new SimpleTable().init();
    }
}

idea插件开发(5)-Swing图形化设计_第19张图片

2、TableModel

public class TableModelTest {
    JFrame jf = new JFrame("TableModel演示");
    //创建一维数组,存储标题
    Object[] titles = {"姓名","年龄","性别"};

    //创建二维数组,存储数据
    Object[][] data = {
            {"李清照",29,"女"},
            {"苏格拉底",56,"男"},
            {"李白",35,"男"},
            {"弄玉",18,"女"},
            {"虎头",2,"男"}
    };
    private Vector titlesV = new Vector();//存储标题
    private Vector dataV = new Vector<>();//存储数据

    public void init(){
        //组装视图
        for (int i = 0; i < titles.length; i++) {
            titlesV.add(titles[i]);
        }

        for (int i = 0; i < data.length; i++) {
            Vector t = new Vector<>();
            for (int j = 0; j < data[i].length; j++) {
                t.add(data[i][j]);
            }
            dataV.add(t);
        }
        MyTableModel myTableModel = new MyTableModel();
        //JTable jTable = new JTable(dataV,titlesV);
        JTable jTable = new JTable(myTableModel);

        jf.add(new JScrollPane(jTable));

        JButton btn = new JButton("获取选中行数据");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedColumn = jTable.getSelectedColumn();
                int selectedRow = jTable.getSelectedRow();
                System.out.println("当前选中行的索引:"+selectedRow);
                System.out.println("当前选中列的索引:"+selectedColumn);

                Object value = myTableModel.getValueAt(selectedRow, selectedColumn);
                System.out.println("当前选中行第一个单元格的内容为:"+value);
            }
        });
        jf.add(btn, BorderLayout.SOUTH);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }

    private class MyTableModel extends AbstractTableModel {

        @Override
        public int getRowCount() {
            return dataV.size();
        }

        @Override
        public int getColumnCount() {
            return titlesV.size();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return dataV.get(rowIndex).get(columnIndex);
        }

        @Override
        public String getColumnName(int column) {
            return (String) titlesV.get(column);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    }


    public static void main(String[] args) {
        new TableModelTest().init();
    }

}
public class DefaultTableModelTest {
    JFrame jf = new JFrame("TableModel演示");
    //创建一维数组,存储标题
    Object[] titles = {"姓名","年龄","性别"};

    //创建二维数组,存储数据
    Object[][] data = {
            {"李清照",29,"女"},
            {"苏格拉底",56,"男"},
            {"李白",35,"男"},
            {"弄玉",18,"女"},
            {"虎头",2,"男"}

    };

    private Vector titlesV = new Vector();//存储标题
    private Vector dataV = new Vector<>();//存储数据



    public void init(){
        //组装视图
        for (int i = 0; i < titles.length; i++) {
            titlesV.add(titles[i]);
        }

        for (int i = 0; i < data.length; i++) {
            Vector t = new Vector<>();
            for (int j = 0; j < data[i].length; j++) {
                t.add(data[i][j]);
            }
            dataV.add(t);
        }


        //通过DefaultTableModel创建JTable
        DefaultTableModel model = new DefaultTableModel(dataV,titlesV);
        JTable jTable = new JTable(model);

        //创建按钮
        JButton addRow = new JButton("添加一行");
        JButton addColum = new JButton("添加一列");
        JButton deleteRow = new JButton("删除一行");

        addRow.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //需要给表格添加一行
                model.addRow(new Object[]{"胡歌",30,"男"});
            }
        });

        deleteRow.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedRow = jTable.getSelectedRow();
                model.removeRow(selectedRow);
            }
        });



        addColum.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                model.addColumn("职业");
            }
        });

        JPanel panel = new JPanel();
        panel.add(addRow);
        panel.add(addColum);
        panel.add(deleteRow);

        jf.add(panel, BorderLayout.SOUTH);

        jf.add(new JScrollPane(jTable));
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }


    public static void main(String[] args) {
        new DefaultTableModelTest().init();
    }

}

idea插件开发(5)-Swing图形化设计_第20张图片

 八、Swing树

1、创建树

public class SimpleJTree {
    JFrame jf = new JFrame("简单树");
    public void init(){

        //创建DefaultMutableTreeNode对象代表结点
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
        DefaultMutableTreeNode guangDong = new DefaultMutableTreeNode("广东");
        DefaultMutableTreeNode guangXi = new DefaultMutableTreeNode("广西");
        DefaultMutableTreeNode foShan = new DefaultMutableTreeNode("佛山");
        DefaultMutableTreeNode shanTou = new DefaultMutableTreeNode("汕头");
        DefaultMutableTreeNode guiLin = new DefaultMutableTreeNode("桂林");
        DefaultMutableTreeNode nanNing = new DefaultMutableTreeNode("南宁");

        //组装结点之间的关系
        root.add(guangDong);
        root.add(guangXi);

        guangDong.add(foShan);
        guangDong.add(shanTou);

        guangXi.add(guiLin);
        guangXi.add(nanNing);

        //创建JTree对象
        JTree tree = new JTree(root);

        //把JTree放入到窗口中进行展示
        jf.add(tree);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

    }

    public static void main(String[] args) {
        new SimpleJTree().init();
    }
}

idea插件开发(5)-Swing图形化设计_第21张图片

2、编辑树

编辑树节点

public class EditTree {

    JFrame jf = new JFrame("可编辑结点的树");

    //定义几个初始结点
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
    DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
    DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
    DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
    DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
    DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
    DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");


    //定义按钮,完成操作
    JButton addSiblingBtn = new JButton("添加兄弟结点");
    JButton addChildBtn = new JButton("添加子结点");
    JButton deleteBtn = new JButton("删除结点");
    JButton editBtn = new JButton("编辑当前结点");

    public void init() {

        //通过add()方法建立父子层级关系
        guangdong.add(foshan);
        guangdong.add(shantou);
        guangxi.add(guilin);
        guangxi.add(nanning);
        root.add(guangdong);
        root.add(guangxi);

        JTree tree = new JTree(root);

        //完成树的结点编辑的代码
        tree.setEditable(true);
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();

        //处理添加
        addSiblingBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //添加兄弟结点逻辑

                //1.获取当前选中的结点
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                if (selectedNode == null) {
                    return;
                }

                //2.获取当前结点的父结点
                DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode.getParent();
                if (parentNode == null) {
                    return;
                }

                //3.创建新结点
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");

                //4.把新结点通过父结点进行添加
                int index = parentNode.getIndex(selectedNode);
                model.insertNodeInto(newNode, parentNode, index);

                //5.显示新结点
                TreeNode[] pathToRoot = model.getPathToRoot(newNode);
                TreePath treePath = new TreePath(pathToRoot);
                tree.scrollPathToVisible(treePath);

                //6.重绘tree
                tree.updateUI();

            }
        });

        addChildBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //为选中结点添加子节点

                //1.获取选中结点
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                if (selectedNode == null) {
                    return;
                }
                //2.创建新结点
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");

                //3.把新结点添加到当前结点中
                selectedNode.add(newNode);

                //4.显示新结点
                TreeNode[] pathToRoot = model.getPathToRoot(newNode);
                TreePath treePath = new TreePath(pathToRoot);
                tree.scrollPathToVisible(treePath);

                //5.重绘UI
                tree.updateUI();
            }
        });

        //处理删除
        deleteBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();

                if (selectedNode != null && selectedNode.getParent() != null) {
                    model.removeNodeFromParent(selectedNode);
                }

            }
        });

        //处理编辑
        editBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取当前选中结点的路径
                TreePath selectionPath = tree.getSelectionPath();

                //判断如果路径不为空,则设置该路径的最后一个结点可编辑
                if (selectionPath != null) {
                    tree.startEditingAtPath(selectionPath);
                }
            }
        });
        jf.add(new JScrollPane(tree));

        JPanel panel = new JPanel();
        panel.add(addSiblingBtn);
        panel.add(addChildBtn);
        panel.add(deleteBtn);
        panel.add(editBtn);

        jf.add(panel, BorderLayout.SOUTH);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

    }

    public static void main(String[] args) {
        new EditTree().init();
    }
}

idea插件开发(5)-Swing图形化设计_第22张图片

 监听节点事件

public class ListenerJTree {
    JFrame jf = new JFrame("监听树的选择事件");

    JTree tree;

    DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
    DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
    DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
    DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
    DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
    DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
    DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");

    JTextArea eventTxt = new JTextArea(5, 20);

    public void init() {

        //通过add()方法建立父子层级关系
        guangdong.add(foshan);
        guangdong.add(shantou);
        guangxi.add(guilin);
        guangxi.add(nanning);
        root.add(guangdong);
        root.add(guangxi);

        tree = new JTree(root);

        //TODO 设置选择模式
        TreeSelectionModel selectionModel = tree.getSelectionModel();
        selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //TODO 设置监听器
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent e) {
                //把当前选中结点的路径显示到文本域中
                TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();

                eventTxt.append(newLeadSelectionPath.toString()+"\n");
            }
        });

        Box box = Box.createHorizontalBox();
        box.add(new JScrollPane(tree));
        box.add(new JScrollPane(eventTxt));

        jf.add(box);
        jf.pack();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        new ListenerJTree().init();
    }
}

3、改变树外观

public class ChangeAllCellRender {

    JFrame jf = new JFrame("改变所有结点外观");

    JTree tree;

    DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
    DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
    DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
    DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
    DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
    DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
    DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");

    public void init(){
        //通过add()方法建立父子层级关系
        guangdong.add(foshan);
        guangdong.add(shantou);
        guangxi.add(guilin);
        guangxi.add(nanning);
        root.add(guangdong);
        root.add(guangxi);

        tree = new JTree(root);

        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
        //设置非选定结点的背景颜色
        renderer.setBackgroundNonSelectionColor(new Color(220,220,220));
        //设置选中结点的背景色
        renderer.setBackgroundSelectionColor(new Color(140,140,140));
        //设置选中状态下结点的边框颜色
        renderer.setBorderSelectionColor(Color.BLACK);
        //设置处于折叠状态下非叶子结点的图标
        renderer.setClosedIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\close.gif"));
        //设置结点文本的字体
        renderer.setFont(new Font("StSong", Font.BOLD,16));
        //设置叶子结点图标
        renderer.setLeafIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\leaf.png"));
        //设置处于展开状态下非叶子结点图标
        renderer.setOpenIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\open.gif"));
        //设置绘制非选中状态下结点文本颜色
        renderer.setTextNonSelectionColor(new Color(255,0,0));
        //设置选中状态下结点的文本颜色
        renderer.setTextSelectionColor(new Color(0,0,255));

        //把结点绘制器设置给树对象
        tree.setCellRenderer(renderer);

        jf.add(new JScrollPane(tree));
        jf.pack();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);

    }
    public static void main(String[] args) {
        new ChangeAllCellRender().init();
    }
}
public class ExtendsDefaultCellTreeRenderer {

    JFrame jf = new JFrame("根据结点类型定义图标");

    JTree tree;

    //初始化5个图标
    ImageIcon rootIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\root.gif");
    ImageIcon databaseIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\database.gif");
    ImageIcon tableIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\table.gif");
    ImageIcon columnIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\column.gif");
    ImageIcon indexIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\index.gif");

    //定义一个NodeData类,用于封装结点数据
    class NodeData{
        public ImageIcon icon;
        public String name;

        public NodeData(ImageIcon icon, String name) {
            this.icon = icon;
            this.name = name;
        }


    }

    //定义几个初始结点
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeData(rootIcon,"数据库导航"));
    DefaultMutableTreeNode salaryDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司工资数据库"));
    DefaultMutableTreeNode customerDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司客户数据库"));
    DefaultMutableTreeNode employee = new DefaultMutableTreeNode(new NodeData(tableIcon,"员工表"));
    DefaultMutableTreeNode attend = new DefaultMutableTreeNode(new NodeData(tableIcon,"考勤表"));
    DefaultMutableTreeNode concat = new DefaultMutableTreeNode(new NodeData(tableIcon,"联系方式表"));
    DefaultMutableTreeNode id = new DefaultMutableTreeNode(new NodeData(indexIcon,"员工ID"));
    DefaultMutableTreeNode name = new DefaultMutableTreeNode(new NodeData(columnIcon,"姓名"));
    DefaultMutableTreeNode gender = new DefaultMutableTreeNode(new NodeData(columnIcon,"性别"));

    public void init(){
        //通过结点的add方法,建立结点的父子关系

        root.add(salaryDb);
        root.add(customerDb);

        salaryDb.add(employee);
        salaryDb.add(attend);

        customerDb.add(concat);

        concat.add(id);
        concat.add(name);
        concat.add(gender);

        //创建树
        tree = new JTree(root);

        //TODO 通过扩展DefaultTreeCellRenderer修改外观
        tree.setCellRenderer(new MyRenderer());


        jf.add(new JScrollPane(tree));
        jf.pack();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);

    }


    //自定义类,继承DefaultTreeCellRenderer,完成结点的绘制
    private class MyRenderer extends DefaultTreeCellRenderer {

        //重写方法


        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            //当前类间接的继承了JLabel这个组件类,展示一张图片和一些配套的文字
            //Object value这个参数,代表的就是即将要绘制的结点

            //获取当前结点
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;

            //获取到当前即将绘制的结点的名称和图标
            NodeData nodeData = (NodeData) node.getUserObject();

            //通过setText方法和setIcon方法完成设置
            this.setText(nodeData.name);
            this.setIcon(nodeData.icon);
            return this;
        }
    }

    public static void main(String[] args) {
        new ExtendsDefaultCellTreeRenderer().init();
    }

}
public class CustomerTreeNode {

    JFrame jf = new JFrame("定制树的结点");

    JTree tree;

    //定义几个初始结点

    DefaultMutableTreeNode friends = new DefaultMutableTreeNode("我的好友");
    DefaultMutableTreeNode qingzhao = new DefaultMutableTreeNode("李清照");
    DefaultMutableTreeNode suge = new DefaultMutableTreeNode("苏格拉底");
    DefaultMutableTreeNode libai = new DefaultMutableTreeNode("李白");
    DefaultMutableTreeNode nongyu = new DefaultMutableTreeNode("弄玉");
    DefaultMutableTreeNode hutou = new DefaultMutableTreeNode("虎头");

    public void init() {
        //组装视图
        friends.add(qingzhao);
        friends.add(suge);
        friends.add(libai);
        friends.add(nongyu);
        friends.add(hutou);

        tree = new JTree(friends);

        //TODO 设置结点绘制器
        MyRenderer renderer = new MyRenderer();
        tree.setCellRenderer(renderer);

        jf.add(new JScrollPane(tree));
        jf.pack();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);

    }

    //自定义类,实现TreeCellRenderer接口,绘制组件
    private class MyRenderer extends JPanel implements TreeCellRenderer {
        private ImageIcon icon;
        private String name;
        private Color background;
        private Color foreground;

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            //给成员变量设置值
            this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+value.toString()+".gif");
            this.name = value.toString();

            this.background = hasFocus? new Color(144,200,225) : new Color(255,255,255);
            this.foreground = hasFocus? new Color(255,255,3) : new Color(0,0,0);

            return this;
        }

        //通过重写getPreferenceSize方法,指定当前Jpanel组件的大小

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(80,80);
        }

        @Override
        public void paint(Graphics g) {
            //绘制组件内容

            int iconWidth = this.icon.getIconWidth();
            int iconHeight = this.icon.getIconHeight();

            //填充背景
            g.setColor(background);
            g.fillRect(0,0,getWidth(),getHeight());

            //绘制头像
            g.drawImage(this.icon.getImage(),getWidth()/2 - iconWidth/2,10,null);

            //绘制昵称
            g.setColor(foreground);

            g.setFont(new Font("StSong",Font.BOLD,18));
            g.drawString(this.name,getWidth()/2-this.name.length()*20/2,iconHeight+30);

        }
    }

    public static void main(String[] args) {
        new CustomerTreeNode().init();
    }
}

九、Swing控件修饰

1、控件边框

public class BorderTest {

    JFrame jf  = new JFrame("测试边框");

    public void init(){
        //组装视图
        //1.JFrame的布局修改为GridLayout
        jf.setLayout(new GridLayout(2,4));

        //2.往网格中填充不同的JPanel组件,并且设置边框和内容

        //创建BevelBorder
        Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.GREEN, Color.BLUE, Color.GRAY);
        jf.add(getJPanelWithBorder(bevelBorder,"BevelBorder"));

        //创建LineBorder
        Border lineBorder = BorderFactory.createLineBorder(Color.ORANGE, 10);
        jf.add(getJPanelWithBorder(lineBorder,"LineBorder"));

        //创建EmptyBorder
        Border emptyBorder = BorderFactory.createEmptyBorder(10, 5, 20, 10);
        jf.add(getJPanelWithBorder(emptyBorder,"EmptyBorder"));

        //创建EchtedBorder
        Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);
        jf.add(getJPanelWithBorder(etchedBorder,"EtchedBorder"));

        //创建TitledBorder
        TitledBorder titledBorder = new TitledBorder(new LineBorder(Color.ORANGE,10),"测试标题",TitledBorder.LEFT,TitledBorder.BOTTOM,new Font("StSong", Font.BOLD,18),Color.BLUE);
        jf.add(getJPanelWithBorder(titledBorder,"TitledBorder"));

        //创建MatteBorder
        MatteBorder matteBorder = new MatteBorder(10, 5, 20, 10, Color.GREEN);
        jf.add(getJPanelWithBorder(matteBorder,"MatteBorder"));

        //创建CompoundBorder
        CompoundBorder compoundBorder = new CompoundBorder( new LineBorder(Color.RED, 10),titledBorder);
        jf.add(getJPanelWithBorder(compoundBorder,"CompoundBorder"));

        //3.设置窗口最佳大小、设置窗口可见,处理关闭操作
        jf.pack();
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public JPanel getJPanelWithBorder(Border border,String content){
        JPanel jPanel = new JPanel();
        jPanel.add(new JLabel(content));

        //设置边框
        jPanel.setBorder(border);

        return jPanel;
    }

    public static void main(String[] args) {
        new BorderTest().init();
    }
}

idea插件开发(5)-Swing图形化设计_第23张图片

你可能感兴趣的:(Idea插件开发,intellij-idea,java,ide,swing,awt)