how2j.cn

-->
下载区
文件名 文件大小
请先登录 2m
增值内容 2m
2m

解压rar如果失败,请用5.21版本或者更高版本的winrar

点击下载 winrar5.21

11分20秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器

步骤 1 : CategoryService   
步骤 2 : CategoryTableModel   
步骤 3 : CategoryPanel   
步骤 4 : CategoryListener   
步骤 5 : 在CategoryPanel中加上监听器   
步骤 6 : 运行效果   

增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package service; import java.util.Collections; import java.util.List; import dao.CategoryDAO; import dao.RecordDAO; import entity.Category; import entity.Record; public class CategoryService { CategoryDAO categoryDao = new CategoryDAO(); RecordDAO recordDao = new RecordDAO(); public List<Category> list() { List<Category> cs= categoryDao.list(); for (Category c : cs) { List<Record> rs =recordDao.list(c.id); c.recordNumber=rs.size(); } Collections.sort(cs,(c1,c2)->c2.recordNumber-c1.recordNumber); return cs; } public void add(String name) { Category c = new Category(); c.setName(name); categoryDao.add(c); } public void update(int id, String name) { Category c = new Category(); c.setName(name); c.setId(id); categoryDao.update(c); } public void delete(int id) { categoryDao.delete(id); } }
步骤 2 :

CategoryTableModel

edit
增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package gui.model; import java.util.List; import javax.swing.table.AbstractTableModel; import entity.Category; import service.CategoryService; public class CategoryTableModel extends AbstractTableModel { String[] columnNames = new String[] { "分类名称", "消费次数"}; // 使用从Service返回的List作为TableModel的数据 public List<Category> cs = new CategoryService().list(); public int getRowCount() { return cs.size(); } public int getColumnCount() { return columnNames.length; } public String getColumnName(int columnIndex) { return columnNames[columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } // 先通过cs.get(rowIndex)获取行对应的Category对象 // 然后根据columnIndex返回对应的属性 public Object getValueAt(int rowIndex, int columnIndex) { Category h = cs.get(rowIndex); if (0 == columnIndex) return h.name; if (1 == columnIndex) return h.recordNumber; return null; } }
增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package gui.panel; import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import entity.Category; import gui.model.CategoryTableModel; import service.CategoryService; import util.ColorUtil; import util.GUIUtil; public class CategoryPanel extends JPanel { static { GUIUtil.useLNF(); } public static CategoryPanel instance = new CategoryPanel(); public JButton bAdd = new JButton("新增"); public JButton bEdit = new JButton("编辑"); public JButton bDelete = new JButton("删除"); String columNames[] = new String[] { "分类名称", "消费次数" }; public CategoryTableModel ctm = new CategoryTableModel(); public JTable t = new JTable(ctm); public CategoryPanel() { GUIUtil.setColor(ColorUtil.blueColor, bAdd, bEdit, bDelete); JScrollPane sp = new JScrollPane(t); JPanel pSubmit = new JPanel(); pSubmit.add(bAdd); pSubmit.add(bEdit); pSubmit.add(bDelete); this.setLayout(new BorderLayout()); this.add(sp, BorderLayout.CENTER); this.add(pSubmit, BorderLayout.SOUTH); } public static void main(String[] args) { GUIUtil.showPanel(CategoryPanel.instance); } public Category getSelectedCategory() { int index = t.getSelectedRow(); return ctm.cs.get(index); } public void updateData() { ctm.cs = new CategoryService().list(); t.updateUI(); t.getSelectionModel().setSelectionInterval(0, 0); if(0==ctm.cs.size()){ bEdit.setEnabled(false); bDelete.setEnabled(false); } else{ bEdit.setEnabled(true); bDelete.setEnabled(true); } } }
增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
CategoryListener
package gui.listener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JOptionPane; import entity.Category; import gui.panel.CategoryPanel; import service.CategoryService; public class CategoryListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { CategoryPanel p = CategoryPanel.instance; JButton b = (JButton) e.getSource(); if (b == p.bAdd) { String name = JOptionPane.showInputDialog(null); if (0 == name.length()) { JOptionPane.showMessageDialog(p, "分类名称不能为空"); return; } new CategoryService().add(name); } if (b == p.bEdit) { Category c = p.getSelectedCategory(); int id = c.id; String name = JOptionPane.showInputDialog("修改分类名称", c.name); if (0 == name.length()) { JOptionPane.showMessageDialog(p, "分类名称不能为空"); return; } new CategoryService().update(id, name); } if (b == p.bDelete) { Category c = p.getSelectedCategory(); if (0 != c.recordNumber) { JOptionPane.showMessageDialog(p, "本分类下有消费记录存在,不能删除"); return; } if (JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(p, "确认要删除?")) return; int id = c.id; new CategoryService().delete(id); } p.updateData(); } }
步骤 5 :

