当前位置:   article > 正文

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

idea 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开发基本都遵循如下关系来设计:

2、Swing体系

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

 二、Swing容器

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

1、JFrame

        显示一个空白窗口

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

2、JDialog

  1. public class DialogTest {
  2. public static void main(String[] args) {
  3. JFrame frame = new JFrame("这里测试Dialog");
  4. JDialog d1 = new JDialog(frame, "模式对话框", true);
  5. //2.通过setBounds方法设置Dialog的位置以及大小
  6. d1.setBounds(20,30,300,200);
  7. //3.创建两个按钮
  8. JButton b1 = new JButton("打开模式对话框");
  9. //4.给这两个按钮添加点击后的行为
  10. b1.addActionListener(new ActionListener() {
  11. @Override
  12. public void actionPerformed(ActionEvent e) {
  13. d1.setVisible(true);
  14. }
  15. });
  16. //5.把按钮添加到frame中
  17. frame.add(b1, BorderLayout.NORTH);
  18. //设置frame最佳大小并可见
  19. frame.pack();
  20. frame.setVisible(true);
  21. }
  22. }

 

3、MessageDialog

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

  1. public class MessageDialogTest {
  2. JFrame jf = new JFrame("测试消息对话框");
  3. JTextArea jta = new JTextArea(6, 30);
  4. //声明按钮
  5. JButton btn = new JButton(new AbstractAction("弹出消息对话框") {
  6. @Override
  7. public void actionPerformed(ActionEvent e) {
  8. //弹出一个消息对话框,并且显示 文本域中输入的内容
  9. String text = jta.getText();
  10. //参数:int messageType 指定消息对话框的类型: 错误消息,警告消息,问题消息...
  11. //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.ERROR_MESSAGE);
  12. //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.INFORMATION_MESSAGE);
  13. //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE);
  14. //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.QUESTION_MESSAGE);
  15. //JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.PLAIN_MESSAGE);
  16. JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE,new ImageIcon("E:\\GUISwing\\img\\component\\female.png"));
  17. }
  18. });
  19. public void init(){
  20. //组装视图
  21. jf.add(jta);
  22. jf.add(btn, BorderLayout.SOUTH);
  23. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  24. jf.pack();
  25. jf.setVisible(true);
  26. }
  27. public static void main(String[] args) {
  28. new MessageDialogTest().init();
  29. }

4、为容器添加工具栏

Frame菜单

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

  1. public class SimpleMenu {
  2. //创建窗口
  3. private JFrame frame = new JFrame("这里测试菜单相关组件");
  4. //创建菜单条
  5. JMenuBar menuBar = new JMenuBar();
  6. //创建菜单组件
  7. JMenu fileMenu = new JMenu("文件");
  8. JMenu editMenu = new JMenu("编辑");
  9. //菜单项组件
  10. JMenuItem copy = new JMenuItem("复制");
  11. JMenuItem paste = new JMenuItem("粘贴");
  12. public void init(){
  13. //组装编辑菜单
  14. editMenu.add(copy);
  15. editMenu.add(paste);
  16. //组装菜单条
  17. menuBar.add(fileMenu);
  18. menuBar.add(editMenu);
  19. //把菜单条放入到Frame中
  20. frame.setJMenuBar(menuBar);
  21. //设置frame最佳大小并可见
  22. frame.pack();
  23. frame.setVisible(true);
  24. }
  25. public static void main(String[] args) {
  26. new SimpleMenu().init();
  27. }
  28. }

Toolbar工具栏

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

  1. public class JToolBarTest {
  2. JFrame jf = new JFrame("测试工具条");
  3. JTextArea jta = new JTextArea(6,35);
  4. //声明工具条相关内容
  5. JToolBar jToolBar = new JToolBar("播放工具条",SwingConstants.HORIZONTAL);
  6. //创建3个Action对象
  7. //传递的参数,name和icon,最终在添加到工具条中时,会被拿出来作为按钮的名称和图标
  8. Action pre = new AbstractAction("上一曲",new ImageIcon("E:\\GUISwing\\img\\component\\上一曲16.png")) {
  9. @Override
  10. public void actionPerformed(ActionEvent e) {
  11. jta.append("上一曲.\n");
  12. }
  13. };
  14. public void init(){
  15. //通过Action对象来创建JButton
  16. JButton preBtn = new JButton(pre);
  17. jToolBar.add(preBtn);
  18. jToolBar.addSeparator();
  19. //让工具条可以拖动
  20. jToolBar.setFloatable(true);
  21. jf.add(jToolBar, BorderLayout.NORTH);
  22. //把一个组件设置到JScrollPane中,那么该组件就支持滚动条了
  23. JScrollPane jScrollPane = new JScrollPane(jta);
  24. jf.add(jScrollPane);
  25. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  26. jf.pack();
  27. jf.setVisible(true);
  28. }
  29. public static void main(String[] args) {
  30. new JToolBarTest().init();
  31. }
  32. }

