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

显示一个空白窗口

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);}
}

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() {@Overridepublic void actionPerformed(ActionEvent e) {d1.setVisible(true);}});//5.把按钮添加到frame中frame.add(b1, BorderLayout.NORTH);//设置frame最佳大小并可见frame.pack();frame.setVisible(true);}
}

3、MessageDialog

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

public class MessageDialogTest {JFrame jf = new JFrame("测试消息对话框");JTextArea jta = new JTextArea(6, 30);//声明按钮JButton btn = new JButton(new AbstractAction("弹出消息对话框") {@Overridepublic 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();}

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();}
}

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")) {@Overridepublic void actionPerformed(ActionEvent e) {jta.append("上一曲.\n");}};public void init(){//通过Action对象来创建JButtonJButton 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();}
}

5、特殊容器

JSplitPane-可调整大小的面板

public class SplitPaneTest {Book[] books = {new Book("java自学宝典",  "国内关于 Java 编程最全面的图书 \n 看得懂 , 学得会"),new Book("轻量级的JAVAEE企业应用实战", "SSM整合开发的经典图书,值的拥有"),};JFrame jf = new JFrame("测试JSplitPane");//声明程序中用到的组件JList<Book> 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() {@Overridepublic 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;
}

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<String>(new String[]{"用户一","用户二","用户三"}));tabbedPane.addTab("商品管理",new JList<String>(new String[]{"商品一","商品二","商品三"}));tabbedPane.addTab("订单管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList<String>(new String[]{"订单一","订单二","订单三","订单四"}));//完成设置tabbedPane.setEnabledAt(0,false);//禁用用户管理tabbedPane.setSelectedIndex(1);//默认商品管理//监听当前标签面板的选中情况tabbedPane.addChangeListener(new ChangeListener() {@Overridepublic 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();}
}

三、Swing布局

1、BorderLayout

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

public class BorderLayoutTest extends JFrame {  //0.继承JFramepublic 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();}
}

2、FlowLayout

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

public class FlowLayoutTest extends JFrame {  //0.继承JFramepublic 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); //设置窗体关闭的同时关闭jvmthis.setResizable(false);  //Resizable:可调整大小的,设置窗体大小不可变}public static void main(String[] args) {new FlowLayoutTest();}
}

3、GridLayout

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

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

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对象设置给Frameframe.setLayout(boxLayout);//3.往frame中添加两个按钮组件frame.add(new Button("按钮1"));frame.add(new Button("按钮2"));frame.pack();frame.setVisible(true);}
}

四、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() {@Overridepublic 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{@Overridepublic 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);//把当前窗口的布局方式修改为FlowLayoutjf.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();}
}

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);//把当前窗口的布局方式修改为FlowLayoutjf.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() {@Overridepublic void actionPerformed(ActionEvent e) {//读取线程任务对象的当前完成量,设置给进度条int current = simulaterActivity.getCurrent();bar.setValue(current);}});timer.start();//监听进度条的任务变化bar.addChangeListener(new ChangeListener() {@Overridepublic void stateChanged(ChangeEvent e) {int value = bar.getValue();if (value == simulaterActivity.getAmount()){timer.stop();}}});}@Dataprivate class SimulaterActivity implements  Runnable{//记录任务总量private int amount;//记录当前任务的完成量private volatile int current;@Overridepublic void run() {//子线程的任务  模拟耗时操作while(current<amount){try {Thread.currentThread().sleep(50);} catch (InterruptedException e) {e.printStackTrace();}current++;}}}public static void main(String[] args) {new JProgressTest2().init();}
}

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);//把当前窗口的布局方式修改为FlowLayoutjf.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() {@Overridepublic void actionPerformed(ActionEvent e) {//读取线程任务对象的当前完成量,设置给进度条int current = simulaterActivity.getCurrent();model.setValue(current);}});timer.start();//监听进度条的任务变化model.addChangeListener(new ChangeListener() {@Overridepublic void stateChanged(ChangeEvent e) {int value = model.getValue();if (value == simulaterActivity.getAmount()){timer.stop();}}});}@Dataprivate class SimulaterActivity implements  Runnable{//记录任务总量private int amount;//记录当前任务的完成量private volatile int current;@Overridepublic void run() {//子线程的任务  模拟耗时操作while(current<amount){try {Thread.currentThread().sleep(50);} catch (InterruptedException e) {e.printStackTrace();}current++;}}}public static void main(String[] args) {new JProgressTest2().init();}
}

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() {@Overridepublic 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();}//定义一个线程任务,模拟耗时操作@Dataprivate class SimulaterActivity implements Runnable{//内存可见private volatile int current = 0;private int amount;public SimulaterActivity(int amount) {this.amount = amount;}@Overridepublic void run() {//通过循环,不断的修改current的值,模拟任务完成量while(current<amount){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}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<String> bookList ;JComboBox<String> 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() {@Overridepublic void valueChanged(ListSelectionEvent e) {//获取当前选中的条目java.util.List<String> selectedValuesList = bookList.getSelectedValuesList();//把当前条目的内容设置到文本域中。}});Box bookListVBox = Box.createVerticalBox();bookListVBox.add(new JScrollPane(bookList));bookListVBox.add(layoutPanel);bookListVBox.add(selectModePanel);//组装JComboBoxVector<String> 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() {@Overridepublic 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() {@Overridepublic void actionPerformed(ActionEvent e) {bookList.setSelectionMode(selectionModel);}});}public static void main(String[] args) {new ListTest().init();}
}