在CategoryPanel中加上监听器

edit
增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package gui.panel; import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import entity.Category; import gui.listener.CategoryListener; import gui.model.CategoryTableModel; import service.CategoryService; import util.ColorUtil; import util.GUIUtil; public class CategoryPanel extends JPanel { static { GUIUtil.useLNF(); } public static CategoryPanel instance = new CategoryPanel(); public JButton bAdd = new JButton("新增"); public JButton bEdit = new JButton("编辑"); public JButton bDelete = new JButton("删除"); String columNames[] = new String[] { "分类名称", "消费次数" }; public CategoryTableModel ctm = new CategoryTableModel(); public JTable t = new JTable(ctm); public CategoryPanel() { GUIUtil.setColor(ColorUtil.blueColor, bAdd, bEdit, bDelete); JScrollPane sp = new JScrollPane(t); JPanel pSubmit = new JPanel(); pSubmit.add(bAdd); pSubmit.add(bEdit); pSubmit.add(bDelete); this.setLayout(new BorderLayout()); this.add(sp, BorderLayout.CENTER); this.add(pSubmit, BorderLayout.SOUTH); addListener(); } public static void main(String[] args) { GUIUtil.showPanel(CategoryPanel.instance); } public Category getSelectedCategory() { int index = t.getSelectedRow(); return ctm.cs.get(index); } public void updateData() { ctm.cs = new CategoryService().list(); t.updateUI(); t.getSelectionModel().setSelectionInterval(0, 0); if(0==ctm.cs.size()){ bEdit.setEnabled(false); bDelete.setEnabled(false); } else{ bEdit.setEnabled(true); bDelete.setEnabled(true); } } public void addListener() { CategoryListener listener = new CategoryListener(); bAdd.addActionListener(listener); bEdit.addActionListener(listener); bDelete.addActionListener(listener); } }
增值内容,请先登录
完整的J2SE桌面项目,从无到有完整的开发流程,涵盖全部52个知识点,154个开发步骤, 一共36个讲解视频,累计时长3小时10分59秒,大小1.94G,充实J2SE项目经验,为简历加上一个有吸引力的砝码
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
运行效果


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2022-01-09 CategoryTableModel 由 implement TableModel改成现在代码上的"extends AbstractTableModle"
Alex97




一,使用implement TableModel 在"原型_界面类"章节里,categoryTableModle使用的是 implement TableModel,其中有个重写方法,需要重写为 public Class<?> getColumnClass(int columnIndex) { if (columnIndex==0){return String.class;} if (columnIndex==1){return int.class;} return null; }. 不重写的话会报空指针异常,并且分类面板崩溃. 二,改为extends AbstractTableModle 否则,应该提示将"implement TableModle"改成现在代码上的"extends AbstractTableModle",并删除getColumnClass方法
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        if (columnIndex==0){return String.class;}
        if (columnIndex==1){return int.class;}
        return null;
    }