5、特殊容器

 JSplitPane-可调整大小的面板

  1. public class SplitPaneTest {
  2. Book[] books = {new Book("java自学宝典", "国内关于 Java 编程最全面的图书 \n 看得懂 , 学得会"),
  3. new Book("轻量级的JAVAEE企业应用实战", "SSM整合开发的经典图书,值的拥有"),
  4. };
  5. JFrame jf = new JFrame("测试JSplitPane");
  6. //声明程序中用到的组件
  7. JList<Book> bookJList = new JList<>(books);
  8. JLabel bookCover = new JLabel();
  9. JTextArea bookDesc = new JTextArea();
  10. public void init(){
  11. //组装视图
  12. //设定组件大小
  13. bookJList.setPreferredSize(new Dimension(150,400));
  14. bookCover.setPreferredSize(new Dimension(220,270));
  15. bookDesc.setPreferredSize(new Dimension(220,130));
  16. //为jList设置条目选中监听器
  17. bookJList.addListSelectionListener(new ListSelectionListener() {
  18. @Override
  19. public void valueChanged(ListSelectionEvent e) {
  20. //获取当前选中的是哪个条目
  21. Book book = bookJList.getSelectedValue();
  22. //把书籍的图片用bookCover展示
  23. bookDesc.setText(book.getDesc());
  24. }
  25. });
  26. //组装左边区域
  27. JSplitPane left = new JSplitPane(JSplitPane.VERTICAL_SPLIT,bookCover,new JScrollPane(bookDesc));
  28. left.setOneTouchExpandable(true);//一触即展
  29. //组装整体
  30. JSplitPane hole = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,left,bookJList);
  31. //支持连续布局
  32. hole.setContinuousLayout(true);
  33. hole.setDividerSize(10);
  34. jf.add(hole);
  35. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  36. jf.pack();
  37. jf.setVisible(true);
  38. }
  39. public static void main(String[] args) {
  40. new SplitPaneTest().init();
  41. }
  42. }
  43. @Data
  44. @AllArgsConstructor
  45. class Book {
  46. private String name;
  47. private String desc;
  48. }

 TabbedPane-标签页面板

  1. public class JTabbedPaneTest {
  2. JFrame jf = new JFrame("测试JTabbedPane");
  3. JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.LEFT,JTabbedPane.SCROLL_TAB_LAYOUT);
  4. public void init(){
  5. //添加标签
  6. tabbedPane.addTab("用户管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList<String>(new String[]{"用户一","用户二","用户三"}));
  7. tabbedPane.addTab("商品管理",new JList<String>(new String[]{"商品一","商品二","商品三"}));
  8. tabbedPane.addTab("订单管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList<String>(new String[]{"订单一","订单二","订单三","订单四"}));
  9. //完成设置
  10. tabbedPane.setEnabledAt(0,false);//禁用用户管理
  11. tabbedPane.setSelectedIndex(1);//默认商品管理
  12. //监听当前标签面板的选中情况
  13. tabbedPane.addChangeListener(new ChangeListener() {
  14. @Override
  15. public void stateChanged(ChangeEvent e) {
  16. int selectedIndex = tabbedPane.getSelectedIndex();
  17. JOptionPane.showMessageDialog(jf,"当前选中了第 "+(selectedIndex+1)+"个标签");
  18. }
  19. });
  20. jf.add(tabbedPane);
  21. jf.setBounds(400,400,400,400);
  22. jf.setResizable(false);
  23. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  24. jf.setVisible(true);
  25. }
  26. public static void main(String[] args) {
  27. new JTabbedPaneTest().init();
  28. }
  29. }

三、Swing布局

1、BorderLayout

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

  1. public class BorderLayoutTest extends JFrame { //0.继承JFrame
  2. public BorderLayoutTest() {
  3. //1. 创建组件
  4. JButton jButton = new JButton("中间");
  5. JButton jButton2 = new JButton("北间");
  6. JButton jButton3 = new JButton("西间");
  7. JButton jButton4 = new JButton("东间");
  8. JButton jButton5 = new JButton("南间");
  9. //2. 添加各个组件
  10. this.add(jButton, BorderLayout.CENTER); //布局的中间
  11. this.add(jButton2, BorderLayout.NORTH); //布局的北边
  12. this.add(jButton3, BorderLayout.WEST); //布局的西边
  13. this.add(jButton4, BorderLayout.EAST); //布局的东边
  14. this.add(jButton5, BorderLayout.SOUTH); //布局的南边
  15. //3. 设置窗体属性
  16. this.setTitle("演示边界布局管理器");
  17. this.setSize(300, 200);
  18. this.setLocation(200, 200);
  19. this.setVisible(true);
  20. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  21. }
  22. public static void main(String[] args) {
  23. new BorderLayoutTest();
  24. }
  25. }

 2、FlowLayout

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

  1. public class FlowLayoutTest extends JFrame { //0.继承JFrame
  2. public FlowLayoutTest() {
  3. //1. 创建组件
  4. JButton jButton1 = new JButton("A");
  5. JButton jButton2 = new JButton("B");
  6. JButton jButton3 = new JButton("C");
  7. JButton jButton4 = new JButton("D");
  8. JButton jButton5 = new JButton("E");
  9. //2. 添加各个组件
  10. this.add(jButton1);
  11. this.add(jButton2);
  12. this.add(jButton3);
  13. this.add(jButton4);
  14. this.add(jButton5);
  15. //设置流布局
  16. this.setLayout(new FlowLayout(FlowLayout.LEFT));
  17. //4. 设置窗体属性
  18. this.setTitle("演示流布局管理器"); //设置标题
  19. this.setSize(300, 200); //设置
  20. this.setLocation(200, 200); //设置窗体出现的位置
  21. this.setVisible(true); //设置窗体可见
  22. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体关闭的同时关闭jvm
  23. this.setResizable(false); //Resizable:可调整大小的,设置窗体大小不可变
  24. }
  25. public static void main(String[] args) {
  26. new FlowLayoutTest();
  27. }
  28. }

 3、GridLayout

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

  1. public class GridLayoutTest extends JFrame {
  2. //定义组件
  3. int size = 9;
  4. //定义按钮数组
  5. JButton jButton[] = new JButton[size];
  6. //构造函数
  7. public GridLayoutTest() {
  8. //创建组件
  9. for(int i = 0; i<size; i++){
  10. jButton[i] = new JButton(String.valueOf(i+1));
  11. this.add(jButton[i]);
  12. }
  13. //设置网格布局
  14. this.setLayout(new GridLayout(3, 3, 10, 30));
  15. //设置窗格属性
  16. this.setTitle("演示网格布局管理器");
  17. this.setSize(400, 400);
  18. this.setLocation(200, 200);
  19. this.setVisible(true);
  20. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  21. this.setResizable(false); //Resizable:可调整大小的
  22. }
  23. public static void main(String[] args) {
  24. GridLayoutTest testGridLayout = new GridLayoutTest();
  25. }
  26. }

4、BoxLayout

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

  1. public class BoxLayoutTest {
  2. public static void main(String[] args) {
  3. Frame frame = new Frame("这里测试BoxLayout");
  4. //1.基于frame容器,创建一个BoxLayout对象,并且,该对象存放组件是垂直存放
  5. //BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
  6. BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);//水平排列
  7. //2.把BoxLayout对象设置给Frame
  8. frame.setLayout(boxLayout);
  9. //3.往frame中添加两个按钮组件
  10. frame.add(new Button("按钮1"));
  11. frame.add(new Button("按钮2"));
  12. frame.pack();
  13. frame.setVisible(true);
  14. }
  15. }

  四、Swing事件

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

1、定制侦听器

  1. public class EventDemo1 {
  2. Frame frame = new Frame("这里测试事件处理");
  3. TextField tf = new TextField(30);
  4. //事件源
  5. Button ok = new Button("确定");
  6. public void init(){//组装视图
  7. //注册监听
  8. ok.addActionListener(new ActionListener() {
  9. @Override
  10. public void actionPerformed(ActionEvent e) {
  11. System.out.println("ok按钮被点击了...");
  12. tf.setText("Hello World");
  13. }
  14. });
  15. //把tf和ok放入到Frame中
  16. frame.add(tf, BorderLayout.NORTH);
  17. frame.add(ok);
  18. frame.pack();
  19. frame.setVisible(true);
  20. }
  21. public static void main(String[] args) {
  22. new EventDemo1().init();
  23. }
  24. }

2、共享侦听器

  1. public class EventDemo1 {
  2. Frame frame = new Frame("这里测试事件处理");
  3. TextField tf = new TextField(30);
  4. Button ok = new Button("确定");
  5. public void init(){//组装视图
  6. //监听器,这种写法适合公共监听器,后面多个摈控件通过addActionListener()来共享
  7. MyListener myListener = new MyListener();
  8. ok.addActionListener(myListener);
  9. //把tf和ok放入到Frame中
  10. frame.add(tf, BorderLayout.NORTH);
  11. frame.add(ok);
  12. frame.pack();
  13. frame.setVisible(true);
  14. }
  15. public static void main(String[] args) {
  16. new EventDemo1().init();
  17. }
  18. }
  19. class MyListener implements ActionListener{
  20. @Override
  21. public void actionPerformed(ActionEvent e) {
  22. System.out.println("ok按钮被点击了...");
  23. }
  24. }

五、Swing进度条

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