2、固定值的列表

public class NumberListModel extends AbstractListModel<BigDecimal> {BigDecimal start;BigDecimal end;BigDecimal step;public NumberListModel(BigDecimal start, BigDecimal end, BigDecimal step) {this.start = start;this.end = end;this.step = step;}@Overridepublic int getSize() {int floor = (int) Math.floor(end.subtract(start).divide(step,2, RoundingMode.HALF_DOWN).doubleValue());return floor+1;}@Overridepublic 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<BigDecimal> {//当前选中条目的索引private int selectedId;public NumberComboBoxListModel(BigDecimal start, BigDecimal end, BigDecimal step) {super(start, end, step);}@Overridepublic 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();}}@Overridepublic 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<BigDecimal> jList = new JList<>(new NumberListModel(new BigDecimal(1),new BigDecimal(21),new BigDecimal(2)));JComboBox<BigDecimal> 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() {@Overridepublic void valueChanged(ListSelectionEvent e) {java.util.List<BigDecimal> selectedValuesList = jList.getSelectedValuesList();jTextField.setText("");for (BigDecimal item : selectedValuesList) {jTextField.setText(jTextField.getText()+item.toString()+",");}}});jComboBox.setMaximumRowCount(4);jComboBox.addItemListener(new ItemListener() {@Overridepublic 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();}
}

3、动态改变列表的值

public class DefaultListModelTest {JFrame jf = new JFrame("测试DefaultListModel");JTextField bookName = new JTextField(20);JButton removeBtn = new JButton("删除选中图书");JButton addBtn = new JButton("添加指定图书");//创建JListJList<String> bookList;DefaultListModel<String> model = new DefaultListModel<>();public void init(){//组装视图model.addElement("java自学宝典");model.addElement("轻量级JavaEE企业应用实战");model.addElement("Android基础教程");model.addElement("JQuery实战教程");bookList = new JList<>(model);//设置JlistbookList.setVisibleRowCount(4);//设置单选bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);jf.add(new JScrollPane(bookList));//组装底部addBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String name = bookName.getText();if (!name.trim().equals("")){//不是空字符串才添加model.addElement(name);}}});removeBtn.addActionListener(new ActionListener() {@Overridepublic 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();}}

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;@Overridepublic 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;}@Overridepublic Dimension getPreferredSize() {return new Dimension(60,80);}//绘制列表项的内容@Overridepublic 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();}
}

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<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() {@Overridepublic 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 {@Overridepublic int getRowCount() {return dataV.size();}@Overridepublic int getColumnCount() {return titlesV.size();}@Overridepublic Object getValueAt(int rowIndex, int columnIndex) {return dataV.get(rowIndex).get(columnIndex);}@Overridepublic String getColumnName(int column) {return (String) titlesV.get(column);}@Overridepublic 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<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创建JTableDefaultTableModel 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() {@Overridepublic void actionPerformed(ActionEvent e) {//需要给表格添加一行model.addRow(new Object[]{"胡歌",30,"男"});}});deleteRow.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int selectedRow = jTable.getSelectedRow();model.removeRow(selectedRow);}});addColum.addActionListener(new ActionListener() {@Overridepublic 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();}}

八、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();}
}

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() {@Overridepublic 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.重绘treetree.updateUI();}});addChildBtn.addActionListener(new ActionListener() {@Overridepublic 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.重绘UItree.updateUI();}});//处理删除deleteBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();if (selectedNode != null && selectedNode.getParent() != null) {model.removeNodeFromParent(selectedNode);}}});//处理编辑editBtn.addActionListener(new ActionListener() {@Overridepublic 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();}
}

