java Console 控制台为null问题 Console con = System.console()

本文探讨了Java SE6中引入的Console类的使用方法及其局限性。特别关注如何通过Console类读取用户输入的名字和密码,并解释了在不同环境中(如Eclipse IDE与命令行)使用Console类时可能遇到的问题。

问题描述

学习如何从控制台输入中一般都会使用Scanner类,但是读取密码时JavaSE6引入了Console类,测试代码如下:

        Console console =  System.console();
        System.out.println(console);
        System.out.print("请输入你的名字:");
        String personName = console.readLine();
        System.out.print("请输入你的密码:");
        char[] password = console.readPassword();

该段代码在Eclipse的控制台中打印出来的结果是console的值为null.

原因

  如果Java程序要与windows下的cmd或者Linux下的Terminal交互,就可以使用这个Java Console类代劳。Java要与Console进行交互,不总是能得到可用的Java Console类的。一个JVM是否有可用的Console,依赖于底层平台和JVM如何被调用。如果JVM是在交互式命令行(比如Windows的cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的Console实例。
  但当使用Eclipse等IDE运行以上代码时Console中将会为null。
  表示Java程序无法获得Console实例,是因为JVM不是在命令行中被调用的,或者输入输出被重定向了。在Eclipse诸如类似的IDE工具中运行Console类。如果没有对Console实例判空操作,结果使用了该实例会抛出java.lang.NullPointerException异常。
  以上解释参考:http://blog.sina.com.cn/s/blog_a4f75d8001018wvf.html

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; public class SportManneger extends JFrame implements ActionListener { JTextField keyword; JTable table; JButton btnAdd; JButton btnEdit; JButton btnDelete; JButton btnSearch; JButton btnRefresh; DefaultTableModel model; JLabel statusLabel; SportManneger() { super("体育商品管理系统"); Container c = getContentPane(); c.setLayout(new BorderLayout(0, 0)); // 背景面板 JPanel backgroundPanel = new JPanel(new BorderLayout()) { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); java.awt.GradientPaint gradient = new java.awt.GradientPaint( 0, 0, new Color(250, 250, 255), 0, getHeight(), new Color(245, 245, 240) ); g2d.setPaint(gradient); g2d.fillRect(0, 0, getWidth(), getHeight()); } }; backgroundPanel.setOpaque(true); // 顶部按钮栏 JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10)); topPanel.setOpaque(false); topPanel.setBorder(new EmptyBorder(15, 15, 15, 15)); btnAdd = createStyledButton("添加商品", new Color(34, 139, 34), new Color(50, 205, 50)); btnEdit = createStyledButton("编辑商品", new Color(70, 130, 180), new Color(100, 149, 237)); btnDelete = createStyledButton("删除商品", new Color(220, 20, 60), new Color(255, 69, 0)); btnRefresh = createStyledButton("刷新", new Color(128, 128, 128), new Color(169, 169, 169)); topPanel.add(btnAdd); topPanel.add(btnEdit); topPanel.add(btnDelete); topPanel.add(btnRefresh); // 搜索栏 JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10)); searchPanel.setOpaque(false); searchPanel.setBorder(new EmptyBorder(10, 15, 10, 15)); JLabel searchLabel = new JLabel("搜索:"); searchLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14)); keyword = new JTextField(20); keyword.setFont(new Font("微软雅黑", Font.PLAIN, 13)); keyword.setBorder(new javax.swing.border.CompoundBorder( new javax.swing.border.LineBorder(new Color(200, 200, 200), 1, true), new EmptyBorder(5, 10, 5, 10) )); keyword.setPreferredSize(new Dimension(200, 30)); btnSearch = createStyledButton("搜索", new Color(138, 43, 226), new Color(186, 85, 211)); searchPanel.add(searchLabel); searchPanel.add(keyword); searchPanel.add(btnSearch); // 合并顶部面板 JPanel topBarPanel = new JPanel(new BorderLayout()); topBarPanel.setOpaque(false); topBarPanel.add(topPanel, BorderLayout.WEST); topBarPanel.add(searchPanel, BorderLayout.EAST); // 表格 String[] colName = {"ID", "商品名称", "类别", "价格", "库存", "品牌", "描述"}; model = new DefaultTableModel(colName, 0) { @Override public boolean isCellEditable(int row, int column) { return false; } }; table = new JTable(model); table.setFont(new Font("微软雅黑", Font.PLAIN, 13)); table.setRowHeight(30); table.setSelectionBackground(new Color(230, 240, 255)); table.setSelectionForeground(Color.BLACK); table.setGridColor(new Color(240, 240, 240)); table.setBackground(Color.WHITE); table.setShowGrid(true); table.setIntercellSpacing(new Dimension(0, 0)); // 表头样式 JTableHeader header = table.getTableHeader(); header.setFont(new Font("微软雅黑", Font.BOLD, 14)); header.setForeground(new Color(255, 128, 0)); header.setPreferredSize(new Dimension(100, 40)); header.setReorderingAllowed(false); JScrollPane sp = new JScrollPane(table); sp.setBorder(null); sp.setOpaque(false); sp.getViewport().setOpaque(false); // 状态栏 JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); statusPanel.setOpaque(false); statusPanel.setBorder(new EmptyBorder(5, 15, 5, 15)); statusPanel.setBackground(new Color(240, 240, 240)); statusLabel = new JLabel("就绪"); statusLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12)); statusLabel.setForeground(new Color(100, 100, 100)); statusPanel.add(statusLabel); backgroundPanel.add(topBarPanel, BorderLayout.NORTH); backgroundPanel.add(sp, BorderLayout.CENTER); backgroundPanel.add(statusPanel, BorderLayout.SOUTH); c.add(backgroundPanel); btnAdd.addActionListener(this); btnEdit.addActionListener(this); btnDelete.addActionListener(this); btnSearch.addActionListener(this); btnRefresh.addActionListener(this); // 初始化加载数据 try { Class.forName("com.mysql.cj.jdbc.Driver"); // 显式加载驱动 refreshTable(); } catch (Exception e) { e.printStackTrace(); updateStatus("错误:驱动加载失败"); } setSize(1200, 700); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } private JButton createStyledButton(String text, Color bgColor, Color hoverColor) { JButton btn = new JButton(text) { @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (getModel().isPressed()) { g2d.setColor(bgColor.darker()); } else if (getModel().isRollover()) { g2d.setColor(hoverColor); } else { g2d.setColor(bgColor); } g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 5, 5); g2d.dispose(); super.paintComponent(g); } }; btn.setFont(new Font("微软雅黑", Font.BOLD, 13)); btn.setForeground(Color.WHITE); btn.setPreferredSize(new Dimension(100, 35)); btn.setFocusPainted(false); btn.setBorderPainted(false); btn.setContentAreaFilled(false); btn.setOpaque(false); return btn; } private void updateStatus(String status) { statusLabel.setText(status); } public void refreshTable() { try { System.out.println("🔄 开始刷新表格..."); // ✅ 彻底清空模型 model.setRowCount(0); // ✅ 重新查询 queryAll(); int count = model.getRowCount(); System.out.println("✅ 刷新完成,共加载 " + count + " 条记录"); updateStatus("就绪 - 共 " + count + " 条记录"); } catch (SQLException e) { e.printStackTrace(); updateStatus("错误:刷新失败"); JOptionPane.showMessageDialog(this, "数据库访问失败:" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } } private void queryAll() throws SQLException { String url = "jdbc:mysql://127.0.0.1:3306/sport_sql?" + "useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&cacheResultSetMetadata=false"; try (Connection con = DriverManager.getConnection(url, "root", "1234"); Statement st = con.createStatement(); ResultSet res = st.executeQuery("SELECT * FROM products")) { while (res.next()) { Object[] row = { res.getInt("ID"), res.getString("商品名称"), res.getString("类别"), String.format("%.2f", res.getDouble("价格")), res.getInt("库存"), res.getString("品牌"), res.getString("描述") }; model.addRow(row); } } } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnSearch) { String key = keyword.getText().trim(); if (key.isEmpty()) { refreshTable(); } else { try { model.setRowCount(0); search(key); int count = model.getRowCount(); updateStatus("搜索完成 - 找到 " + count + " 条记录"); } catch (SQLException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "搜索失败:" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } } } else if (e.getSource() == btnRefresh) { refreshTable(); } else if (e.getSource() == btnDelete) { if (table.getSelectedRow() < 0) { JOptionPane.showMessageDialog(this, "请先选择要删除的商品!", "提示", JOptionPane.WARNING_MESSAGE); return; } int result = JOptionPane.showConfirmDialog(this, "确定要删除选中的商品吗?", "确认删除", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { try { System.out.println("🗑️ 正在执行删除..."); delete(); System.out.println("✔️ 删除完成,准备刷新"); refreshTable(); // ✅ 必须在这里刷新! System.out.println("🔁 刷新完成"); } catch (SQLException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "删除失败:" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } } } else if (e.getSource() == btnAdd) { new SportAdd(this).setVisible(true); } else if (e.getSource() == btnEdit) { if (table.getSelectedRow() < 0) { JOptionPane.showMessageDialog(this, "请先选择要编辑的商品!", "提示", JOptionPane.WARNING_MESSAGE); return; } String id = model.getValueAt(table.getSelectedRow(), 0).toString(); new SportEdit(this, id).setVisible(true); } } private void search(String key) throws SQLException { String sql = "SELECT * FROM products WHERE " + "商品名称 LIKE ? OR 类别 LIKE ? OR 品牌 LIKE ? OR 描述 LIKE ?"; String likeKey = "%" + key + "%"; String url = "jdbc:mysql://127.0.0.1:3306/sport_sql?" + "useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"; try (Connection con = DriverManager.getConnection(url, "root", "1234"); PreparedStatement ps = con.prepareStatement(sql)) { ps.setString(1, likeKey); ps.setString(2, likeKey); ps.setString(3, likeKey); ps.setString(4, likeKey); try (ResultSet res = ps.executeQuery()) { while (res.next()) { Object[] row = { res.getInt("ID"), res.getString("商品名称"), res.getString("类别"), String.format("%.2f", res.getDouble("价格")), res.getInt("库存"), res.getString("品牌"), res.getString("描述") }; model.addRow(row); } } } } public void delete() throws SQLException { String url = "jdbc:mysql://127.0.0.1:3306/sport_sql?" + "useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&rewriteBatchedStatements=true"; try (Connection con = DriverManager.getConnection(url, "root", "1234")) { con.setAutoCommit(false); // 启用事务 try (PreparedStatement ps = con.prepareStatement("DELETE FROM products WHERE ID = ?")) { int[] selectedRows = table.getSelectedRows(); for (int i = 0; i < selectedRows.length; i++) { int modelIndex = selectedRows[i]; String idStr = model.getValueAt(modelIndex, 0).toString(); try { int id = Integer.parseInt(idStr); ps.setInt(1, id); ps.addBatch(); // 添加到批处理 } catch (NumberFormatException ignored) {} } ps.executeBatch(); // 执行批量删除 con.commit(); // 提交事务 System.out.println("✅ 数据库删除成功(已提交事务)"); } catch (SQLException e) { con.rollback(); System.err.println("❌ 删除失败,事务已回滚"); throw e; } } } public static void main(String[] args) { new SportManneger(); } } 点删除商品商品还是存在 请完善这个不敢
最新发布
12-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值