java swing开发窗体程序开发(六)树组件-表组件-定时器

前言:在开发java swing窗体程序时可能遇到以下的需求,比如要显示一个文件目录结构,文件目录树,有不同的分类,不同分类下有多个条目项。这就需要用到树组件。当需要显示一个表格,整齐的显示,就像excel那种形式,此时就需要表格组件【注意这里讲的并不是格子布局】

(一)树组件

核心类JTree,一个JTree的对象就代表一个树组件,创建树前应该先创节点,然后再去指 定节点间关系,最后形成树。

节点类型:

  • 根节点:仅有一个(树根)
  • 分支节点:带叶节点的分支(树枝)
  • 叶节点:不带子节点了(树叶)

分支节点可以点击图标展开或者收起

默认显示只会显示根节点和它直接相连的子节点

想作为节点需要实现 MutableTreeNode接口, 但不必我们自己写类来实现接口,在 java.swing.tree这个包中已经提供了一个叫做DefaultMutableTreeNode 通过创建这个类对象就可以作为节点,该类有两个构造方法

DefaultMutableTreeNode(Object userObject);
DefaultMutableTreeNode(Object userObject,boolean allowChild)

第一个构造方法:默认允许该节点能有子节点,其可以通过add()方法添加其他节点。通过 该构造函数创建的节点,可以通过setAllowsChildren(boolean b)来设置其是否允许添加子节点。

第二个构造方法:即在创建节点的时候就指定了其是否允许添加子节点

需要注意的是,其中userObject是一个Object类型对象,构造时需传入的对象,其表示这 个节点中存储的内容。

在实际使用中,这个Object参数,如果这个节点不是叶子节点,传入的都是字符串,代表 这个分支的含义。叶子节点的话,传入的是类的对象或者是自己的定义类的对象。此时这个节点显示的内容将会是这个类的toString()方法,所以想要他正确的显示,需要重写自定类的toString方法

当所有节点创建好之后,并用add函数处理好,分支节点和页节点关系后。从中选取一个作 为根节点(不能出现多个),调用JTree类的构造函数JTree(TreeNode root),传入 DefaultMutableTreeNode对象。即可生成树,窗口本身再调用add()函数,将JTree对象加入进去。

点击树上的节点会自动触发TreeSelectionEvent事件(注意:是指叶子节点,点分支节点 不会触发事件,只会收起和展开),其需要一个监听器,这个类需要实现 TreeSelectionListener接口。 该接口中的核心函数valueChanged(TreeSelectionEvent e)需要实现。 Jtree对象可以通过addTreeSelectionListener()来添加监视器。

以下是一个小demo来演示树组件

/**
 * 数据模型类,用于存储在树的节点当中
 */
 public class Goods {
 private String name;
 private double price;
 public Goods(String name,double price)
 {
 this.name=name;
 this.price=price;
 }

 public String getName() {
 return name;
 }

 public double getPrice() {
 return price;
 }

 @Override
 public String toString()
 {
 //叶节点显示出来的内容,这里叶节点应当将商品名字
 return name;
 }
 }
 public class SimpleListener implements TreeSelectionListener {
 private JTree tree;//这个树
 private JTextArea textArea;//显示区域
 public void setTree(JTree tree) {
 this.tree = tree;
 }

 public void setTextArea(JTextArea textArea) {
 this.textArea = textArea;
 }

 public void valueChanged(TreeSelectionEvent e) {
 //获得当前树选中的叶子节点
 DefaultMutableTreeNode selectedNode=(DefaultMutableTreeNode) tree.getLa
stSelectedPathComponent();
 if(selectedNode.isLeaf())
 {
 //选中的节点为叶子节点的情况下。JtextArea才会有变化
 Goods selectGoods=(Goods) selectedNode.getUserObject();//获得选中节点存储
的东西
 //将该商品信息进行显示
 textArea.append(selectGoods.getName()+"价格
为"+selectGoods.getPrice()+"\n");
 }

 }
 }

 public class SimpleForm extends JFrame {
 private JTree tree;//树组件
 private JTextArea textArea;//显示信息
 private SimpleListener listener;
 public SimpleForm()
 {
 //Gui部分
 setLayout(new GridLayout(1,2));
 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 setVisible(true);
 setBounds(80,80,300,300);
 textArea=new JTextArea();
 add(new JScrollPane(textArea));
 //树结构部分
 DefaultMutableTreeNode rootNode=new DefaultMutableTreeNode("商品");//定
义根节点
 DefaultMutableTreeNode TVtypeNode=new DefaultMutableTreeNode("电视
类");//定义子节点(有分支)
 DefaultMutableTreeNode PhoneTypeNode=new DefaultMutableTreeNode("手机
类");//定义子节点(有分支
 //定义叶节点的对象
 Goods changhongTV=new Goods("长虹电视",1000);
 Goods haierTV=new Goods("海尔电视",2000);
 Goods nokiaPhone=new Goods("诺基亚手机",500);
 Goods samsungPhone=new Goods("三星手机",600);
 //创建叶节点
 DefaultMutableTreeNode changhongTvNode=new DefaultMutableTreeNode(chang
hongTV);
 DefaultMutableTreeNode haierTvNode=new DefaultMutableTreeNode(haierTV);
 DefaultMutableTreeNode nokiaNode=new
DefaultMutableTreeNode(nokiaPhone);
 DefaultMutableTreeNode samsungNode=new DefaultMutableTreeNode(samsungPh
one);
 //指定父子关系
 TVtypeNode.add(changhongTvNode);
 TVtypeNode.add(haierTvNode);
 PhoneTypeNode.add(nokiaNode);
 PhoneTypeNode.add(samsungNode);
 rootNode.add(TVtypeNode);
 rootNode.add(PhoneTypeNode);
 //实例化树,并设置根节点
 tree=new JTree(rootNode);
 //把树加入该界面进行显示
 add(new JScrollPane(tree));
 //设置监听器
 listener=new SimpleListener();
 listener.setTree(tree);
 listener.setTextArea(textArea);
 //添加监听器
 tree.addTreeSelectionListener(listener);
 }
 }

 public class Main {
 public static void main(String[] args)
 {
 SimpleForm form=new SimpleForm();
 }
 }

效果如下

(二)表组件

即用于显示表格,且允许对其中的数据进行编辑,其有常见的3种构造方法

JTable();//创建默认的表格模型
JTable(int a,int b);//创建a行,b列的默认表格
JTable(Object data[][],Object columnName[]);//创建默认表格对象,并向其中填入
数据data二维数组,columnName数组中,存储的是列名

需要注意的是

第3种构造方法,可以传入Object的对象,和刚刚的JTree树组件一样,其可以传入字符 串,也可以传入自定对象,当传入自定对象时,其显示出来的东西就是该类对象调用 toString()函数后显示的内容。 所以,这个自定类需要重写自己的toString方法

下面是一个案例

public class SimpleListener implements ActionListener {
    private JTable table;
    private Object [][]data;

    public void setTable(JTable table) {
        this.table = table;
    }

    public void setData(Object[][] data) {
        this.data = data;
    }

    public void actionPerformed(ActionEvent actionEvent)
    {
        for(int i=0;i<8;i++)
        {
            double sum=0;
            boolean isNum=true;
            for(int j=1;j<=2;j++) {
                try {
                    sum += Double.parseDouble(data[i][j].toString());
                } catch (Exception e) {
                    //说明输入了不是数字的内容
                    isNum = false;
                    table.repaint();//表格重新绘制
                }
                if (isNum == true) {
                    //总分一栏
                    data[i][3] = String.valueOf(sum);
                    table.repaint();//表格重新绘制
                }
            }
        }
    }
}

public class SimpleWindow extends JFrame {
    private JTable table;
    private Object [][]data;
    private Object []columName;
    private JButton button;
    private SimpleListener listener;

    public SimpleWindow()
    {
        //GUI部分
        setLayout(new BorderLayout());
        columName=new Object[]{"姓名","英语","数学","总成绩"};//该表格表头
        data=new Object[8][4];//该表格将会是8行4列
        for(int i=0;i<=data.length-1;i++)
        {
            for(int j=0;j<=data[i].length-1;j++)
            {
                if(j!=0)
                {
                    //即非第一列,第一列应该为姓名,其余列默认都为0
                    data[i][j]=0;
                }else {
                    //第一列设置为姓名
                    data[i][j]="姓名";
                }
            }
        }
        button=new JButton("计算总成绩");
        table=new JTable(data,columName);
        //注意!必须把JTable加载JScrollPane中,否则显示不出表头
        add(new JScrollPane(table),BorderLayout.CENTER);
        add(button,BorderLayout.SOUTH);
        setVisible(true);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setBounds(100,100,200,200);
        //设置监听器
        listener=new SimpleListener();
        listener.setData(data);
        listener.setTable(table);
        //添加监听器
        button.addActionListener(listener);
    }
}
public class Main {
    public static void main(String []args)
    {
        SimpleWindow window=new SimpleWindow();
    }
}

效果如下

Add:关于表JTable的一些设置:

默认:该表的表头和值是可修改的。

  • 使表头不可拖动
//注意bookTable为JTable对象
booksTable.getTableHeader().setReorderingAllowed(false);
  • 使表中数据不可更改
booksTable=new JTable(data,columnName){
 @Override
 public boolean isCellEditable(int row, int column) {
 return false;
 }
 };

(三)计时器组件

在Javax.swing包中的Timer类(Java.util也有个Timer,不是那个),是一个计时器组 件。其有两种构造方法

new Timer(int a,Object b);//设置振铃周期,并设置监听器
new Timer(int a);//仅设置振铃周期,此后还需要timer对象addActionListener()
来指定监听器

其中a代表周期,即每过a毫秒震铃一次,b是监听器,即实现了ActionListener接口的类对 象。振铃时就会触发ActionEvent事件,从而执行接口回调actionPerormed方法。

该类的常用实例方法还有:

setReapeats(boolean );//设置是否重复,默认为true,设置为false后,时间到了就只会振铃一次,不会重复执行
setInitialDelay(int delay);//设置首次振铃的延时
start();//开始计时
stop();//停止计时
restart();//继续计时

案例如下

public class WindowTimer extends JFrame implements ActionListener{
    private JTextField text;
    private JButton startBtn,stopBtn,continueBtn;
    private Timer timer;
    private SimpleDateFormat format;//日期输出格式
    public WindowTime()
    {
        //GUI部分
        text=new JTextField(10);//用来显示时间
       startBtn=new JButton("开始");
       stopBtn=new JButton("停止");
       continueBtn=new JButton("继续"); 
       setLayout(new FlowLayout());//设置布局
       add(startBtn);
       add(stopBtn);
       add(continueBtn);
       add(text);
       setSize(500,500);
       setVisiable(true);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //设置timer计时器,和日期格式化
       format=new SimpleDateFormat("hh:mm:ss");
       timer=new Timer(1000,this);//1s振铃一次
       //设置监听器,该类本身就是监听器,不用设置,引用可以直接拿到
       //添加监听器,3个按钮和一个timer共用一个Listener
       startBtn.addActionListener(this);
       stopBtn.addActionListener(this);
       continueBtn.addActionListener(this);
       timer.addActionListener(this);
    }
    
    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource()==timer)
        {
            //触发源是计时器,那么需要设置时间
            Date currentDate=new Date();
            text.setText(fomrat.(currentDate));
        }else if(e.getSource()==startBtn)
        {
            //触发源是开始按钮
            timer.start();
        }else if(e.getSource()==stopBtn)
        {
            //触发源是结束按钮
            timer.stop();
        }else if(e.getSource()==continueBtn)
        {
            //触发源是继续按钮
            timer.reStart();
        }
    }
}

上一篇:java swing开发窗体程序开发(五)对话框

【!!!】欢迎关注我的个人线上课堂https://www.zuikakuedu.cn,内含JavaWeb与Unity游戏开发实战教程,完全免费!,Csdn博客涉及的课程资料也在该网站上

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最咔酷学院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值