监听节点事件

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() {@Overridepublic 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 {//重写方法@Overridepublic 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;@Overridepublic 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组件的大小@Overridepublic Dimension getPreferredSize() {return new Dimension(80,80);}@Overridepublic 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的布局修改为GridLayoutjf.setLayout(new GridLayout(2,4));//2.往网格中填充不同的JPanel组件,并且设置边框和内容//创建BevelBorderBorder bevelBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.GREEN, Color.BLUE, Color.GRAY);jf.add(getJPanelWithBorder(bevelBorder,"BevelBorder"));//创建LineBorderBorder lineBorder = BorderFactory.createLineBorder(Color.ORANGE, 10);jf.add(getJPanelWithBorder(lineBorder,"LineBorder"));//创建EmptyBorderBorder emptyBorder = BorderFactory.createEmptyBorder(10, 5, 20, 10);jf.add(getJPanelWithBorder(emptyBorder,"EmptyBorder"));//创建EchtedBorderBorder etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);jf.add(getJPanelWithBorder(etchedBorder,"EtchedBorder"));//创建TitledBorderTitledBorder 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"));//创建MatteBorderMatteBorder matteBorder = new MatteBorder(10, 5, 20, 10, Color.GREEN);jf.add(getJPanelWithBorder(matteBorder,"MatteBorder"));//创建CompoundBorderCompoundBorder 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图形化设计相关推荐

  1. JAVA Swing 图形化界面编程

    JAVA Swing 图形化界面编程 目录 1.组件 1.1 基本组件 1.2. 组件边框 1.3. JToolBar 工具条 1.4 JColorChooser 颜色选择器 1.5 JFileCho ...

  2. java基础学习——Swing图形化用户界面编程

    GUI概述 早期计算机系统中,电脑向用户提供的是单调.枯燥.纯字符状态的"命令行界面(CLI)".就是到现在,我们还可以依稀看到它们的身影:在Windows中开个DOS窗口,就可看 ...

  3. Java编程之图形化设计求任意输入数的阶乘

    问题描述:下面是我使用Java编程所实现的图形化的能求输入的任意数的阶乘. 程序源码: import java.awt.*; import java.awt.event.*; import javax ...

  4. Java 网络编程之swing图形化QQ聊天室

    Java写聊天室就要用到网络编程,TCP/UDP都可以,这里用UDP实现. 话不多说,先上图看效果 首先Java通过两个类实现UDP协议顶层的数据报:DatagramPacket对象是数据容器,Dat ...

  5. 汉字创意 字体图形化设计

    设计前的思考 文字是一种记录与传达语言的符号,是人类文明进步的重要标志.随着图形化时代的来临,文字与图形的关系在设计领域起着举足轻重的作用.当练习字体设计时,找有代表性的字体来做,练习有代表性的字体不 ...

  6. vue 图形化设计工具_Vue: Vue-CLI3.0 创建项目

    真实的开始需要的:开发服务器: 需要http/https协议访问 BaBel: es6转es5,兼容2015年6月之前的浏览器 postcss less sass: 开发高效 esLint: 协作开发 ...

  7. Java图形化设计 简易画板

    简易画板 UI界面设置 监听器类 图形保存 github源代码下载: 画图工具源代码. UI界面设置 根据我们想实现的画板要求,可以分步骤进行解决.在创建画板之前,首先创建窗体框架,利用java提供的 ...

  8. Java图形化界面设计——容器(JFrame)

    Java图形化界面设计--容器(JFrame) 程序是为了方便用户使用的,因此实现图形化界面的程序编写是所有编程语言发展的必然趋势,在命令提示符下运行的程序可以让我们了解java程序的基本知识体系结构 ...

  9. 基于Qt的ui图形化界面进行的界面设计

    qt初学者往往会发现这样的一个问题--无论是我买的相关的书,还是网上博客的内容,基本全都是利用纯代码的形式来进行界面设计的.而初学者对各种控件的代码实现并不熟悉,往往在这里耗费大量时间.故本篇文章介绍 ...

最新文章

  1. 产品经理多任务并行处理,如何管理提效?
  2. php删除记录前的判断弹窗,thinkPHP删除前弹出确认框的简单实现方法
  3. Docker端口映射错误的解决方法
  4. 使用Docker搭建Elasticsearch6.8.6集群及设置集群用户密码
  5. 美研申请,你应该知道的那些事?
  6. python nose测试框架全面介绍十---用例的跳过
  7. python包的管理(添加的3种方式 删除包)
  8. 看DLI服务4核心如何提升云服务自动化运维
  9. 23_python基础—模块和包
  10. 看门狗(APB watchdog)简介,各个寄存器简介,把看门狗挂到APB总线上,看门狗的验证测试(1)
  11. PHP函数spl_autoload_register()用法和__autoload()介绍(转)
  12. 超越存储,历久弥新!新华三发布入门级存储产品
  13. [CSS]打败 IE 的葵花宝典:CSS Bug Table
  14. 环形电流计算公式_圆环电流的电流密度
  15. 【JAVA程序设计】(C00005)基于springboot的进存销管理系统
  16. 微软默认 密钥管理服务器,加密和密钥管理概述 - Microsoft Service Assurance | Microsoft Docs...
  17. 2021年总结:厚积薄发,突破自我
  18. HTML基础之创建简单表格
  19. 如何成为一名全栈开发人员----转载
  20. 海马体拍照照片赚钱掘金项目

热门文章

  1. 潭州教育html视屏,潭州教育HTML多列布局CSS实现
  2. Java面试官最爱问的垃圾回收机制,mysqlssl连接
  3. 【Carsim学习】Carsim2019安装教程
  4. 何为非侵入式负荷识别-特征提取
  5. 【自动化】DCS PLC区别;PLC常见的六大应用
  6. Springboot 自定义模板导出Excel文件
  7. Python1--糗事百科笑话爬取
  8. 理解ASAN的shadow memory和读懂报错信息
  9. windows中文件夹有小锁是什么意思,文件夹小锁怎么去掉
  10. 核心代码是整个程序吗_你认为3D建模是像程序员一样敲代码吗?你太out了