JPanel中的组件仅在调整大小后显示

时间:2017-08-21 13:37:24

标签: java swing jpanel

我的JPanel中的按钮在加载时不会显示,只有当我调整窗口大小或将鼠标移到窗口上时才会显示。在其他讨论中,建议使用“validate()”或“repaint()”,但这对我不起作用。 我正在使用基本的模型视图控制器设计,我很确定我正在做其他正确的事情。 万一你想知道,当然会有更多的面板添加到框架中,这就是update()和changeCards()方法的目的。 这是我的框架:

public class View extends JFrame {

    private MainMenuPanel mainMenu;

    private final String MAIN_MENU_CONSTRAINTS = "MAIN_MENU";

    public View() {

        super();

        init();

        mainMenu = new MainMenuPanel();
        add(mainMenu;MAIN_MENU_CONSTRAINTS);
        validate();
        repaint(0,0,getWidth(),getHeight());
        setVisible(true);
    }


    private void init() {
        setVisible(false);

        setTitle("Test");

        // set card-layout
        setRootPaneCheckingEnabled(false);
        CardLayout cl = new CardLayout();
        this.setLayout(cl);

        // expand frame to whole display size
        setExtendedState(MAXIMIZED_BOTH);

        // set unclosable
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }


    public void update (Mode mode) {

        switch (mode) {

            case MAIN_MENU:
                changeCard(MAIN_MENU_CONSTRAINTS);
                break;

        }

    }

    public void changeCard(String card) {

        // update cards
        CardLayout cl = (CardLayout) getLayout();
        cl.show(this, card);
    }
}

以下是小组:

public class MainMenuPanel extends Panel implements ActionListener{


    private JButton startButton;
    private JButton quitButton;

    private final String START_ACTION_COMMAND = "START";
    private final String QUIT_ACTION_COMMAND = "QUIT";

    private MainMenuPanelListenerImpl listener;


    public MainMenuPanel() {

        super();

        init();

        initComponents();
        configureComponents();
        configureListeners();
        addComponents();

        revalidate();

    } 


    private void init() {
        setLayout(null);
    }

    private void initComponents() {
        startButton = new JButton();
        quitButton = new JButton();
    }

    private void configureComponents() {
        startButton.setText("Start");
        quitButton.setText("End");

        startButton.setBounds((int)(0.5*getWidth()-200), (int)(0.5*getHeight()-75), 400, 75);
        quitButton.setBounds((int)(0.5*getWidth()-200), (int)(0.5*getHeight()+25),400,75);
    }

    private void configureListeners() {
        startButton.addActionListener(this);
        startButton.setActionCommand(START_ACTION_COMMAND);
        quitButton.addActionListener(this);
        quitButton.setActionCommand(QUIT_ACTION_COMMAND);
    }

    private void addComponents() {
        add(startButton);
        add(quitButton);
        startButton.validate();
        quitButton.validate();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case START_ACTION_COMMAND:
                listener.start();
                break;
            case QUIT_ACTION_COMMAND:
                System.exit(0);
            break;
        }
    }

    public void setListener(MainMenuPanelListenerImpl listener) {
        this.listener = listener;
    }
}

2 个答案:

答案 0 :(得分:1)

在你绘制元素之后,你把 setvisible(true) 因为如果你把它放在之前,Jframe 将不会绘制任何元素

答案 1 :(得分:0)

首先,您将旧的AWT-Components(如Panel)与较新的SWING-Components(如JFrame)混合使用。那些不能很好地协同工作,所以我会先尝试解决这个问题。我强烈建议您使用SWING,或者如果您想学习最新的Java GUI库,那么请学习JavaFX。

不要在JFrame的构造函数中使用重绘方法,实际上你根本不应该在SWING中使用重绘。你也不需要在构造函数中验证。如果您想将JFrame放置在某个位置,则应使用类似this.setLocation(0,0)

的内容

关于主要问题:面板可能仅在调整大小后显示它的组件,因为您以错误的方式将其添加到JFrame。在SWING中有一个称为内容窗格的东西,您应该将所有内容添加到(除了JMenuBar,但这是一个不同的故事)。

只需将内容窗格的布局设置为您要使用的卡片布局,然后将面板添加到内容窗格中。

此处有关于小组级别的链接:https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html