D:\JDK\bin\java "-javaagent:D:\IDEA\IntelliJ IDEA 2017.2\lib\idea_rt.jar=3672:D:\IDEA\IntelliJ IDEA 2017.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JDK\jre\lib\charsets.jar;D:\JDK\jre\lib\deploy.jar;D:\JDK\jre\lib\ext\access-bridge.jar;D:\JDK\jre\lib\ext\cldrdata.jar;D:\JDK\jre\lib\ext\dnsns.jar;D:\JDK\jre\lib\ext\jaccess.jar;D:\JDK\jre\lib\ext\jfxrt.jar;D:\JDK\jre\lib\ext\localedata.jar;D:\JDK\jre\lib\ext\nashorn.jar;D:\JDK\jre\lib\ext\sunec.jar;D:\JDK\jre\lib\ext\sunjce_provider.jar;D:\JDK\jre\lib\ext\sunmscapi.jar;D:\JDK\jre\lib\ext\sunpkcs11.jar;D:\JDK\jre\lib\ext\zipfs.jar;D:\JDK\jre\lib\javaws.jar;D:\JDK\jre\lib\jce.jar;D:\JDK\jre\lib\jfr.jar;D:\JDK\jre\lib\jfxswt.jar;D:\JDK\jre\lib\jsse.jar;D:\JDK\jre\lib\management-agent.jar;D:\JDK\jre\lib\plugin.jar;D:\JDK\jre\lib\resources.jar;D:\JDK\jre\lib\rt.jar;D:\project\hutubill\out\production\hutubill;D:\project\hutubill\lib\liquidlnf.jar;D:\project\hutubill\lib\chart.jar;D:\project\hutubill\lib\swingx-core-1.6.2.jar;D:\project\hutubill\lib\mysql-connector-java-5.0.8-bin.jar startup.BootStrap

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.JTable.prepareRenderer(JTable.java:5723)
	at com.birosoft.liquid.LiquidTableUI.paintCell(LiquidTableUI.java:298)
	at com.birosoft.liquid.LiquidTableUI.paintCells(LiquidTableUI.java:190)
	at com.birosoft.liquid.LiquidTableUI.paint(LiquidTableUI.java:101)
	at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
	at javax.swing.JComponent.paintComponent(JComponent.java:780)
	at javax.swing.JComponent.paint(JComponent.java:1056)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JViewport.paint(JViewport.java:728)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
	at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
	at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:831)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.JTable.prepareRenderer(JTable.java:5723)
	at com.birosoft.liquid.LiquidTableUI.paintCell(LiquidTableUI.java:298)
	at com.birosoft.liquid.LiquidTableUI.paintCells(LiquidTableUI.java:190)
	at com.birosoft.liquid.LiquidTableUI.paint(LiquidTableUI.java:101)
	at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
	at javax.swing.JComponent.paintComponent(JComponent.java:780)
	at javax.swing.JComponent.paint(JComponent.java:1056)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JViewport.paint(JViewport.java:728)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintChildren(JComponent.java:889)
	at javax.swing.JComponent.paint(JComponent.java:1065)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
	at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
	at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:831)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)


1 个答案

how2j
答案时间:2022-02-02
good!



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2021-04-26 当记录过多时,CategoryService.list()使用record来获取recordNumer创建对象过多,不如通过sql语句直接获取到recordNumber
郁蒸十四




不如写个方法用来获取id对应的record条数,mysql的开销远比Java小
    private int getRecordNumber(int id){
        String sql="select count(*) from category c left join record r on c.id=r.category_id where c.id=? and r.id is not null";
        int recordNumber=0;
        try(Connection connection=DBUtil.getConnection();PreparedStatement preparedStatement=connection.prepareStatement(sql)){
            preparedStatement.setInt(1,id);
            ResultSet resultSet=preparedStatement.executeQuery();
            if (resultSet.next()){
                recordNumber=resultSet.getInt(1);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        return recordNumber;
    }

    public List<Category> list(int start,int count){
        String sql="select * from category limit ?,?";
        List<Category> categories=new ArrayList<>();
        try(Connection connection=DBUtil.getConnection();PreparedStatement preparedStatement=connection.prepareStatement(sql)){
            preparedStatement.setInt(1,start);
            preparedStatement.setInt(2,count);
            ResultSet resultSet=preparedStatement.executeQuery();
            while (resultSet.next()){
                Category category=new Category();
                category.setId(resultSet.getInt("id"));
                category.setName(resultSet.getString("name"));
                category.setRecordNumber(getRecordNumber(category.getId()));
                categories.add(category);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        return categories;
    }

							


1 个答案

how2j
答案时间:2021-04-27
dao 有个 getTotal方法嘛



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2021-04-05 建议在CategoryListener类中增加一行name是否是null的判断
2020-12-21 抛了个数组下标越界的异常
2020-11-17 关于新增分类时无法正常显示中文


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 22 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 实践项目-一本糊涂账-消费分类 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图