[英]How to completely get rid of a JPanel and everything in it?
如何在運行時完全擺脫JPanel
及其中的所有內容?
package textgame;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class EscapeFromPrison extends JFrame implements ActionListener{
JButton startGameButton;
JButton creditsButton;
JButton choice1;
Button choice2;
JLabel mainTitleLabel;
JLabel question;
JLabel space;
JLabel credits;
JPanel titleScreen;
public EscapeFromPrison(){
super("Escape From Prison");
setLookAndFeel();
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainTitleLabel = new JLabel("<html>Escape From Prison</html>");
startGameButton = new JButton("<html>START<html>");
startGameButton.setActionCommand("StartGameButton");
creditsButton = new JButton("<html>CREDITS</html>");
creditsButton.addActionListener(this);
creditsButton.setActionCommand("CreditsButton");
question = new JLabel("");
space = new JLabel("");
credits = new JLabel("");
choice1 = new JButton("");
choice2 = new JButton("");
JPanel titleScreen = new JPanel();
BoxLayout titleScreenLayout = new BoxLayout(titleScreen, BoxLayout.Y_AXIS);
titleScreen.setLayout(titleScreenLayout);
titleScreen.add(mainTitleLabel);
titleScreen.add(startGameButton);
titleScreen.add(creditsButton);
add(titleScreen);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent buttonClick){
String event = buttonClick.getActionCommand();
在這個if語句中,我想擺脫mainTitleLabel
, startGameButton
和creditsButton
。 所以問題可能在左上角位置,因為現在它們目前是不可見的,問題是在右上角位置。 我正在使用網格布局。
if(event.equals("StartGameButton")){
GridLayout grid = new GridLayout(2,2);
setLayout(grid);
question.setText("<html>text</html>");
choice1.setActionCommand("");
choice1.setText("");
choice2.setActionCommand("");
choice2.setText("");
mainTitleLabel.setVisible(false);
startGameButton.setVisible(false);
creditsButton.setVisible(false);
add(question);
add(choice1);
add(choice2);
setVisible(true);
}
if(event.equals("CreditsButton")){
FlowLayout flo = new FlowLayout();
setLayout(flo);
credits.setText("<html></html>");
mainTitleLabel.setVisible(false);
startGameButton.setVisible(false);
creditsButton.setVisible(false);
add(credits);
setVisible(true);
}
}
private void setLookAndFeel(){
try{
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
}catch(Exception exc){
//ignore error
}
}
public static void main(String[] arguments){
EscapeFromPrison frame = new EscapeFromPrison();
}
}
當前代碼的基本問題是startGameButton
從未注冊到ActionListener
,因此它永遠不會做任何事情。
最大的問題是,當您添加更多內容時,您的代碼將變得非常復雜。 一個更好的解決方案是將每個視圖分成它自己的類,然后您可以根據需要獨立管理和切換。
這是模型 - 視圖 - 控制器概念的開始,您可以將功能分離為自包含域,這些域可以通過類似觀察者模式(作為一個想法)進行通信。
通過這種方式,您可以使用CardLayout
更輕松地在視圖之間切換。
這只是實現這一目標的眾多可能方法之一
首先,我們需要定義某種“控制器”,它可以用來控制可見的東西。 我們使用接口作為主要合同,因為它們限制了實現的暴露並定義了我們期望在類之間維護的確切合同,這通常稱為“接口程序”,請參閱智能Java開發和代碼到接口以獲取更多信息細節
public interface CardGameController {
public void showMainMenu();
public void showQuestion();
public void showCredits();
}
現在,因為我想使用CardLayout
作為控制視圖的底層機制,我需要一個CardGameController
的實現,它可以做到這一點......
public class DefaultCardGameController implements CardGameController {
public static final String MAIN_MENU_PANE = "mainMenuPane";
public static final String CREDITS_PANE = "creditsPane";
public static final String QUESTION_PANE = "questionPane";
private Container parent;
private CardLayout cardLayout;
public DefaultCardGameController(Container parent, CardLayout cardLayout) {
this.parent = parent;
this.cardLayout = cardLayout;
}
public Container getParent() {
return parent;
}
public CardLayout getCardLayout() {
return cardLayout;
}
protected void show(String name) {
getCardLayout().show(getParent(), name);
}
@Override
public void showMainMenu() {
show(MAIN_MENU_PANE);
}
@Override
public void showCredits() {
show(CREDITS_PANE);
}
@Override
public void showQuestion() {
show(QUESTION_PANE);
}
}
有關詳細信息,請查看如何使用CardLayout
現在,我們需要我們想要管理的視圖......
public class MenuPane extends JPanel {
private JButton startGameButton;
private JButton creditsButton;
private JLabel mainTitleLabel;
private CardGameController controller;
public MenuPane(CardGameController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
mainTitleLabel = new JLabel("<html>Escape From Prison</html>");
startGameButton = new JButton("<html>START<html>");
startGameButton.setActionCommand("StartGameButton");
startGameButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showQuestion();
}
});
creditsButton = new JButton("<html>CREDITS</html>");
creditsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showCredits();
}
});
creditsButton.setActionCommand("CreditsButton");
add(mainTitleLabel, gbc);
add(startGameButton, gbc);
add(creditsButton, gbc);
}
}
public class QuestionPane extends JPanel {
private JButton choice1;
private JButton choice2;
private JLabel question;
private CardGameController controller;
public QuestionPane(CardGameController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
question = new JLabel("The meaning of life, the universe and everything!?");
choice1 = new JButton("42");
choice2 = new JButton("46");
add(question, gbc);
JPanel panel = new JPanel();
panel.add(choice1);
panel.add(choice2);
gbc.gridy++;
add(panel, gbc);
// Have some mechanism to control the questions
}
}
public class CreditsPane extends JPanel {
private JLabel credits;
private CardGameController controller;
public CreditsPane(CardGameController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
credits = new JLabel("Happy Bunnies");
add(credits);
}
}
最后,將“大師”視圖匯集在一起......
public class EscapeFromPrison extends JPanel {
private MenuPane menuPane;
private QuestionPane questionPane;
private CreditsPane creditsPane;
public EscapeFromPrison() {
CardLayout cardLayout = new CardLayout();
setLayout(cardLayout);
DefaultCardGameController controller = new DefaultCardGameController(this, cardLayout);
menuPane = new MenuPane(controller);
questionPane = new QuestionPane(controller);
creditsPane = new CreditsPane(controller);
add(menuPane, DefaultCardGameController.MAIN_MENU_PANE);
add(questionPane, DefaultCardGameController.QUESTION_PANE);
add(creditsPane, DefaultCardGameController.CREDITS_PANE);
controller.showMainMenu();
}
private static void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc) {
//ignore error
}
}
public static void main(String[] arguments) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
setLookAndFeel();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new EscapeFromPrison());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
現在,這是一個非常有限的例子,它采用了你已經完成的工作並演示了一些基本原理。
因為你會問一個以上的問題,你需要一些方法來更有效地管理問題(和答案),這最好通過某種模型來完成,其中包含所有問題,可能的答案和用戶答案。 這樣,你只需要一個問題視圖,但可以使用問題模型中的信息來重新配置自己以顯示每個新問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.