Java-GUI提供了两套设计AWT和Swing,其中Swing是基于AWT开发的,两者在功能上基本一样。发展至今天,最大的区别就是在显示样式上,AWT会匹配当前操作系统的UI而在不同平台下表现出不同的样式,但Swing不会。所以建议插件开发时采用Swing-GUI。
Idea的图形界面是基于Swing开发的,官方文档也有推荐,详细的UI控件可查看官方文档IntelliJ Platform UI Guidelines ,虽说Swing内容比较多,但相对来讲比较简单。 所有GUI开发基本都遵循如下关系来设计:
idea控件开发只要了解这一张图即可,开发时参考此图再查相应的API文档。不需要太高深的技术(Canvas开发除外,那个涉及很多图形方面的专业知识。
本章会从容器、布局、复杂控件几个方式给出一些示例。
显示一个空白窗口
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);
}
}
public class DialogTest {
public static void main(String[] args) {
JFrame frame = new JFrame("这里测试Dialog");
JDialog d1 = new JDialog(frame, "模式对话框", true);
//2.通过setBounds方法设置Dialog的位置以及大小
d1.setBounds(20,30,300,200);
//3.创建两个按钮
JButton b1 = new JButton("打开模式对话框");
//4.给这两个按钮添加点击后的行为
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
d1.setVisible(true);
}
});
//5.把按钮添加到frame中
frame.add(b1, BorderLayout.NORTH);
//设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
简化版本的弹出窗口确定框,注意这些Dialog全是模态化的。
public class MessageDialogTest {
JFrame jf = new JFrame("测试消息对话框");
JTextArea jta = new JTextArea(6, 30);
//声明按钮
JButton btn = new JButton(new AbstractAction("弹出消息对话框") {
@Override
public void actionPerformed(ActionEvent e) {
//弹出一个消息对话框,并且显示 文本域中输入的内容
String text = jta.getText();
//参数:int messageType 指定消息对话框的类型: 错误消息,警告消息,问题消息...
//JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.ERROR_MESSAGE);
//JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.INFORMATION_MESSAGE);
//JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE);
//JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.QUESTION_MESSAGE);
//JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.PLAIN_MESSAGE);
JOptionPane.showMessageDialog(jf,text,"消息对话框",JOptionPane.WARNING_MESSAGE,new ImageIcon("E:\\GUISwing\\img\\component\\female.png"));
}
});
public void init(){
//组装视图
jf.add(jta);
jf.add(btn, BorderLayout.SOUTH);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new MessageDialogTest().init();
}
菜单分为两种:一种是嵌入到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();
}
}
这个工具栏是可以拖动的。
public class JToolBarTest {
JFrame jf = new JFrame("测试工具条");
JTextArea jta = new JTextArea(6,35);
//声明工具条相关内容
JToolBar jToolBar = new JToolBar("播放工具条",SwingConstants.HORIZONTAL);
//创建3个Action对象
//传递的参数,name和icon,最终在添加到工具条中时,会被拿出来作为按钮的名称和图标
Action pre = new AbstractAction("上一曲",new ImageIcon("E:\\GUISwing\\img\\component\\上一曲16.png")) {
@Override
public void actionPerformed(ActionEvent e) {
jta.append("上一曲.\n");
}
};
public void init(){
//通过Action对象来创建JButton
JButton preBtn = new JButton(pre);
jToolBar.add(preBtn);
jToolBar.addSeparator();
//让工具条可以拖动
jToolBar.setFloatable(true);
jf.add(jToolBar, BorderLayout.NORTH);
//把一个组件设置到JScrollPane中,那么该组件就支持滚动条了
JScrollPane jScrollPane = new JScrollPane(jta);
jf.add(jScrollPane);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new JToolBarTest().init();
}
}
public class SplitPaneTest {
Book[] books = {new Book("java自学宝典", "国内关于 Java 编程最全面的图书 \n 看得懂 , 学得会"),
new Book("轻量级的JAVAEE企业应用实战", "SSM整合开发的经典图书,值的拥有"),
};
JFrame jf = new JFrame("测试JSplitPane");
//声明程序中用到的组件
JList bookJList = new JList<>(books);
JLabel bookCover = new JLabel();
JTextArea bookDesc = new JTextArea();
public void init(){
//组装视图
//设定组件大小
bookJList.setPreferredSize(new Dimension(150,400));
bookCover.setPreferredSize(new Dimension(220,270));
bookDesc.setPreferredSize(new Dimension(220,130));
//为jList设置条目选中监听器
bookJList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
//获取当前选中的是哪个条目
Book book = bookJList.getSelectedValue();
//把书籍的图片用bookCover展示
bookDesc.setText(book.getDesc());
}
});
//组装左边区域
JSplitPane left = new JSplitPane(JSplitPane.VERTICAL_SPLIT,bookCover,new JScrollPane(bookDesc));
left.setOneTouchExpandable(true);//一触即展
//组装整体
JSplitPane hole = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,left,bookJList);
//支持连续布局
hole.setContinuousLayout(true);
hole.setDividerSize(10);
jf.add(hole);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new SplitPaneTest().init();
}
}
@Data
@AllArgsConstructor
class Book {
private String name;
private String desc;
}
public class JTabbedPaneTest {
JFrame jf = new JFrame("测试JTabbedPane");
JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.LEFT,JTabbedPane.SCROLL_TAB_LAYOUT);
public void init(){
//添加标签
tabbedPane.addTab("用户管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList(new String[]{"用户一","用户二","用户三"}));
tabbedPane.addTab("商品管理",new JList(new String[]{"商品一","商品二","商品三"}));
tabbedPane.addTab("订单管理",new ImageIcon("swing\\img\\container\\open.gif"),new JList(new String[]{"订单一","订单二","订单三","订单四"}));
//完成设置
tabbedPane.setEnabledAt(0,false);//禁用用户管理
tabbedPane.setSelectedIndex(1);//默认商品管理
//监听当前标签面板的选中情况
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int selectedIndex = tabbedPane.getSelectedIndex();
JOptionPane.showMessageDialog(jf,"当前选中了第 "+(selectedIndex+1)+"个标签");
}
});
jf.add(tabbedPane);
jf.setBounds(400,400,400,400);
jf.setResizable(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
public static void main(String[] args) {
new JTabbedPaneTest().init();
}
}
其中边上的4个方向可以不设置,这样就可以实现列和行布局模式了。
public class BorderLayoutTest extends JFrame { //0.继承JFrame
public BorderLayoutTest() {
//1. 创建组件
JButton jButton = new JButton("中间");
JButton jButton2 = new JButton("北间");
JButton jButton3 = new JButton("西间");
JButton jButton4 = new JButton("东间");
JButton jButton5 = new JButton("南间");
//2. 添加各个组件
this.add(jButton, BorderLayout.CENTER); //布局的中间
this.add(jButton2, BorderLayout.NORTH); //布局的北边
this.add(jButton3, BorderLayout.WEST); //布局的西边
this.add(jButton4, BorderLayout.EAST); //布局的东边
this.add(jButton5, BorderLayout.SOUTH); //布局的南边
//3. 设置窗体属性
this.setTitle("演示边界布局管理器");
this.setSize(300, 200);
this.setLocation(200, 200);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new BorderLayoutTest();
}
}
一种流布局模式,控件会按添加顺序依次摆放,如果超过容器大小会自动换行。
public class FlowLayoutTest extends JFrame { //0.继承JFrame
public FlowLayoutTest() {
//1. 创建组件
JButton jButton1 = new JButton("A");
JButton jButton2 = new JButton("B");
JButton jButton3 = new JButton("C");
JButton jButton4 = new JButton("D");
JButton jButton5 = new JButton("E");
//2. 添加各个组件
this.add(jButton1);
this.add(jButton2);
this.add(jButton3);
this.add(jButton4);
this.add(jButton5);
//设置流布局
this.setLayout(new FlowLayout(FlowLayout.LEFT));
//4. 设置窗体属性
this.setTitle("演示流布局管理器"); //设置标题
this.setSize(300, 200); //设置
this.setLocation(200, 200); //设置窗体出现的位置
this.setVisible(true); //设置窗体可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体关闭的同时关闭jvm
this.setResizable(false); //Resizable:可调整大小的,设置窗体大小不可变
}
public static void main(String[] args) {
new FlowLayoutTest();
}
}
网格模式,适合比较复杂的布局方式。
public class GridLayoutTest extends JFrame {
//定义组件
int size = 9;
//定义按钮数组
JButton jButton[] = new JButton[size];
//构造函数
public GridLayoutTest() {
//创建组件
for(int i = 0; i
可指定BoxLayout参数控制容器内的元素是按行还是按列排列。
public class BoxLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BoxLayout");
//1.基于frame容器,创建一个BoxLayout对象,并且,该对象存放组件是垂直存放
//BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);//水平排列
//2.把BoxLayout对象设置给Frame
frame.setLayout(boxLayout);
//3.往frame中添加两个按钮组件
frame.add(new Button("按钮1"));
frame.add(new Button("按钮2"));
frame.pack();
frame.setVisible(true);
}
}
事件的类型比较多,一个简单的示例如下,有两种方式绑定事件。允许一个事件源绑定多个事件,也允许绑定多个同类型的事件。在内部会形成一个事件链依次执行。
public class EventDemo1 {
Frame frame = new Frame("这里测试事件处理");
TextField tf = new TextField(30);
//事件源
Button ok = new Button("确定");
public void init(){//组装视图
//注册监听
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("ok按钮被点击了...");
tf.setText("Hello World");
}
});
//把tf和ok放入到Frame中
frame.add(tf, BorderLayout.NORTH);
frame.add(ok);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new EventDemo1().init();
}
}
public class EventDemo1 {
Frame frame = new Frame("这里测试事件处理");
TextField tf = new TextField(30);
Button ok = new Button("确定");
public void init(){//组装视图
//监听器,这种写法适合公共监听器,后面多个摈控件通过addActionListener()来共享
MyListener myListener = new MyListener();
ok.addActionListener(myListener);
//把tf和ok放入到Frame中
frame.add(tf, BorderLayout.NORTH);
frame.add(ok);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new EventDemo1().init();
}
}
class MyListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("ok按钮被点击了...");
}
}
主要使用JProgressBar、ProgressMonitor、BoundedRangeModel实现进度条。
这种耗时操作放在主线程的话,会导致执行耗时操作时,用户无法再进行任何操作,因此最好将耗时操作放入子线程中。
public class JProgressTest {
JFrame jf = new JFrame("测试进度条");
//创建进度条
JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
public void init(){
//组装视图
Box vBox = Box.createVerticalBox();
//设置进度条的属性
bar.setStringPainted(true);
bar.setBorderPainted(true);
//把当前窗口的布局方式修改为FlowLayout
jf.setLayout(new FlowLayout());
jf.add(vBox);
jf.add(bar);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
//通过循环模拟修改进度条的进度
for (int i = 0; i <= 100; i++) {
//修改已经完成的工作量,也就是百分比
bar.setValue(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new JProgressTest().init();
}
}
public class JProgressTest2 {
JFrame jf = new JFrame("测试进度条");
//创建进度条
JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
public void init(){
//组装视图
Box vBox = Box.createVerticalBox();
//设置进度条的属性
bar.setStringPainted(true);
bar.setBorderPainted(true);
//把当前窗口的布局方式修改为FlowLayout
jf.setLayout(new FlowLayout());
jf.add(vBox);
jf.add(bar);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
//开启子线程,模拟耗时操作
SimulaterActivity simulaterActivity = new SimulaterActivity();
simulaterActivity.setAmount(bar.getMaximum());
new Thread(simulaterActivity).start();
//设置一个定时任务
Timer timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//读取线程任务对象的当前完成量,设置给进度条
int current = simulaterActivity.getCurrent();
bar.setValue(current);
}
});
timer.start();
//监听进度条的任务变化
bar.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int value = bar.getValue();
if (value == simulaterActivity.getAmount()){
timer.stop();
}
}
});
}
@Data
private class SimulaterActivity implements Runnable{
//记录任务总量
private int amount;
//记录当前任务的完成量
private volatile int current;
@Override
public void run() {
//子线程的任务 模拟耗时操作
while(current
Swing组件大都将外观显示和内部数据分离,JProgressBar也不例外,JProgressBar组件有一个内置的用于保存其状态数据的Model对象,这个对象由BoundedRangeModel对象表示,程序调用JProgressBar对象的方法完成进度百分比的设置,监听进度条的数据变化,其实都是通过
它内置的BoundedRangeModel对象完成的。下面的代码是对之前代码的改进,通过BoundedRangeModel完成数据的设置,获取和监听。
public class JProgressTest3 {
JFrame jf = new JFrame("测试进度条");
//创建进度条
JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
//获取处进度条内置的数据模型对象
BoundedRangeModel model = bar.getModel();
public void init(){
//组装视图
Box vBox = Box.createVerticalBox();
//设置进度条的属性
bar.setStringPainted(true);
bar.setBorderPainted(true);
//把当前窗口的布局方式修改为FlowLayout
jf.setLayout(new FlowLayout());
jf.add(vBox);
jf.add(bar);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
//开启子线程,模拟耗时操作
SimulaterActivity simulaterActivity = new SimulaterActivity();
simulaterActivity.setAmount(bar.getMaximum());
new Thread(simulaterActivity).start();
//设置一个定时任务
Timer timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//读取线程任务对象的当前完成量,设置给进度条
int current = simulaterActivity.getCurrent();
model.setValue(current);
}
});
timer.start();
//监听进度条的任务变化
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int value = model.getValue();
if (value == simulaterActivity.getAmount()){
timer.stop();
}
}
});
}
@Data
private class SimulaterActivity implements Runnable{
//记录任务总量
private int amount;
//记录当前任务的完成量
private volatile int current;
@Override
public void run() {
//子线程的任务 模拟耗时操作
while(current
使用ProgressMonitor创建的对话框里包含的进度条是非常固定的,程序甚至不能设置该进度条是否包含边框(总是包含边框),不能设置进度不确定,不能改变进度条的方向(总是水平方向)。
public class ProgressMonitorTest {
Timer timer;
public void init(){
//创建进度对话框
ProgressMonitor monitor = new ProgressMonitor(null,"等待任务完成","已完成",0,100);
SimulaterActivity simulaterActivity = new SimulaterActivity(100);
new Thread(simulaterActivity).start();
//设置定时任务
timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//读取当前任务量,修改进度
int current = simulaterActivity.getCurrent();
monitor.setProgress(current);
//判断用户是否点击了取消按钮,停止定时任务,关闭对话框,退出程序
if (monitor.isCanceled()){
timer.stop();
monitor.close();
System.exit(0);
}
}
});
timer.start();
}
public static void main(String[] args) {
new ProgressMonitorTest().init();
}
//定义一个线程任务,模拟耗时操作
@Data
private class SimulaterActivity implements Runnable{
//内存可见
private volatile int current = 0;
private int amount;
public SimulaterActivity(int amount) {
this.amount = amount;
}
@Override
public void run() {
//通过循环,不断的修改current的值,模拟任务完成量
while(current
public class ListTest {
JFrame jf = new JFrame("列表框测试");
String[] books = {"java自学宝典","轻量级javaEE企业应用实战","Android基础教程","jQuery实战教程","SpringBoot企业级开发"};
//定义 布局选择按钮 所在的面板
JPanel layoutPanel = new JPanel();
ButtonGroup layoutGroup = new ButtonGroup();
//定义 选择模式按钮 所在面板
JPanel selectModePanel = new JPanel();
ButtonGroup selectModeGroup = new ButtonGroup();
//用一个字符串数组来创建一个JList对象
JList bookList ;
JComboBox bookSelector;
public void init(){
//组装视图
//组装Jlist相关内容
bookList = new JList<>(books);
addBtn2LayoutPanel("纵向滚动",JList.VERTICAL);
addBtn2LayoutPanel("纵向换行",JList.VERTICAL_WRAP);
addBtn2LayoutPanel("横向换行",JList.HORIZONTAL_WRAP);
addBtn2SelectModelPanel("无限制",ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
addBtn2SelectModelPanel("单选",ListSelectionModel.SINGLE_SELECTION);
addBtn2SelectModelPanel("单范围",ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//对JList做设置
bookList.setVisibleRowCount(3);
bookList.setSelectionInterval(2,4);
//处理条目选中事件
bookList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
//获取当前选中的条目
java.util.List selectedValuesList = bookList.getSelectedValuesList();
//把当前条目的内容设置到文本域中。
}
});
Box bookListVBox = Box.createVerticalBox();
bookListVBox.add(new JScrollPane(bookList));
bookListVBox.add(layoutPanel);
bookListVBox.add(selectModePanel);
//组装JComboBox
Vector vector = new Vector<>();
for (int i = 0; i < books.length; i++) {
vector.add(books[i]);
}
bookSelector = new JComboBox<>(vector);
bookSelector.setEditable(true);
bookSelector.setMaximumRowCount(4);
//组装顶部的左右两部分
Box topBox = Box.createHorizontalBox();
topBox.add(bookListVBox);
JPanel bookSelectPanel = new JPanel();
bookSelectPanel.add(bookSelector);
topBox.add(bookSelectPanel);
//组装底部
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
//组装整体
Box holeBox = Box.createVerticalBox();
holeBox.add(topBox);
holeBox.add(bottomPanel);
jf.add(holeBox);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
//封装方法,往layoutPanel中添加单选按钮
public void addBtn2LayoutPanel(String name,int layoutType){
//设置标题边框
layoutPanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选项布局"));
//创建单选按钮
JRadioButton button = new JRadioButton(name);
layoutPanel.add(button);
//让第一个按钮默认选中
if (layoutGroup.getButtonCount()==0){
button.setSelected(true);
}
layoutGroup.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
bookList.setLayoutOrientation(layoutType);
}
});
}
//封装方法,给selectModelPanel添加按钮
public void addBtn2SelectModelPanel(String name,int selectionModel){
//设置标题边框
selectModePanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选择模式"));
//创建单选按钮
JRadioButton button = new JRadioButton(name);
selectModePanel.add(button);
//让第一个按钮默认选中
if (selectModeGroup.getButtonCount()==0){
button.setSelected(true);
}
selectModeGroup.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
bookList.setSelectionMode(selectionModel);
}
});
}
public static void main(String[] args) {
new ListTest().init();
}
}
public class NumberListModel extends AbstractListModel {
BigDecimal start;
BigDecimal end;
BigDecimal step;
public NumberListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
this.start = start;
this.end = end;
this.step = step;
}
@Override
public int getSize() {
int floor = (int) Math.floor(end.subtract(start).divide(step,2, RoundingMode.HALF_DOWN).doubleValue());
return floor+1;
}
@Override
public BigDecimal getElementAt(int index) {
BigDecimal ele = new BigDecimal(index).multiply(step).add(start).setScale(2, RoundingMode.HALF_DOWN);
return ele;
}
}
public class NumberComboBoxListModel extends NumberListModel implements ComboBoxModel {
//当前选中条目的索引
private int selectedId;
public NumberComboBoxListModel(BigDecimal start, BigDecimal end, BigDecimal step) {
super(start, end, step);
}
@Override
public void setSelectedItem(Object anItem) {
if (anItem instanceof BigDecimal){
BigDecimal curr = (BigDecimal) anItem;
selectedId = curr.subtract(super.start).divide(super.step,2, RoundingMode.HALF_DOWN).intValue();
}
}
@Override
public Object getSelectedItem() {
BigDecimal item = new BigDecimal(selectedId).multiply(super.step).add(super.start).setScale(1, RoundingMode.HALF_DOWN);
return item;
}
}
public class ListModelTest {
JFrame jf = new JFrame("测试ListModel");
JList jList = new JList<>(new NumberListModel(new BigDecimal(1),new BigDecimal(21),new BigDecimal(2)));
JComboBox jComboBox = new JComboBox<>(new NumberComboBoxListModel(new BigDecimal(0.1),new BigDecimal(1.2),new BigDecimal(0.1)));
JLabel label = new JLabel("您选择的值是:");
JTextField jTextField = new JTextField(15);
public void init(){
//组装视图
//组装顶部
jList.setVisibleRowCount(4);
jList.setSelectionInterval(2,4);
jList.setFixedCellWidth(90);
jList.setFixedCellHeight(30);
jList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
java.util.List selectedValuesList = jList.getSelectedValuesList();
jTextField.setText("");
for (BigDecimal item : selectedValuesList) {
jTextField.setText(jTextField.getText()+item.toString()+",");
}
}
});
jComboBox.setMaximumRowCount(4);
jComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
Object selectedItem = jComboBox.getSelectedItem();
jTextField.setText(selectedItem.toString());
}
});
Box hBox = Box.createHorizontalBox();
hBox.add(new JScrollPane(jList));
JPanel tempPanel = new JPanel();
tempPanel.add(jComboBox);
hBox.add(tempPanel);
jf.add(hBox);
//组装底部
JPanel bottomPanel = new JPanel();
bottomPanel.add(label);
bottomPanel.add(jTextField);
jf.add(bottomPanel, BorderLayout.SOUTH);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new ListModelTest().init();
}
}
public class DefaultListModelTest {
JFrame jf = new JFrame("测试DefaultListModel");
JTextField bookName = new JTextField(20);
JButton removeBtn = new JButton("删除选中图书");
JButton addBtn = new JButton("添加指定图书");
//创建JList
JList bookList;
DefaultListModel model = new DefaultListModel<>();
public void init(){
//组装视图
model.addElement("java自学宝典");
model.addElement("轻量级JavaEE企业应用实战");
model.addElement("Android基础教程");
model.addElement("JQuery实战教程");
bookList = new JList<>(model);
//设置Jlist
bookList.setVisibleRowCount(4);
//设置单选
bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jf.add(new JScrollPane(bookList));
//组装底部
addBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String name = bookName.getText();
if (!name.trim().equals("")){//不是空字符串才添加
model.addElement(name);
}
}
});
removeBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedIndex = bookList.getSelectedIndex();
if (selectedIndex>=0){
model.remove(selectedIndex);
}
}
});
JPanel bottomPanel = new JPanel();
bottomPanel.add(bookName);
bottomPanel.add(addBtn);
bottomPanel.add(removeBtn);
jf.add(bottomPanel, BorderLayout.SOUTH);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new DefaultListModelTest().init();
}
}
public class ListCellRendererTest {
private JFrame mainWin = new JFrame("好友列表");
private String[] friends = {
"李清照",
"苏格拉底",
"李白",
"弄玉",
"虎头"
};
//定义一个JList对象
JList friendsList = new JList(friends);
public void init() {
//组装视图
//给JList设置ListCellRenderer对象,指定列表项绘制的组件
friendsList.setCellRenderer(new MyRenderer());
mainWin.add(friendsList);
mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWin.pack();
mainWin.setVisible(true);
}
private class MyRenderer extends JPanel implements ListCellRenderer{
private String name;
private ImageIcon icon;
//记录背景色
private Color backGround;
//记录前景色:文字的颜色
private Color forceGround;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
//重置成员变量的值
this.name = value.toString();
this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+name+".gif");
this.backGround = isSelected? list.getSelectionBackground() : list.getBackground();
this.forceGround = isSelected? list.getSelectionForeground() : list.getForeground();
return this;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(60,80);
}
//绘制列表项的内容
@Override
public void paint(Graphics g) {
int imageWidth = icon.getImage().getWidth(null);
int imageHeight = icon.getImage().getHeight(null);
//填充背景矩形
g.setColor(backGround);
g.fillRect(0,0,getWidth(),getHeight());
//绘制头像
g.drawImage(icon.getImage(),this.getWidth()/2 -imageWidth/2 ,10,null);
//绘制昵称
g.setColor(forceGround);
g.setFont(new Font("StSong",Font.BOLD,18));
g.drawString(this.name,this.getWidth()/2 - this.name.length()*20/2,imageHeight+30);
}
}
public static void main(String[] args) {
new ListCellRendererTest().init();
}
}
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();
}
}
public class TableModelTest {
JFrame jf = new JFrame("TableModel演示");
//创建一维数组,存储标题
Object[] titles = {"姓名","年龄","性别"};
//创建二维数组,存储数据
Object[][] data = {
{"李清照",29,"女"},
{"苏格拉底",56,"男"},
{"李白",35,"男"},
{"弄玉",18,"女"},
{"虎头",2,"男"}
};
private Vector titlesV = new Vector();//存储标题
private Vector dataV = new Vector<>();//存储数据
public void init(){
//组装视图
for (int i = 0; i < titles.length; i++) {
titlesV.add(titles[i]);
}
for (int i = 0; i < data.length; i++) {
Vector t = new Vector<>();
for (int j = 0; j < data[i].length; j++) {
t.add(data[i][j]);
}
dataV.add(t);
}
MyTableModel myTableModel = new MyTableModel();
//JTable jTable = new JTable(dataV,titlesV);
JTable jTable = new JTable(myTableModel);
jf.add(new JScrollPane(jTable));
JButton btn = new JButton("获取选中行数据");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedColumn = jTable.getSelectedColumn();
int selectedRow = jTable.getSelectedRow();
System.out.println("当前选中行的索引:"+selectedRow);
System.out.println("当前选中列的索引:"+selectedColumn);
Object value = myTableModel.getValueAt(selectedRow, selectedColumn);
System.out.println("当前选中行第一个单元格的内容为:"+value);
}
});
jf.add(btn, BorderLayout.SOUTH);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
private class MyTableModel extends AbstractTableModel {
@Override
public int getRowCount() {
return dataV.size();
}
@Override
public int getColumnCount() {
return titlesV.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return dataV.get(rowIndex).get(columnIndex);
}
@Override
public String getColumnName(int column) {
return (String) titlesV.get(column);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
}
public static void main(String[] args) {
new TableModelTest().init();
}
}
public class DefaultTableModelTest {
JFrame jf = new JFrame("TableModel演示");
//创建一维数组,存储标题
Object[] titles = {"姓名","年龄","性别"};
//创建二维数组,存储数据
Object[][] data = {
{"李清照",29,"女"},
{"苏格拉底",56,"男"},
{"李白",35,"男"},
{"弄玉",18,"女"},
{"虎头",2,"男"}
};
private Vector titlesV = new Vector();//存储标题
private Vector dataV = new Vector<>();//存储数据
public void init(){
//组装视图
for (int i = 0; i < titles.length; i++) {
titlesV.add(titles[i]);
}
for (int i = 0; i < data.length; i++) {
Vector t = new Vector<>();
for (int j = 0; j < data[i].length; j++) {
t.add(data[i][j]);
}
dataV.add(t);
}
//通过DefaultTableModel创建JTable
DefaultTableModel model = new DefaultTableModel(dataV,titlesV);
JTable jTable = new JTable(model);
//创建按钮
JButton addRow = new JButton("添加一行");
JButton addColum = new JButton("添加一列");
JButton deleteRow = new JButton("删除一行");
addRow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//需要给表格添加一行
model.addRow(new Object[]{"胡歌",30,"男"});
}
});
deleteRow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedRow = jTable.getSelectedRow();
model.removeRow(selectedRow);
}
});
addColum.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.addColumn("职业");
}
});
JPanel panel = new JPanel();
panel.add(addRow);
panel.add(addColum);
panel.add(deleteRow);
jf.add(panel, BorderLayout.SOUTH);
jf.add(new JScrollPane(jTable));
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new DefaultTableModelTest().init();
}
}
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();
}
}
public class EditTree {
JFrame jf = new JFrame("可编辑结点的树");
//定义几个初始结点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
//定义按钮,完成操作
JButton addSiblingBtn = new JButton("添加兄弟结点");
JButton addChildBtn = new JButton("添加子结点");
JButton deleteBtn = new JButton("删除结点");
JButton editBtn = new JButton("编辑当前结点");
public void init() {
//通过add()方法建立父子层级关系
guangdong.add(foshan);
guangdong.add(shantou);
guangxi.add(guilin);
guangxi.add(nanning);
root.add(guangdong);
root.add(guangxi);
JTree tree = new JTree(root);
//完成树的结点编辑的代码
tree.setEditable(true);
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
//处理添加
addSiblingBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//添加兄弟结点逻辑
//1.获取当前选中的结点
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (selectedNode == null) {
return;
}
//2.获取当前结点的父结点
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode.getParent();
if (parentNode == null) {
return;
}
//3.创建新结点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
//4.把新结点通过父结点进行添加
int index = parentNode.getIndex(selectedNode);
model.insertNodeInto(newNode, parentNode, index);
//5.显示新结点
TreeNode[] pathToRoot = model.getPathToRoot(newNode);
TreePath treePath = new TreePath(pathToRoot);
tree.scrollPathToVisible(treePath);
//6.重绘tree
tree.updateUI();
}
});
addChildBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//为选中结点添加子节点
//1.获取选中结点
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (selectedNode == null) {
return;
}
//2.创建新结点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
//3.把新结点添加到当前结点中
selectedNode.add(newNode);
//4.显示新结点
TreeNode[] pathToRoot = model.getPathToRoot(newNode);
TreePath treePath = new TreePath(pathToRoot);
tree.scrollPathToVisible(treePath);
//5.重绘UI
tree.updateUI();
}
});
//处理删除
deleteBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (selectedNode != null && selectedNode.getParent() != null) {
model.removeNodeFromParent(selectedNode);
}
}
});
//处理编辑
editBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取当前选中结点的路径
TreePath selectionPath = tree.getSelectionPath();
//判断如果路径不为空,则设置该路径的最后一个结点可编辑
if (selectionPath != null) {
tree.startEditingAtPath(selectionPath);
}
}
});
jf.add(new JScrollPane(tree));
JPanel panel = new JPanel();
panel.add(addSiblingBtn);
panel.add(addChildBtn);
panel.add(deleteBtn);
panel.add(editBtn);
jf.add(panel, BorderLayout.SOUTH);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
new EditTree().init();
}
}
public class ListenerJTree {
JFrame jf = new JFrame("监听树的选择事件");
JTree tree;
DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
JTextArea eventTxt = new JTextArea(5, 20);
public void init() {
//通过add()方法建立父子层级关系
guangdong.add(foshan);
guangdong.add(shantou);
guangxi.add(guilin);
guangxi.add(nanning);
root.add(guangdong);
root.add(guangxi);
tree = new JTree(root);
//TODO 设置选择模式
TreeSelectionModel selectionModel = tree.getSelectionModel();
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
//TODO 设置监听器
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
//把当前选中结点的路径显示到文本域中
TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
eventTxt.append(newLeadSelectionPath.toString()+"\n");
}
});
Box box = Box.createHorizontalBox();
box.add(new JScrollPane(tree));
box.add(new JScrollPane(eventTxt));
jf.add(box);
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
public static void main(String[] args) {
new ListenerJTree().init();
}
}
public class ChangeAllCellRender {
JFrame jf = new JFrame("改变所有结点外观");
JTree tree;
DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
public void init(){
//通过add()方法建立父子层级关系
guangdong.add(foshan);
guangdong.add(shantou);
guangxi.add(guilin);
guangxi.add(nanning);
root.add(guangdong);
root.add(guangxi);
tree = new JTree(root);
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
//设置非选定结点的背景颜色
renderer.setBackgroundNonSelectionColor(new Color(220,220,220));
//设置选中结点的背景色
renderer.setBackgroundSelectionColor(new Color(140,140,140));
//设置选中状态下结点的边框颜色
renderer.setBorderSelectionColor(Color.BLACK);
//设置处于折叠状态下非叶子结点的图标
renderer.setClosedIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\close.gif"));
//设置结点文本的字体
renderer.setFont(new Font("StSong", Font.BOLD,16));
//设置叶子结点图标
renderer.setLeafIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\leaf.png"));
//设置处于展开状态下非叶子结点图标
renderer.setOpenIcon(new ImageIcon("E:\\GUISwing\\img\\tree\\open.gif"));
//设置绘制非选中状态下结点文本颜色
renderer.setTextNonSelectionColor(new Color(255,0,0));
//设置选中状态下结点的文本颜色
renderer.setTextSelectionColor(new Color(0,0,255));
//把结点绘制器设置给树对象
tree.setCellRenderer(renderer);
jf.add(new JScrollPane(tree));
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
public static void main(String[] args) {
new ChangeAllCellRender().init();
}
}
public class ExtendsDefaultCellTreeRenderer {
JFrame jf = new JFrame("根据结点类型定义图标");
JTree tree;
//初始化5个图标
ImageIcon rootIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\root.gif");
ImageIcon databaseIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\database.gif");
ImageIcon tableIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\table.gif");
ImageIcon columnIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\column.gif");
ImageIcon indexIcon = new ImageIcon("E:\\GUISwing\\img\\tree\\index.gif");
//定义一个NodeData类,用于封装结点数据
class NodeData{
public ImageIcon icon;
public String name;
public NodeData(ImageIcon icon, String name) {
this.icon = icon;
this.name = name;
}
}
//定义几个初始结点
DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeData(rootIcon,"数据库导航"));
DefaultMutableTreeNode salaryDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司工资数据库"));
DefaultMutableTreeNode customerDb = new DefaultMutableTreeNode(new NodeData(databaseIcon,"公司客户数据库"));
DefaultMutableTreeNode employee = new DefaultMutableTreeNode(new NodeData(tableIcon,"员工表"));
DefaultMutableTreeNode attend = new DefaultMutableTreeNode(new NodeData(tableIcon,"考勤表"));
DefaultMutableTreeNode concat = new DefaultMutableTreeNode(new NodeData(tableIcon,"联系方式表"));
DefaultMutableTreeNode id = new DefaultMutableTreeNode(new NodeData(indexIcon,"员工ID"));
DefaultMutableTreeNode name = new DefaultMutableTreeNode(new NodeData(columnIcon,"姓名"));
DefaultMutableTreeNode gender = new DefaultMutableTreeNode(new NodeData(columnIcon,"性别"));
public void init(){
//通过结点的add方法,建立结点的父子关系
root.add(salaryDb);
root.add(customerDb);
salaryDb.add(employee);
salaryDb.add(attend);
customerDb.add(concat);
concat.add(id);
concat.add(name);
concat.add(gender);
//创建树
tree = new JTree(root);
//TODO 通过扩展DefaultTreeCellRenderer修改外观
tree.setCellRenderer(new MyRenderer());
jf.add(new JScrollPane(tree));
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
//自定义类,继承DefaultTreeCellRenderer,完成结点的绘制
private class MyRenderer extends DefaultTreeCellRenderer {
//重写方法
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
//当前类间接的继承了JLabel这个组件类,展示一张图片和一些配套的文字
//Object value这个参数,代表的就是即将要绘制的结点
//获取当前结点
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
//获取到当前即将绘制的结点的名称和图标
NodeData nodeData = (NodeData) node.getUserObject();
//通过setText方法和setIcon方法完成设置
this.setText(nodeData.name);
this.setIcon(nodeData.icon);
return this;
}
}
public static void main(String[] args) {
new ExtendsDefaultCellTreeRenderer().init();
}
}
public class CustomerTreeNode {
JFrame jf = new JFrame("定制树的结点");
JTree tree;
//定义几个初始结点
DefaultMutableTreeNode friends = new DefaultMutableTreeNode("我的好友");
DefaultMutableTreeNode qingzhao = new DefaultMutableTreeNode("李清照");
DefaultMutableTreeNode suge = new DefaultMutableTreeNode("苏格拉底");
DefaultMutableTreeNode libai = new DefaultMutableTreeNode("李白");
DefaultMutableTreeNode nongyu = new DefaultMutableTreeNode("弄玉");
DefaultMutableTreeNode hutou = new DefaultMutableTreeNode("虎头");
public void init() {
//组装视图
friends.add(qingzhao);
friends.add(suge);
friends.add(libai);
friends.add(nongyu);
friends.add(hutou);
tree = new JTree(friends);
//TODO 设置结点绘制器
MyRenderer renderer = new MyRenderer();
tree.setCellRenderer(renderer);
jf.add(new JScrollPane(tree));
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
//自定义类,实现TreeCellRenderer接口,绘制组件
private class MyRenderer extends JPanel implements TreeCellRenderer {
private ImageIcon icon;
private String name;
private Color background;
private Color foreground;
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
//给成员变量设置值
this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+value.toString()+".gif");
this.name = value.toString();
this.background = hasFocus? new Color(144,200,225) : new Color(255,255,255);
this.foreground = hasFocus? new Color(255,255,3) : new Color(0,0,0);
return this;
}
//通过重写getPreferenceSize方法,指定当前Jpanel组件的大小
@Override
public Dimension getPreferredSize() {
return new Dimension(80,80);
}
@Override
public void paint(Graphics g) {
//绘制组件内容
int iconWidth = this.icon.getIconWidth();
int iconHeight = this.icon.getIconHeight();
//填充背景
g.setColor(background);
g.fillRect(0,0,getWidth(),getHeight());
//绘制头像
g.drawImage(this.icon.getImage(),getWidth()/2 - iconWidth/2,10,null);
//绘制昵称
g.setColor(foreground);
g.setFont(new Font("StSong",Font.BOLD,18));
g.drawString(this.name,getWidth()/2-this.name.length()*20/2,iconHeight+30);
}
}
public static void main(String[] args) {
new CustomerTreeNode().init();
}
}
public class BorderTest {
JFrame jf = new JFrame("测试边框");
public void init(){
//组装视图
//1.JFrame的布局修改为GridLayout
jf.setLayout(new GridLayout(2,4));
//2.往网格中填充不同的JPanel组件,并且设置边框和内容
//创建BevelBorder
Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.GREEN, Color.BLUE, Color.GRAY);
jf.add(getJPanelWithBorder(bevelBorder,"BevelBorder"));
//创建LineBorder
Border lineBorder = BorderFactory.createLineBorder(Color.ORANGE, 10);
jf.add(getJPanelWithBorder(lineBorder,"LineBorder"));
//创建EmptyBorder
Border emptyBorder = BorderFactory.createEmptyBorder(10, 5, 20, 10);
jf.add(getJPanelWithBorder(emptyBorder,"EmptyBorder"));
//创建EchtedBorder
Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN);
jf.add(getJPanelWithBorder(etchedBorder,"EtchedBorder"));
//创建TitledBorder
TitledBorder titledBorder = new TitledBorder(new LineBorder(Color.ORANGE,10),"测试标题",TitledBorder.LEFT,TitledBorder.BOTTOM,new Font("StSong", Font.BOLD,18),Color.BLUE);
jf.add(getJPanelWithBorder(titledBorder,"TitledBorder"));
//创建MatteBorder
MatteBorder matteBorder = new MatteBorder(10, 5, 20, 10, Color.GREEN);
jf.add(getJPanelWithBorder(matteBorder,"MatteBorder"));
//创建CompoundBorder
CompoundBorder compoundBorder = new CompoundBorder( new LineBorder(Color.RED, 10),titledBorder);
jf.add(getJPanelWithBorder(compoundBorder,"CompoundBorder"));
//3.设置窗口最佳大小、设置窗口可见,处理关闭操作
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public JPanel getJPanelWithBorder(Border border,String content){
JPanel jPanel = new JPanel();
jPanel.add(new JLabel(content));
//设置边框
jPanel.setBorder(border);
return jPanel;
}
public static void main(String[] args) {
new BorderTest().init();
}
}