1、主线程内的进度条

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

  1. public class JProgressTest {
  2. JFrame jf = new JFrame("测试进度条");
  3. //创建进度条
  4. JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
  5. public void init(){
  6. //组装视图
  7. Box vBox = Box.createVerticalBox();
  8. //设置进度条的属性
  9. bar.setStringPainted(true);
  10. bar.setBorderPainted(true);
  11. //把当前窗口的布局方式修改为FlowLayout
  12. jf.setLayout(new FlowLayout());
  13. jf.add(vBox);
  14. jf.add(bar);
  15. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  16. jf.pack();
  17. jf.setVisible(true);
  18. //通过循环模拟修改进度条的进度
  19. for (int i = 0; i <= 100; i++) {
  20. //修改已经完成的工作量,也就是百分比
  21. bar.setValue(i);
  22. try {
  23. Thread.sleep(500);
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  29. public static void main(String[] args) {
  30. new JProgressTest().init();
  31. }
  32. }

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

  1. public class JProgressTest2 {
  2. JFrame jf = new JFrame("测试进度条");
  3. //创建进度条
  4. JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
  5. public void init(){
  6. //组装视图
  7. Box vBox = Box.createVerticalBox();
  8. //设置进度条的属性
  9. bar.setStringPainted(true);
  10. bar.setBorderPainted(true);
  11. //把当前窗口的布局方式修改为FlowLayout
  12. jf.setLayout(new FlowLayout());
  13. jf.add(vBox);
  14. jf.add(bar);
  15. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  16. jf.pack();
  17. jf.setVisible(true);
  18. //开启子线程,模拟耗时操作
  19. SimulaterActivity simulaterActivity = new SimulaterActivity();
  20. simulaterActivity.setAmount(bar.getMaximum());
  21. new Thread(simulaterActivity).start();
  22. //设置一个定时任务
  23. Timer timer = new Timer(200, new ActionListener() {
  24. @Override
  25. public void actionPerformed(ActionEvent e) {
  26. //读取线程任务对象的当前完成量,设置给进度条
  27. int current = simulaterActivity.getCurrent();
  28. bar.setValue(current);
  29. }
  30. });
  31. timer.start();
  32. //监听进度条的任务变化
  33. bar.addChangeListener(new ChangeListener() {
  34. @Override
  35. public void stateChanged(ChangeEvent e) {
  36. int value = bar.getValue();
  37. if (value == simulaterActivity.getAmount()){
  38. timer.stop();
  39. }
  40. }
  41. });
  42. }
  43. @Data
  44. private class SimulaterActivity implements Runnable{
  45. //记录任务总量
  46. private int amount;
  47. //记录当前任务的完成量
  48. private volatile int current;
  49. @Override
  50. public void run() {
  51. //子线程的任务 模拟耗时操作
  52. while(current<amount){
  53. try {
  54. Thread.currentThread().sleep(50);
  55. } catch (InterruptedException e) {
  56. e.printStackTrace();
  57. }
  58. current++;
  59. }
  60. }
  61. }
  62. public static void main(String[] args) {
  63. new JProgressTest2().init();
  64. }
  65. }

 3、获取进度条数据

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

  1. public class JProgressTest3 {
  2. JFrame jf = new JFrame("测试进度条");
  3. //创建进度条
  4. JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
  5. //获取处进度条内置的数据模型对象
  6. BoundedRangeModel model = bar.getModel();
  7. public void init(){
  8. //组装视图
  9. Box vBox = Box.createVerticalBox();
  10. //设置进度条的属性
  11. bar.setStringPainted(true);
  12. bar.setBorderPainted(true);
  13. //把当前窗口的布局方式修改为FlowLayout
  14. jf.setLayout(new FlowLayout());
  15. jf.add(vBox);
  16. jf.add(bar);
  17. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  18. jf.pack();
  19. jf.setVisible(true);
  20. //开启子线程,模拟耗时操作
  21. SimulaterActivity simulaterActivity = new SimulaterActivity();
  22. simulaterActivity.setAmount(bar.getMaximum());
  23. new Thread(simulaterActivity).start();
  24. //设置一个定时任务
  25. Timer timer = new Timer(200, new ActionListener() {
  26. @Override
  27. public void actionPerformed(ActionEvent e) {
  28. //读取线程任务对象的当前完成量,设置给进度条
  29. int current = simulaterActivity.getCurrent();
  30. model.setValue(current);
  31. }
  32. });
  33. timer.start();
  34. //监听进度条的任务变化
  35. model.addChangeListener(new ChangeListener() {
  36. @Override
  37. public void stateChanged(ChangeEvent e) {
  38. int value = model.getValue();
  39. if (value == simulaterActivity.getAmount()){
  40. timer.stop();
  41. }
  42. }
  43. });
  44. }
  45. @Data
  46. private class SimulaterActivity implements Runnable{
  47. //记录任务总量
  48. private int amount;
  49. //记录当前任务的完成量
  50. private volatile int current;
  51. @Override
  52. public void run() {
  53. //子线程的任务 模拟耗时操作
  54. while(current<amount){
  55. try {
  56. Thread.currentThread().sleep(50);
  57. } catch (InterruptedException e) {
  58. e.printStackTrace();
  59. }
  60. current++;
  61. }
  62. }
  63. }
  64. public static void main(String[] args) {
  65. new JProgressTest2().init();
  66. }
  67. }

4、ProgressMonitor

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

  1. public class ProgressMonitorTest {
  2. Timer timer;
  3. public void init(){
  4. //创建进度对话框
  5. ProgressMonitor monitor = new ProgressMonitor(null,"等待任务完成","已完成",0,100);
  6. SimulaterActivity simulaterActivity = new SimulaterActivity(100);
  7. new Thread(simulaterActivity).start();
  8. //设置定时任务
  9. timer = new Timer(200, new ActionListener() {
  10. @Override
  11. public void actionPerformed(ActionEvent e) {
  12. //读取当前任务量,修改进度
  13. int current = simulaterActivity.getCurrent();
  14. monitor.setProgress(current);
  15. //判断用户是否点击了取消按钮,停止定时任务,关闭对话框,退出程序
  16. if (monitor.isCanceled()){
  17. timer.stop();
  18. monitor.close();
  19. System.exit(0);
  20. }
  21. }
  22. });
  23. timer.start();
  24. }
  25. public static void main(String[] args) {
  26. new ProgressMonitorTest().init();
  27. }
  28. //定义一个线程任务,模拟耗时操作
  29. @Data
  30. private class SimulaterActivity implements Runnable{
  31. //内存可见
  32. private volatile int current = 0;
  33. private int amount;
  34. public SimulaterActivity(int amount) {
  35. this.amount = amount;
  36. }
  37. @Override
  38. public void run() {
  39. //通过循环,不断的修改current的值,模拟任务完成量
  40. while(current<amount){
  41. try {
  42. Thread.sleep(50);
  43. } catch (InterruptedException e) {
  44. e.printStackTrace();
  45. }
  46. current++;
  47. }
  48. }
  49. }
  50. }

六、Swing下拉列表

1、简单列表

  1. public class ListTest {
  2. JFrame jf = new JFrame("列表框测试");
  3. String[] books = {"java自学宝典","轻量级javaEE企业应用实战","Android基础教程","jQuery实战教程","SpringBoot企业级开发"};
  4. //定义 布局选择按钮 所在的面板
  5. JPanel layoutPanel = new JPanel();
  6. ButtonGroup layoutGroup = new ButtonGroup();
  7. //定义 选择模式按钮 所在面板
  8. JPanel selectModePanel = new JPanel();
  9. ButtonGroup selectModeGroup = new ButtonGroup();
  10. //用一个字符串数组来创建一个JList对象
  11. JList<String> bookList ;
  12. JComboBox<String> bookSelector;
  13. public void init(){
  14. //组装视图
  15. //组装Jlist相关内容
  16. bookList = new JList<>(books);
  17. addBtn2LayoutPanel("纵向滚动",JList.VERTICAL);
  18. addBtn2LayoutPanel("纵向换行",JList.VERTICAL_WRAP);
  19. addBtn2LayoutPanel("横向换行",JList.HORIZONTAL_WRAP);
  20. addBtn2SelectModelPanel("无限制",ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  21. addBtn2SelectModelPanel("单选",ListSelectionModel.SINGLE_SELECTION);
  22. addBtn2SelectModelPanel("单范围",ListSelectionModel.SINGLE_INTERVAL_SELECTION);
  23. //对JList做设置
  24. bookList.setVisibleRowCount(3);
  25. bookList.setSelectionInterval(2,4);
  26. //处理条目选中事件
  27. bookList.addListSelectionListener(new ListSelectionListener() {
  28. @Override
  29. public void valueChanged(ListSelectionEvent e) {
  30. //获取当前选中的条目
  31. java.util.List<String> selectedValuesList = bookList.getSelectedValuesList();
  32. //把当前条目的内容设置到文本域中。
  33. }
  34. });
  35. Box bookListVBox = Box.createVerticalBox();
  36. bookListVBox.add(new JScrollPane(bookList));
  37. bookListVBox.add(layoutPanel);
  38. bookListVBox.add(selectModePanel);
  39. //组装JComboBox
  40. Vector<String> vector = new Vector<>();
  41. for (int i = 0; i < books.length; i++) {
  42. vector.add(books[i]);
  43. }
  44. bookSelector = new JComboBox<>(vector);
  45. bookSelector.setEditable(true);
  46. bookSelector.setMaximumRowCount(4);
  47. //组装顶部的左右两部分
  48. Box topBox = Box.createHorizontalBox();
  49. topBox.add(bookListVBox);
  50. JPanel bookSelectPanel = new JPanel();
  51. bookSelectPanel.add(bookSelector);
  52. topBox.add(bookSelectPanel);
  53. //组装底部
  54. JPanel bottomPanel = new JPanel();
  55. bottomPanel.setLayout(new BorderLayout());
  56. //组装整体
  57. Box holeBox = Box.createVerticalBox();
  58. holeBox.add(topBox);
  59. holeBox.add(bottomPanel);
  60. jf.add(holeBox);
  61. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  62. jf.pack();
  63. jf.setVisible(true);
  64. }
  65. //封装方法,往layoutPanel中添加单选按钮
  66. public void addBtn2LayoutPanel(String name,int layoutType){
  67. //设置标题边框
  68. layoutPanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选项布局"));
  69. //创建单选按钮
  70. JRadioButton button = new JRadioButton(name);
  71. layoutPanel.add(button);
  72. //让第一个按钮默认选中
  73. if (layoutGroup.getButtonCount()==0){
  74. button.setSelected(true);
  75. }
  76. layoutGroup.add(button);
  77. button.addActionListener(new ActionListener() {
  78. @Override
  79. public void actionPerformed(ActionEvent e) {
  80. bookList.setLayoutOrientation(layoutType);
  81. }
  82. });
  83. }
  84. //封装方法,给selectModelPanel添加按钮
  85. public void addBtn2SelectModelPanel(String name,int selectionModel){
  86. //设置标题边框
  87. selectModePanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选择模式"));
  88. //创建单选按钮
  89. JRadioButton button = new JRadioButton(name);
  90. selectModePanel.add(button);
  91. //让第一个按钮默认选中
  92. if (selectModeGroup.getButtonCount()==0){
  93. button.setSelected(true);
  94. }
  95. selectModeGroup.add(button);
  96. button.addActionListener(new ActionListener() {
  97. @Override
  98. public void actionPerformed(ActionEvent e) {
  99. bookList.setSelectionMode(selectionModel);
  100. }
  101. });
  102. }
  103. public static void main(String[] args) {
  104. new ListTest().init();
  105. }
  106. }

 2、固定值的列表

  1. public class NumberListModel extends AbstractListModel<BigDecimal> {
  2. BigDecimal start;
  3. BigDecimal end;
  4. BigDecimal step;
  5. public NumberListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
  6. this.start = start;
  7. this.end = end;
  8. this.step = step;
  9. }
  10. @Override
  11. public int getSize() {
  12. int floor = (int) Math.floor(end.subtract(start).divide(step,2, RoundingMode.HALF_DOWN).doubleValue());
  13. return floor+1;
  14. }
  15. @Override
  16. public BigDecimal getElementAt(int index) {
  17. BigDecimal ele = new BigDecimal(index).multiply(step).add(start).setScale(2, RoundingMode.HALF_DOWN);
  18. return ele;
  19. }
  20. }
  1. public class NumberComboBoxListModel extends NumberListModel implements ComboBoxModel<BigDecimal> {
  2. //当前选中条目的索引
  3. private int selectedId;
  4. public NumberComboBoxListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
  5. super(start, end, step);
  6. }
  7. @Override
  8. public void setSelectedItem(Object anItem) {
  9. if (anItem instanceof BigDecimal){
  10. BigDecimal curr = (BigDecimal) anItem;
  11. selectedId = curr.subtract(super.start).divide(super.step,2, RoundingMode.HALF_DOWN).intValue();
  12. }
  13. }
  14. @Override
  15. public Object getSelectedItem() {
  16. BigDecimal item = new BigDecimal(selectedId).multiply(super.step).add(super.start).setScale(1, RoundingMode.HALF_DOWN);
  17. return item;
  18. }
  19. }
  1. public class ListModelTest {
  2. JFrame jf = new JFrame("测试ListModel");
  3. JList<BigDecimal> jList = new JList<>(new NumberListModel(new BigDecimal(1),new BigDecimal(21),new BigDecimal(2)));
  4. JComboBox<BigDecimal> jComboBox = new JComboBox<>(new NumberComboBoxListModel(new BigDecimal(0.1),new BigDecimal(1.2),new BigDecimal(0.1)));
  5. JLabel label = new JLabel("您选择的值是:");
  6. JTextField jTextField = new JTextField(15);
  7. public void init(){
  8. //组装视图
  9. //组装顶部
  10. jList.setVisibleRowCount(4);
  11. jList.setSelectionInterval(2,4);
  12. jList.setFixedCellWidth(90);
  13. jList.setFixedCellHeight(30);
  14. jList.addListSelectionListener(new ListSelectionListener() {
  15. @Override
  16. public void valueChanged(ListSelectionEvent e) {
  17. java.util.List<BigDecimal> selectedValuesList = jList.getSelectedValuesList();
  18. jTextField.setText("");
  19. for (BigDecimal item : selectedValuesList) {
  20. jTextField.setText(jTextField.getText()+item.toString()+",");
  21. }
  22. }
  23. });
  24. jComboBox.setMaximumRowCount(4);
  25. jComboBox.addItemListener(new ItemListener() {
  26. @Override
  27. public void itemStateChanged(ItemEvent e) {
  28. Object selectedItem = jComboBox.getSelectedItem();
  29. jTextField.setText(selectedItem.toString());
  30. }
  31. });
  32. Box hBox = Box.createHorizontalBox();
  33. hBox.add(new JScrollPane(jList));
  34. JPanel tempPanel = new JPanel();
  35. tempPanel.add(jComboBox);
  36. hBox.add(tempPanel);
  37. jf.add(hBox);
  38. //组装底部
  39. JPanel bottomPanel = new JPanel();
  40. bottomPanel.add(label);
  41. bottomPanel.add(jTextField);
  42. jf.add(bottomPanel, BorderLayout.SOUTH);
  43. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  44. jf.pack();
  45. jf.setVisible(true);
  46. }
  47. public static void main(String[] args) {
  48. new ListModelTest().init();
  49. }
  50. }

 3、动态改变列表的值

  1. public class DefaultListModelTest {
  2. JFrame jf = new JFrame("测试DefaultListModel");
  3. JTextField bookName = new JTextField(20);
  4. JButton removeBtn = new JButton("删除选中图书");
  5. JButton addBtn = new JButton("添加指定图书");
  6. //创建JList
  7. JList<String> bookList;
  8. DefaultListModel<String> model = new DefaultListModel<>();
  9. public void init(){
  10. //组装视图
  11. model.addElement("java自学宝典");
  12. model.addElement("轻量级JavaEE企业应用实战");
  13. model.addElement("Android基础教程");
  14. model.addElement("JQuery实战教程");
  15. bookList = new JList<>(model);
  16. //设置Jlist
  17. bookList.setVisibleRowCount(4);
  18. //设置单选
  19. bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  20. jf.add(new JScrollPane(bookList));
  21. //组装底部
  22. addBtn.addActionListener(new ActionListener() {
  23. @Override
  24. public void actionPerformed(ActionEvent e) {
  25. String name = bookName.getText();
  26. if (!name.trim().equals("")){//不是空字符串才添加
  27. model.addElement(name);
  28. }
  29. }
  30. });
  31. removeBtn.addActionListener(new ActionListener() {
  32. @Override
  33. public void actionPerformed(ActionEvent e) {
  34. int selectedIndex = bookList.getSelectedIndex();
  35. if (selectedIndex>=0){
  36. model.remove(selectedIndex);
  37. }
  38. }
  39. });
  40. JPanel bottomPanel = new JPanel();
  41. bottomPanel.add(bookName);
  42. bottomPanel.add(addBtn);
  43. bottomPanel.add(removeBtn);
  44. jf.add(bottomPanel, BorderLayout.SOUTH);
  45. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  46. jf.pack();
  47. jf.setVisible(true);
  48. }
  49. public static void main(String[] args) {
  50. new DefaultListModelTest().init();
  51. }
  52. }

 4、改变列表控件外观

  1. public class ListCellRendererTest {
  2. private JFrame mainWin = new JFrame("好友列表");
  3. private String[] friends = {
  4. "李清照",
  5. "苏格拉底",
  6. "李白",
  7. "弄玉",
  8. "虎头"
  9. };
  10. //定义一个JList对象
  11. JList friendsList = new JList(friends);
  12. public void init() {
  13. //组装视图
  14. //给JList设置ListCellRenderer对象,指定列表项绘制的组件
  15. friendsList.setCellRenderer(new MyRenderer());
  16. mainWin.add(friendsList);
  17. mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  18. mainWin.pack();
  19. mainWin.setVisible(true);
  20. }
  21. private class MyRenderer extends JPanel implements ListCellRenderer{
  22. private String name;
  23. private ImageIcon icon;
  24. //记录背景色
  25. private Color backGround;
  26. //记录前景色:文字的颜色
  27. private Color forceGround;
  28. @Override
  29. public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
  30. //重置成员变量的值
  31. this.name = value.toString();
  32. this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+name+".gif");
  33. this.backGround = isSelected? list.getSelectionBackground() : list.getBackground();
  34. this.forceGround = isSelected? list.getSelectionForeground() : list.getForeground();
  35. return this;
  36. }
  37. @Override
  38. public Dimension getPreferredSize() {
  39. return new Dimension(60,80);
  40. }
  41. //绘制列表项的内容
  42. @Override
  43. public void paint(Graphics g) {
  44. int imageWidth = icon.getImage().getWidth(null);
  45. int imageHeight = icon.getImage().getHeight(null);
  46. //填充背景矩形
  47. g.setColor(backGround);
  48. g.fillRect(0,0,getWidth(),getHeight());
  49. //绘制头像
  50. g.drawImage(icon.getImage(),this.getWidth()/2 -imageWidth/2 ,10,null);
  51. //绘制昵称
  52. g.setColor(forceGround);
  53. g.setFont(new Font("StSong",Font.BOLD,18));
  54. g.drawString(this.name,this.getWidth()/2 - this.name.length()*20/2,imageHeight+30);
  55. }
  56. }
  57. public static void main(String[] args) {
  58. new ListCellRendererTest().init();
  59. }
  60. }

七、Swing表格

1、简单表格

  1. public class SimpleTable {
  2. JFrame jf = new JFrame("简单表格");
  3. //创建一维数组,存储标题
  4. Object[] titles = {"姓名","年龄","性别"};
  5. //创建二维数组,存储数据
  6. Object[][] data = {
  7. {"李清照",29,"女"},
  8. {"苏格拉底",56,"男"},
  9. {"李白",35,"男"},
  10. {"弄玉",18,"女"},
  11. {"虎头",2,"男"}
  12. };
  13. public void init(){
  14. //组装视图
  15. JTable jTable = new JTable(data,titles);
  16. jf.add(new JScrollPane(jTable));
  17. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  18. jf.pack();
  19. jf.setVisible(true);
  20. }
  21. public static void main(String[] args) {
  22. new SimpleTable().init();
  23. }
  24. }

2、TableModel

  1. public class TableModelTest {
  2. JFrame jf = new JFrame("TableModel演示");
  3. //创建一维数组,存储标题
  4. Object[] titles = {"姓名","年龄","性别"};
  5. //创建二维数组,存储数据
  6. Object[][] data = {
  7. {"李清照",29,"女"},
  8. {"苏格拉底",56,"男"},
  9. {"李白",35,"男"},
  10. {"弄玉",18,"女"},
  11. {"虎头",2,"男"}
  12. };
  13. private Vector titlesV = new Vector();//存储标题
  14. private Vector<Vector> dataV = new Vector<>();//存储数据
  15. public void init(){
  16. //组装视图
  17. for (int i = 0; i < titles.length; i++) {
  18. titlesV.add(titles[i]);
  19. }
  20. for (int i = 0; i < data.length; i++) {
  21. Vector t = new Vector<>();
  22. for (int j = 0; j < data[i].length; j++) {
  23. t.add(data[i][j]);
  24. }
  25. dataV.add(t);
  26. }
  27. MyTableModel myTableModel = new MyTableModel();
  28. //JTable jTable = new JTable(dataV,titlesV);
  29. JTable jTable = new JTable(myTableModel);
  30. jf.add(new JScrollPane(jTable));
  31. JButton btn = new JButton("获取选中行数据");
  32. btn.addActionListener(new ActionListener() {
  33. @Override
  34. public void actionPerformed(ActionEvent e) {
  35. int selectedColumn = jTable.getSelectedColumn();
  36. int selectedRow = jTable.getSelectedRow();
  37. System.out.println("当前选中行的索引:"+selectedRow);
  38. System.out.println("当前选中列的索引:"+selectedColumn);
  39. Object value = myTableModel.getValueAt(selectedRow, selectedColumn);
  40. System.out.println("当前选中行第一个单元格的内容为:"+value);
  41. }
  42. });
  43. jf.add(btn, BorderLayout.SOUTH);
  44. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  45. jf.pack();
  46. jf.setVisible(true);
  47. }
  48. private class MyTableModel extends AbstractTableModel {
  49. @Override
  50. public int getRowCount() {
  51. return dataV.size();
  52. }
  53. @Override
  54. public int getColumnCount() {
  55. return titlesV.size();
  56. }
  57. @Override
  58. public Object getValueAt(int rowIndex, int columnIndex) {
  59. return dataV.get(rowIndex).get(columnIndex);
  60. }
  61. @Override
  62. public String getColumnName(int column) {
  63. return (String) titlesV.get(column);
  64. }
  65. @Override
  66. public boolean isCellEditable(int rowIndex, int columnIndex) {
  67. return false;
  68. }
  69. }
  70. public static void main(String[] args) {
  71. new TableModelTest().init();
  72. }
  73. }
  1. public class DefaultTableModelTest {
  2. JFrame jf = new JFrame("TableModel演示");
  3. //创建一维数组,存储标题
  4. Object[] titles = {"姓名","年龄","性别"};
  5. //创建二维数组,存储数据
  6. Object[][] data = {
  7. {"李清照",29,"女"},
  8. {"苏格拉底",56,"男"},
  9. {"李白",35,"男"},
  10. {"弄玉",18,"女"},
  11. {"虎头",2,"男"}
  12. };
  13. private Vector titlesV = new Vector();//存储标题
  14. private Vector<Vector> dataV = new Vector<>();//存储数据
  15. public void init(){
  16. //组装视图
  17. for (int i = 0; i < titles.length; i++) {
  18. titlesV.add(titles[i]);
  19. }
  20. for (int i = 0; i < data.length; i++) {
  21. Vector t = new Vector<>();
  22. for (int j = 0; j < data[i].length; j++) {
  23. t.add(data[i][j]);
  24. }
  25. dataV.add(t);
  26. }
  27. //通过DefaultTableModel创建JTable
  28. DefaultTableModel model = new DefaultTableModel(dataV,titlesV);
  29. JTable jTable = new JTable(model);
  30. //创建按钮
  31. JButton addRow = new JButton("添加一行");
  32. JButton addColum = new JButton("添加一列");
  33. JButton deleteRow = new JButton("删除一行");
  34. addRow.addActionListener(new ActionListener() {
  35. @Override
  36. public void actionPerformed(ActionEvent e) {
  37. //需要给表格添加一行
  38. model.addRow(new Object[]{"胡歌",30,"男"});
  39. }
  40. });
  41. deleteRow.addActionListener(new ActionListener() {
  42. @Override
  43. public void actionPerformed(ActionEvent e) {
  44. int selectedRow = jTable.getSelectedRow();
  45. model.removeRow(selectedRow);
  46. }
  47. });
  48. addColum.addActionListener(new ActionListener() {
  49. @Override
  50. public void actionPerformed(ActionEvent e) {
  51. model.addColumn("职业");
  52. }
  53. });
  54. JPanel panel = new JPanel();
  55. panel.add(addRow);
  56. panel.add(addColum);
  57. panel.add(deleteRow);
  58. jf.add(panel, BorderLayout.SOUTH);
  59. jf.add(new JScrollPane(jTable));
  60. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  61. jf.pack();
  62. jf.setVisible(true);
  63. }
  64. public static void main(String[] args) {
  65. new DefaultTableModelTest().init();
  66. }
  67. }

 八、Swing树

1、创建树

  1. public class SimpleJTree {
  2. JFrame jf = new JFrame("简单树");
  3. public void init(){
  4. //创建DefaultMutableTreeNode对象代表结点
  5. DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
  6. DefaultMutableTreeNode guangDong = new DefaultMutableTreeNode("广东");
  7. DefaultMutableTreeNode guangXi = new DefaultMutableTreeNode("广西");
  8. DefaultMutableTreeNode foShan = new DefaultMutableTreeNode("佛山");
  9. DefaultMutableTreeNode shanTou = new DefaultMutableTreeNode("汕头");
  10. DefaultMutableTreeNode guiLin = new DefaultMutableTreeNode("桂林");
  11. DefaultMutableTreeNode nanNing = new DefaultMutableTreeNode("南宁");
  12. //组装结点之间的关系
  13. root.add(guangDong);
  14. root.add(guangXi);
  15. guangDong.add(foShan);
  16. guangDong.add(shanTou);
  17. guangXi.add(guiLin);
  18. guangXi.add(nanNing);
  19. //创建JTree对象
  20. JTree tree = new JTree(root);
  21. //把JTree放入到窗口中进行展示
  22. jf.add(tree);
  23. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  24. jf.pack();
  25. jf.setVisible(true);
  26. }
  27. public static void main(String[] args) {
  28. new SimpleJTree().init();
  29. }
  30. }

