簡體   English   中英

為什么我的相框沒有調整尺寸?

[英]Why is my frame not resizing?

選擇狀態時,框架的內容窗格將刪除其組件。 然后,根據您選擇的狀態,另一個類將內容窗格添加到該窗格。 這樣做之后,框架將打包以相應地調整大小。

我想自由控制Frame中的內容,例如能夠將面板並排放置,彼此疊放等。所以我真的不想使用CardLayout。 (我寧願讓一個面板同時處理登錄屏幕和聊天。然后,能夠在該面板旁邊顯示另一個面板)。

我在登錄和聊天屏幕上使用的是JFrame的內容窗格,但是當我運行代碼時,我得到一個很小的框架(有一些大小,但幾乎沒有),里面是白色的。

  1. 展示框
  2. 切換到聊天
  3. 刪除窗格上的所有內容(當前什么也沒有)
  4. 將組件添加到窗格
  5. 包裝框架,以便可以根據窗格大小進行調整
  6. 如果需要,請重新驗證(不確定何時需要重新驗證)

請告訴我我做錯了什么,也許可以指導我正確的方向。 PS:沒有錯誤

編輯:我唯一能想到的是,由於我正在通過方法傳遞frame.getContentPane() ,並且方法是按值傳遞的,因此對frame.getContentPane()的實際引用可能不會引起我的注意在要求。 但是然后我不知道為什么框架的內部會是白色的(就像我的JTextArea嘗試渲染一樣),並且框架的內部有填充,所以必須要發生一些事情。

Main.java:

package main;

import ui.Frame;

public class Main {
    public static Frame frame = new Frame();

    public static void main(String[] args) {
        frame.show();
        frame.switchState(State.chat);

    }

    public static enum State {
        login, chat;
    }
}

Frame.java:

package ui;

import main.Main.State; 
import javax.swing.JFrame;

public class Frame {
        private Panel currentpanel; //from package ui, not AWT
        private ChatPanel chatpanel = new ChatPanel();

        private JFrame frame;
        public Frame() {
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
        }

        public void show() {
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

        public void switchState(State state) {
            frame.removeAll();

            switch(state) {
                 case chat:
                currentpanel = chatpanel;
                currentpanel.addComponentsTo(frame.getContentPane());
                break;
            }
            frame.pack();
            frame.revalidate();
        }
    }

Panel.java:

package ui;

import java.awt.Container;

public interface Panel {
    public void addComponentsTo(Container pane);
}

ChatPanel.java:

package ui;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JTextArea;

public class ChatPanel implements Panel {
    private JTextArea toparea = new JTextArea();
    private JTextArea bottomarea = new JTextArea();

    @Override
    public void addComponentsTo(Container pane) {
        pane.setPreferredSize(new Dimension(500, 500));
        pane.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridy = 0;
        gbc.gridx = 0;
        gbc.ipadx = 450;
        gbc.ipady = 350;
        pane.add(toparea, gbc);

        gbc.gridy = 1;
        gbc.ipady = 100;
        pane.add(bottomarea);
    }
}

我知道這可能會令人沮喪。

你試過打電話嗎

pack(); or repaint();

我發現了問題。 它正在調用frame.removeAll(); 在添加任何東西之前。

當我嘗試if(frame.getComponents().length > 0) ,它仍然觸發removeAll() ,但問題並未得到解決。 看到我還沒有添加任何東西,我檢查了一下組件是什么(通過打印對象),它是一個JRootPane

之后,我嘗試打印出frame.getContentPane().getComponents().length ,它給了我0預期的效果。

長話短說:這是switchPanel(State state)外觀:

    public void switchState(State state) {
        if(frame.getContentPane().getComponents().length > 0)
             frame.removeAll();

        switch(state) {
             case chat:
                 currentpanel = chatpanel;
                 currentpanel.addComponentsTo(frame.getContentPane());
                 break;
        }
        frame.pack();
        frame.revalidate();
    }

注意:我仍然建議使用CardLayout,但是如果您堅持動態設置框架的內容窗格,則為此處。

鏡框類

public class SwitchingFrame extends JFrame {

    public static enum State {ONE, TWO}
    private PanelONE panel1 = new PanelONE();
    private PanelTWO panel2 = new PanelTWO();

    public SwitchingFrame() {

        getContentPane().setLayout(new BorderLayout());
        pack();
        setVisible(true);
    }

    public void switchState(State state) {

        setVisible(false);
        getContentPane().removeAll();
        if (state.equals(State.ONE))
            getContentPane().add(panel1, BorderLayout.CENTER);
        else
            getContentPane().add(panel2, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }
}

切換的兩個面板類

public class PanelONE extends JPanel {

    public PanelONE() {

        add(new JLabel("ONE"));
    }
}

public class PanelONE extends JPanel {

    public PanelTWO() {

        add(new JLabel("TWO"));
    }
}

主要方法包括模擬面板更改的按鈕

public class TestSwitchingFrame {

    public static void main(String[] args) {

        final SwitchingFrame sframe = new SwitchingFrame();

        JFrame frame = new JFrame();
        JButton b1 = new JButton("ONE");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                sframe.switchState(SwitchingFrame.State.ONE);
            }
        });
        JButton b2 = new JButton("TWO");
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                sframe.switchState(SwitchingFrame.State.TWO);
            }
        });
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(b1);
        frame.getContentPane().add(b2);
        frame.pack();
        frame.setVisible(true);
    }
}

您不需要(也不應該)編寫自己的界面(面板)。 您的兩個面板應擴展JPanel並在框架內容窗格中進行設置。 您的框架應該擴展JFrame,並且不需要重寫其show方法(讓Swing為您完成)。 switchState函數的特定實現最終應取決於所需的最終結果。 有相似的方法可以達到幾乎相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM