2016-12-25 50 views
0

(很抱歉,如果這個問題沒有正確地做,我是新的,但至少我問我自己的問題之前研究了很多)如何多次創建新的和部署jcomponents?

你好。我正在用java編寫一個二十一點遊戲,並且它變得非常龐大。 我的問題是如何處理擺動組件的多個實例,我想你可以調用它。我無法弄清楚如何創建組件(如jpanels和jbuttons)作爲類級別或特定的方法。

如果我在他們相應的方法中創建它們,那麼我的動作偵聽器將無法看到它們,但是如果我將它們創建爲類級別,那麼當我調用dispose()時,它們會被刪除。

class BlackjackGame extends JFrame implements ActionListener{ 

    public void mainMenu(){ 

     JPanel menuPane = new JPanel(new GridBagLayout()); //Init of main menu 
     GridBagConstraints c = new GridBagConstraints(); 
     menuPane.setBackground(new Color(125,0,0)); 
     menuPane.setBounds(620,220,175,250); 

     JLabel menuTitle = new JLabel("Welcome to Blackjack!");//Main menu-content 
     c.gridx = 1; 
     c.gridy = 0; 
     c.insets = new Insets(0,0,20,0); 
     menuPane.add(menuTitle, c); 

     JButton playButton = new JButton("Play!"); 
     playButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 1; 
     c.gridwidth = 3; 
     c.ipadx = 25; 
     c.ipady = 25; 
     c.insets = new Insets(0,0,0,0); 
     menuPane.add(playButton, c); 

     JButton exitButton = new JButton("Exit!"); 
     exitButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 2; 
     c.gridwidth = 3; 
     menuPane.add(exitButton, c); 

     JButton rulesButton = new JButton("Set rules."); 
     rulesButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 3; 
     c.gridwidth = 3; 
     menuPane.add(rulesButton, c); 

     this.add(menuPane,0); 
    } 

    //This is where I get problems 
    public void actionPerformed (ActionEvent event){ 
     if(event.getSource() == playButton){ 
      //I want the menuPane to disappear, and a transition into the game. 
      menuPane.dispose(); 
      //Call method for the rest of the game. 

     }else if(event .getSource() etcetera etcetera){ 
      etcetera etcetera 
     } 
    } 
} 

當這樣做時,actionlistener找不到我的組件,比如playButton或menuPane。但是,如果我曾經引進了他們作爲一流水平的對象:

class BlackjackGame extends JFrame implements ActionListener{ 

    JPanel menuPane = new JPanel(new GridBagLayout()); 
    JLabel menuTitle = new JLabel("Welcome to Blackjack!"); 
    JButton playButton = new JButton("Play!"); 
    JButton exitButton = new JButton("Exit!"); 
    JButton rulesButton = new JButton("Set rules."); 

    public void mainMenu(){ 
     //Rest of code 
    } 

    public void actionPerformed(ActionEvent event){ 
     menuPane.dispose(); 
     //Rest of code 
    } 
} 

...然後我打電話menuPane.dispose(),我怎麼能找回來,當我想再次呼籲mainMenu()?如果我想回到主菜單,那麼我需要創建一個menuPane的新實例,以及所有的按鈕,但是因爲它們是課程級別並且已經處理了,所以我不能。

請幫助我,謝謝!

PS。如果它有幫助,我可以發佈完整的代碼,因爲它是atm。

編輯:丹的答案已被接受,因爲它確實是正確的答案,它的工作對我的具體方案非常好。謝謝你,聖誕快樂!

+0

我想你可以從這裏http://stackoverflow.com/questions/11273267/java-open-a-new-window-by-clicking-a-button – IAmBlake

回答

1

首先,除非我誤解你的代碼,menuPane.dispose()不應視爲JPanel工作沒有一個叫dispose()

,最好的辦法功能做你想做的,如果你想使用相同的menuPane做什麼爲菜單。代替menuPane.dispose();使用remove(menuPane);然後add(yourOtherPanel);

