You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JToolBar与JPanel无法在同一JFrame共存的问题求助

Swing布局问题:JPanel与JToolBar无法同时正常显示

问题描述

我希望JPanel能显示在JToolBar正下方,但实际运行后JPanel未出现;若将JPanel设置为BorderLayout.PAGE_START,JFrame仅显示JPanel而不显示JToolBar。

代码示例

package omok;

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.util.*;
import javax.swing.*;
public class Omok implements ActionListener {
    JFrame frame =new JFrame();
    public Omok() {
       JMenuBar menuBar=menubar();
       JToolBar toolBar=toolBar();
       JPanel panel=panel();
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setSize(400,500);
       frame.getContentPane().setBackground(Color.ORANGE);
       frame.setLayout(new BorderLayout());
       frame.setJMenuBar(menuBar);
       frame.add(toolBar,BorderLayout.PAGE_START);
       frame.add(panel,BorderLayout.NORTH);
       frame.pack();
       frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        
    }
private JMenuBar menubar() {
    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("Game");
    menu.setMnemonic(KeyEvent.VK_G);
    menu.getAccessibleContext().setAccessibleDescription("Game menu");
    menuBar.add(menu);
    JMenuItem menuItem = new JMenuItem("Play", KeyEvent.VK_P);
    menuItem.setAccelerator(KeyStroke.getKeyStroke(
       KeyEvent.VK_P, InputEvent.ALT_DOWN_MASK));
    menuItem.getAccessibleContext().setAccessibleDescription(
       "Play a new game");
    //menuItem.addActionListener(…);
    menu.add(menuItem);
    return menuBar;
}
private JToolBar toolBar() {
    ImageIcon icon=new ImageIcon("C:\\Users\\carlo\\Documents\\Adv OO Programming\\L\\OmokGUI\\res\\play.png");
    Image image=icon.getImage();
    Image newImg=image.getScaledInstance(20, 20, Image.SCALE_SMOOTH);
    icon=new ImageIcon(newImg);
    JToolBar toolBar = new JToolBar("Omok");
    JButton button = new JButton(icon);
    button.setPreferredSize(new Dimension(20,20));
    button.setToolTipText("Play a new game");
    button.setFocusPainted(false);
    toolBar.add(button);
    toolBar.setPreferredSize(new Dimension(30,30));
    return toolBar;

}
private JPanel panel() {
    JPanel panel=new JPanel();
    panel.setPreferredSize(new Dimension(40,40));
    panel.setBackground(Color.gray);
    return panel;
}

}

运行结果

代码运行结果

问题原因与解决方法

问题根源

BorderLayout中PAGE_START和NORTH是同一区域的不同名称,完全等价。先后把ToolBar和Panel添加到同一区域时,后添加的Panel会覆盖掉之前的ToolBar,这就是两种布局方式都无法同时显示两个组件的原因。

解决方案

有两种简单的实现方式可以让JToolBar在上、JPanel紧随其下:

方式一:用垂直容器包裹两个组件

创建一个JPanel作为容器,设置垂直方向的BoxLayout,把ToolBar和Panel依次加入该容器,再将容器添加到JFrame的PAGE_START区域:

// 修改Omok构造方法中的组件添加逻辑
JPanel topContainer = new JPanel();
topContainer.setLayout(new BoxLayout(topContainer, BoxLayout.Y_AXIS));
topContainer.add(toolBar);
topContainer.add(panel);
frame.add(topContainer, BorderLayout.PAGE_START);

方式二:将Panel放到CENTER区域

如果希望Panel填充ToolBar下方的剩余空间,直接把Panel添加到BorderLayout的CENTER区域即可:

// 修改构造方法中的添加代码
frame.add(toolBar, BorderLayout.PAGE_START);
frame.add(panel, BorderLayout.CENTER);

如果想保持Panel的固定大小,除了保留setPreferredSize,还要加上panel.setMaximumSize(panel.getPreferredSize()),避免Panel被拉伸。

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:43:17