2、编辑树

编辑树节点

  1. public class EditTree {
  2. JFrame jf = new JFrame("可编辑结点的树");
  3. //定义几个初始结点
  4. DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
  5. DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
  6. DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
  7. DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
  8. DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
  9. DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
  10. DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
  11. //定义按钮,完成操作
  12. JButton addSiblingBtn = new JButton("添加兄弟结点");
  13. JButton addChildBtn = new JButton("添加子结点");
  14. JButton deleteBtn = new JButton("删除结点");
  15. JButton editBtn = new JButton("编辑当前结点");
  16. public void init() {
  17. //通过add()方法建立父子层级关系
  18. guangdong.add(foshan);
  19. guangdong.add(shantou);
  20. guangxi.add(guilin);
  21. guangxi.add(nanning);
  22. root.add(guangdong);
  23. root.add(guangxi);
  24. JTree tree = new JTree(root);
  25. //完成树的结点编辑的代码
  26. tree.setEditable(true);
  27. DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
  28. //处理添加
  29. addSiblingBtn.addActionListener(new ActionListener() {
  30. @Override
  31. public void actionPerformed(ActionEvent e) {
  32. //添加兄弟结点逻辑
  33. //1.获取当前选中的结点
  34. DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
  35. if (selectedNode == null) {
  36. return;
  37. }
  38. //2.获取当前结点的父结点
  39. DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode.getParent();
  40. if (parentNode == null) {
  41. return;
  42. }
  43. //3.创建新结点
  44. DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
  45. //4.把新结点通过父结点进行添加
  46. int index = parentNode.getIndex(selectedNode);
  47. model.insertNodeInto(newNode, parentNode, index);
  48. //5.显示新结点
  49. TreeNode[] pathToRoot = model.getPathToRoot(newNode);
  50. TreePath treePath = new TreePath(pathToRoot);
  51. tree.scrollPathToVisible(treePath);
  52. //6.重绘tree
  53. tree.updateUI();
  54. }
  55. });
  56. addChildBtn.addActionListener(new ActionListener() {
  57. @Override
  58. public void actionPerformed(ActionEvent e) {
  59. //为选中结点添加子节点
  60. //1.获取选中结点
  61. DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
  62. if (selectedNode == null) {
  63. return;
  64. }
  65. //2.创建新结点
  66. DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
  67. //3.把新结点添加到当前结点中
  68. selectedNode.add(newNode);
  69. //4.显示新结点
  70. TreeNode[] pathToRoot = model.getPathToRoot(newNode);
  71. TreePath treePath = new TreePath(pathToRoot);
  72. tree.scrollPathToVisible(treePath);
  73. //5.重绘UI
  74. tree.updateUI();
  75. }
  76. });
  77. //处理删除
  78. deleteBtn.addActionListener(new ActionListener() {
  79. @Override
  80. public void actionPerformed(ActionEvent e) {
  81. DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
  82. if (selectedNode != null && selectedNode.getParent() != null) {
  83. model.removeNodeFromParent(selectedNode);
  84. }
  85. }
  86. });
  87. //处理编辑
  88. editBtn.addActionListener(new ActionListener() {
  89. @Override
  90. public void actionPerformed(ActionEvent e) {
  91. //获取当前选中结点的路径
  92. TreePath selectionPath = tree.getSelectionPath();
  93. //判断如果路径不为空,则设置该路径的最后一个结点可编辑
  94. if (selectionPath != null) {
  95. tree.startEditingAtPath(selectionPath);
  96. }
  97. }
  98. });
  99. jf.add(new JScrollPane(tree));
  100. JPanel panel = new JPanel();
  101. panel.add(addSiblingBtn);
  102. panel.add(addChildBtn);
  103. panel.add(deleteBtn);
  104. panel.add(editBtn);
  105. jf.add(panel, BorderLayout.SOUTH);
  106. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  107. jf.pack();
  108. jf.setVisible(true);
  109. }
  110. public static void main(String[] args) {
  111. new EditTree().init();
  112. }
  113. }

 监听节点事件

  1. public class ListenerJTree {
  2. JFrame jf = new JFrame("监听树的选择事件");
  3. JTree tree;
  4. DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
  5. DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
  6. DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
  7. DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
  8. DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
  9. DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
  10. DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
  11. JTextArea eventTxt = new JTextArea(5, 20);
  12. public void init() {
  13. //通过add()方法建立父子层级关系
  14. guangdong.add(foshan);
  15. guangdong.add(shantou);
  16. guangxi.add(guilin);
  17. guangxi.add(nanning);
  18. root.add(guangdong);
  19. root.add(guangxi);
  20. tree = new JTree(root);
  21. //TODO 设置选择模式
  22. TreeSelectionModel selectionModel = tree.getSelectionModel();
  23. selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
  24. //TODO 设置监听器
  25. tree.addTreeSelectionListener(new TreeSelectionListener() {
  26. @Override
  27. public void valueChanged(TreeSelectionEvent e) {
  28. //把当前选中结点的路径显示到文本域中
  29. TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
  30. eventTxt.append(newLeadSelectionPath.toString()+"\n");
  31. }
  32. });
  33. Box box = Box.createHorizontalBox();
  34. box.add(new JScrollPane(tree));
  35. box.add(new JScrollPane(eventTxt));
  36. jf.add(box);
  37. jf.pack();
  38. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  39. jf.setVisible(true);
  40. }
  41. public static void main(String[] args) {
  42. new ListenerJTree().init();
  43. }
  44. }