工作實施例

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class BlackjackGame extends JFrame implements ActionListener { 
    private JPanel menuPane; 
    private JLabel menuTitle; 
    private JButton playButton; 
    private JButton exitButton; 
    private JButton rulesButton; 

    private JPanel otherPane; 
    private JLabel otherTitle; 
    private JButton otherButton; 

    public BlackjackGame() { 
     mainMenu(); 
     otherPanel(); 
     setSize(400, 400); 
     setVisible(true); 
    } 

    private void mainMenu() { 

     menuPane = new JPanel(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 
     menuPane.setBackground(new Color(125,0,0)); 
     menuPane.setBounds(620,220,175,250); 

     menuTitle = new JLabel("Welcome to Blackjack!"); 
     c.gridx = 1; 
     c.gridy = 0; 
     c.insets = new Insets(0,0,20,0); 
     menuPane.add(menuTitle, c); 

     playButton = new JButton("Play!"); 
     playButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 1; 
     c.gridwidth = 3; 
     c.ipadx = 25; 
     c.ipady = 25; 
     c.insets = new Insets(0,0,0,0); 
     menuPane.add(playButton, c); 

     exitButton = new JButton("Exit!"); 
     exitButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 2; 
     c.gridwidth = 3; 
     menuPane.add(exitButton, c); 

     rulesButton = new JButton("Set rules."); 
     rulesButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 3; 
     c.gridwidth = 3; 
     menuPane.add(rulesButton, c); 

     add(menuPane); 
    } 

    private void otherPanel() { 
     otherPane = new JPanel(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 
     otherPane.setBackground(new Color(125,0,0)); 
     otherPane.setBounds(620,220,175,250); 

     otherTitle = new JLabel("Welcome to Second Pane!"); 
     c.gridx = 1; 
     c.gridy = 0; 
     c.insets = new Insets(0,0,20,0); 
     otherPane.add(otherTitle, c); 

     otherButton = new JButton("Go Back!"); 
     otherButton.addActionListener(this); 
     c.gridx = 0; 
     c.gridy = 1; 
     c.gridwidth = 3; 
     c.ipadx = 25; 
     c.ipady = 25; 
     c.insets = new Insets(0,0,0,0); 
     otherPane.add(otherButton, c); 
    } 

    public void actionPerformed (ActionEvent event) { 
     if(event.getSource() == playButton) { 
      remove(menuPane); 
      add(otherPane); 
      validate(); 
      repaint(); 

     } else if(event.getSource() == otherButton) { 
      remove(otherPane); 
      add(menuPane); 
      validate(); 
      repaint(); 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> new BlackjackGame()); 
    } 
} 

編輯徵求意見

因此Java方法remove()僅刪除從容器,在這種情況下是對象JFrame。此方法不會影響其移動的對象,因此稍後可以重新使用該對象。因此,爲什麼在我上面的代碼可以只使用remove()add()方法,而沒有重新聲明或改造menuPaneotherPane

至於爲什麼我宣佈的對象這樣

`private JPanel menuPane;` 

然後初始化這樣

menuPane = new JPanel(new GridBagLayout()); 

這是因爲我希望ActionListener能夠看清物體,而不直接初始化它們遠。行private JPanel menuPane;使對象成爲一個全局變量,行menuPane = new JPanel(new GridBagLayout());使它成爲我將要使用的內容。這樣做而不是JPanel menuPane = new JPanel(new GridBagLayout());也意味着我可以在多個方法中重用相同的變量。例如

private JPanel panel; 

private void createPanelOne() { 
    panel = new JPanel(new FlowLayout()); 
    ... 
    add(panel); 
} 

private void createPanelTwo() { 
    panel = new JPanel(new GridBagLayout()); 
    ... 
    add(panel); 
} 

這樣做後,您將有兩個JPanel在你JFrame,他們會有所不同,但你只需要使用一個JPanel

這是宣佈它和它的另一種方式使局部變量。除非您傳遞方法,否則局部變量對您所用方法之外的其他方法不可見。

JPanel panel = new JPanel(); 

我不會說這是一絲不苟。我認爲有時候在一個方法中使用局部變量是很好的,而這個方法對其他方法是不可見的。

最後,要將局部變量傳遞給其他方法,您可以在所做的方法中使用參數。例如

public void setSomeValue(int val) { 
    someValue = val; 
} 
+0

歐凱讓我看到得到幫助如果我明白你做了什麼。首先在'public BlackjackGame()'中調用'mainMenu()'和'otherPanel()'方法創建兩個窗格的兩個實例。然後在需要時使用add()和remove()來顯示/取消顯示它們。這是我似乎誤解了它的工作方式,因爲'remove()'不會刪除窗格,使其消失,如果我想讓它再次顯示,我需要重新啓動它?即'menuPane = new JPanel();'感謝您的幫助! – heradsinn

+0

@heradsinn當然。我只會編輯我的答案。請稍等片刻 – Dan

+0

另一件事,我學會初始化對象和組件的方式是'JPanel menuPane = new JPanel();',而你首先聲明它爲'private JPanel menuPane;',然後(沒有JPanel infront)'menuPane =新的JPanel();'。你能否解釋一下差異和優點/缺點,謝謝! – heradsinn

相關問題