Java Swing项目中为Canvas添加JButton后按钮无法显示问题求助
核心问题原因
- JFrame默认使用
BorderLayout布局,连续添加Canvas和按钮时两个组件都被放在BorderLayout.CENTER区域,尺寸更大的Canvas会完全遮挡住按钮 - 使用
setBounds设置组件位置尺寸前,必须手动关闭容器的默认布局管理器,否则坐标设置不生效 - 按钮未绑定实现好的
ActionListener监听器,即使显示也无法触发点击回调
修复后完整代码
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class Main extends Canvas implements ActionListener, MouseListener { private static JButton try144Button = new JButton(); public static void main(String[] args) { // Swing组件建议在事件 dispatch 线程初始化 SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("Chess"); // 关闭默认布局,启用绝对定位 frame.setLayout(null); // 设置窗口关闭即退出程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Canvas canvas = new Main(); canvas.setBounds(0,0,1000,1000); frame.add(canvas); // 按钮放在后添加,层级更高不会被遮挡 frame.add(try144Button); frame.setSize(1000,1000); frame.setVisible(true); }); } public Main(){ try144Button.setText("CLICK ME"); try144Button.setBounds(210, 60, 150, 150); // 绑定点击监听器 try144Button.addActionListener(this); } public void paint(Graphics g) { int xshift; int yshift = 0; g.setColor(new Color(0, 0, 0)); for (int i = 0; i < 4; i++) { xshift = 125; for (int j = 0; j < 4; j++) { g.fillRect(xshift, yshift, 125, 125); xshift += 250; } xshift = 0; yshift += 125; for (int k = 0; k < 4; k++) { g.fillRect(xshift, yshift, 125, 125); xshift += 250; } yshift += 125; } initalprnt(g); } public void initalprnt(Graphics g) { int xshift = 125; int yshift = 0; g.setColor(new Color(0, 100, 0)); for (int i = 0; i < 3; i++) { if (i == 2) { xshift = 125; } for (int j = 0; j < 4; j++) { g.fillOval(xshift, yshift, 125, 125); xshift += 250; } xshift = 0; yshift += 125; } yshift += 250; g.setColor(new Color(0, 0, 100)); for (int k = 0; k < 3; k++) { if (k == 2) { xshift = 0; } for (int j = 0; j < 4; j++) { g.fillOval(xshift, yshift, 125, 125); xshift += 250; } xshift = 125; yshift += 125; } } public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); if (src == try144Button) System.out.println("this worked"); } public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }
主要调整点
- 给JFrame设置空布局,
setBounds设置的坐标和尺寸可以正常生效 - 调整组件添加顺序,按钮在Canvas之后添加,保证按钮层级更高不会被遮挡
- 给按钮绑定了ActionListener监听器,点击后可以正常输出日志
- 新增了窗口关闭退出逻辑,避免程序后台驻留
- 使用
SwingUtilities.invokeLater保证Swing组件在事件调度线程初始化,避免偶发渲染异常
内容的提问来源于stack exchange,提问作者OutcastedCringe
相关产品推荐
相关产品推荐