3、改变树外观

  1. public class ChangeAllCellRender {
  2. JFrame jf = new JFrame("改变所有结点外观");
  3. JTree tree;
  4. DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
  5. DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
  6. DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
  7. DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
  8. DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
  9. DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
  10. DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
  11. public void init(){
  12. //通过add()方法建立父子层级关系
  13. guangdong.add(foshan);
  14. guangdong.add(shantou);
  15. guangxi.add(guilin);
  16. guangxi.add(nanning);
  17. root.add(guangdong);
  18. root.add(guangxi);
  19. tree = new JTree(root);
  20. DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  21. //设置非选定结点的背景颜色
  22. renderer.setBackgroundNonSelectionColor(new Color(220,220,220));
  23. //设置选中结点的背景色
  24. renderer.setBackgroundSelectionColor(new Color(140,140,140));
  25. //设置选中状态下结点的边框颜色
  26. renderer.setBorderSelectionColor(Color.BLACK);
  27. //设置处于折叠状态下非叶子结点的图标
  28. renderer.setClosedIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\close.gif"));
  29. //设置结点文本的字体
  30. renderer.setFont(new Font("StSong", Font.BOLD,16));
  31. //设置叶子结点图标
  32. renderer.setLeafIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\leaf.png"));
  33. //设置处于展开状态下非叶子结点图标
  34. renderer.setOpenIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\open.gif"));
  35. //设置绘制非选中状态下结点文本颜色
  36. renderer.setTextNonSelectionColor(new Color(255,0,0));
  37. //设置选中状态下结点的文本颜色
  38. renderer.setTextSelectionColor(new Color(0,0,255));
  39. //把结点绘制器设置给树对象
  40. tree.setCellRenderer(renderer);
  41. jf.add(new JScrollPane(tree));
  42. jf.pack();
  43. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  44. jf.setVisible(true);
  45. }
  46. public static void main(String[] args) {
  47. new ChangeAllCellRender().init();
  48. }
  49. }
  1. public class ExtendsDefaultCellTreeRenderer {
  2. JFrame jf = new JFrame("根据结点类型定义图标");
  3. JTree tree;
  4. //初始化5个图标
  5. ImageIcon rootIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\root.gif");
  6. ImageIcon databaseIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\database.gif");
  7. ImageIcon tableIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\table.gif");
  8. ImageIcon columnIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\column.gif");
  9. ImageIcon indexIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\index.gif");
  10. //定义一个NodeData类,用于封装结点数据
  11. class NodeData{
  12. public ImageIcon icon;
  13. public String name;
  14. public NodeData(ImageIcon icon, String name) {
  15. this.icon = icon;
  16. this.name = name;
  17. }
  18. }
  19. //定义几个初始结点
  20. DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeData(rootIcon,"数据库导航"));
  21. DefaultMutableTreeNode salaryDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司工资数据库"));
  22. DefaultMutableTreeNode customerDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司客户数据库"));
  23. DefaultMutableTreeNode employee = new DefaultMutableTreeNode(new NodeData(tableIcon,"员工表"));
  24. DefaultMutableTreeNode attend = new DefaultMutableTreeNode(new NodeData(tableIcon,"考勤表"));
  25. DefaultMutableTreeNode concat = new DefaultMutableTreeNode(new NodeData(tableIcon,"联系方式表"));
  26. DefaultMutableTreeNode id = new DefaultMutableTreeNode(new NodeData(indexIcon,"员工ID"));
  27. DefaultMutableTreeNode name = new DefaultMutableTreeNode(new NodeData(columnIcon,"姓名"));
  28. DefaultMutableTreeNode gender = new DefaultMutableTreeNode(new NodeData(columnIcon,"性别"));
  29. public void init(){
  30. //通过结点的add方法,建立结点的父子关系
  31. root.add(salaryDb);
  32. root.add(customerDb);
  33. salaryDb.add(employee);
  34. salaryDb.add(attend);
  35. customerDb.add(concat);
  36. concat.add(id);
  37. concat.add(name);
  38. concat.add(gender);
  39. //创建树
  40. tree = new JTree(root);
  41. //TODO 通过扩展DefaultTreeCellRenderer修改外观
  42. tree.setCellRenderer(new MyRenderer());
  43. jf.add(new JScrollPane(tree));
  44. jf.pack();
  45. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  46. jf.setVisible(true);
  47. }
  48. //自定义类,继承DefaultTreeCellRenderer,完成结点的绘制
  49. private class MyRenderer extends DefaultTreeCellRenderer {
  50. //重写方法
  51. @Override
  52. public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
  53. //当前类间接的继承了JLabel这个组件类,展示一张图片和一些配套的文字
  54. //Object value这个参数,代表的就是即将要绘制的结点
  55. //获取当前结点
  56. DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
  57. //获取到当前即将绘制的结点的名称和图标
  58. NodeData nodeData = (NodeData) node.getUserObject();
  59. //通过setText方法和setIcon方法完成设置
  60. this.setText(nodeData.name);
  61. this.setIcon(nodeData.icon);
  62. return this;
  63. }
  64. }
  65. public static void main(String[] args) {
  66. new ExtendsDefaultCellTreeRenderer().init();
  67. }
  68. }
  1. public class CustomerTreeNode {
  2. JFrame jf = new JFrame("定制树的结点");
  3. JTree tree;
  4. //定义几个初始结点
  5. DefaultMutableTreeNode friends = new DefaultMutableTreeNode("我的好友");
  6. DefaultMutableTreeNode qingzhao = new DefaultMutableTreeNode("李清照");
  7. DefaultMutableTreeNode suge = new DefaultMutableTreeNode("苏格拉底");
  8. DefaultMutableTreeNode libai = new DefaultMutableTreeNode("李白");
  9. DefaultMutableTreeNode nongyu = new DefaultMutableTreeNode("弄玉");
  10. DefaultMutableTreeNode hutou = new DefaultMutableTreeNode("虎头");
  11. public void init() {
  12. //组装视图
  13. friends.add(qingzhao);
  14. friends.add(suge);
  15. friends.add(libai);
  16. friends.add(nongyu);
  17. friends.add(hutou);
  18. tree = new JTree(friends);
  19. //TODO 设置结点绘制器
  20. MyRenderer renderer = new MyRenderer();
  21. tree.setCellRenderer(renderer);
  22. jf.add(new JScrollPane(tree));
  23. jf.pack();
  24. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  25. jf.setVisible(true);
  26. }
  27. //自定义类,实现TreeCellRenderer接口,绘制组件
  28. private class MyRenderer extends JPanel implements TreeCellRenderer {
  29. private ImageIcon icon;
  30. private String name;
  31. private Color background;
  32. private Color foreground;
  33. @Override
  34. public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
  35. //给成员变量设置值
  36. this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+value.toString()+".gif");
  37. this.name = value.toString();
  38. this.background = hasFocus? new Color(144,200,225) : new Color(255,255,255);
  39. this.foreground = hasFocus? new Color(255,255,3) : new Color(0,0,0);
  40. return this;
  41. }
  42. //通过重写getPreferenceSize方法,指定当前Jpanel组件的大小
  43. @Override
  44. public Dimension getPreferredSize() {
  45. return new Dimension(80,80);
  46. }
  47. @Override
  48. public void paint(Graphics g) {
  49. //绘制组件内容
  50. int iconWidth = this.icon.getIconWidth();
  51. int iconHeight = this.icon.getIconHeight();
  52. //填充背景
  53. g.setColor(background);
  54. g.fillRect(0,0,getWidth(),getHeight());
  55. //绘制头像
  56. g.drawImage(this.icon.getImage(),getWidth()/2 - iconWidth/2,10,null);
  57. //绘制昵称
  58. g.setColor(foreground);
  59. g.setFont(new Font("StSong",Font.BOLD,18));
  60. g.drawString(this.name,getWidth()/2-this.name.length()*20/2,iconHeight+30);
  61. }
  62. }
  63. public static void main(String[] args) {
  64. new CustomerTreeNode().init();
  65. }
  66. }

九、Swing控件修饰

1、控件边框

  1. public class BorderTest {
  2. JFrame jf = new JFrame("测试边框");
  3. public void init(){
  4. //组装视图
  5. //1.JFrame的布局修改为GridLayout
  6. jf.setLayout(new GridLayout(2,4));
  7. //2.往网格中填充不同的JPanel组件,并且设置边框和内容
  8. //创建BevelBorder
  9. Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.GREEN, Color.BLUE, Color.GRAY);
  10. jf.add(getJPanelWithBorder(bevelBorder,"BevelBorder"));
  11. //创建LineBorder
  12. Border lineBorder = BorderFactory.createLineBorder(Color.ORANGE, 10);
  13. jf.add(getJPanelWithBorder(lineBorder,"LineBorder"));
  14. //创建EmptyBorder
  15. Border emptyBorder = BorderFactory.createEmptyBorder(10, 5, 20, 10);
  16. jf.add(getJPanelWithBorder(emptyBorder,"EmptyBorder"));
  17. //创建EchtedBorder
  18. Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);
  19. jf.add(getJPanelWithBorder(etchedBorder,"EtchedBorder"));
  20. //创建TitledBorder
  21. TitledBorder titledBorder = new TitledBorder(new LineBorder(Color.ORANGE,10),"测试标题",TitledBorder.LEFT,TitledBorder.BOTTOM,new Font("StSong", Font.BOLD,18),Color.BLUE);
  22. jf.add(getJPanelWithBorder(titledBorder,"TitledBorder"));
  23. //创建MatteBorder
  24. MatteBorder matteBorder = new MatteBorder(10, 5, 20, 10, Color.GREEN);
  25. jf.add(getJPanelWithBorder(matteBorder,"MatteBorder"));
  26. //创建CompoundBorder
  27. CompoundBorder compoundBorder = new CompoundBorder( new LineBorder(Color.RED, 10),titledBorder);
  28. jf.add(getJPanelWithBorder(compoundBorder,"CompoundBorder"));
  29. //3.设置窗口最佳大小、设置窗口可见,处理关闭操作
  30. jf.pack();
  31. jf.setVisible(true);
  32. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  33. }
  34. public JPanel getJPanelWithBorder(Border border,String content){
  35. JPanel jPanel = new JPanel();
  36. jPanel.add(new JLabel(content));
  37. //设置边框
  38. jPanel.setBorder(border);
  39. return jPanel;
  40. }
  41. public static void main(String[] args) {
  42. new BorderTest().init();
  43. }
  44. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/112056
推荐阅读
相关标签
  

闽ICP备14008679号