2015-02-11 41 views
2

我目前正在使用Eclipse(Luna,Win 8.1)開發一個簡短的Java Swing項目。目的是顯示一個包含菜單的框架。該菜單具有不同的頁面(主菜單,選項等),通過JPanels實現按鈕,標籤等。這些JPanel由CardLayout組織,以這種方式調用CardLayout.show(..) - 方法在不同的菜單頁面。當我兩天前停止編程時,一切都很完美。但是,當我想要在昨天早上繼續時,我的代碼似乎完全忽略了CardLayout:將鼠標光標移動到其位置時,位於其他卡片中的按鈕將彈出第一張卡片的背景。我試圖解決(研究,使用備份等)連續17個小時。問題仍然存在,現在= /我非常絕望。以下SSCCE顯示相同的行爲(將鼠標移到左下角以查看「選項」卡的「返回」按鈕彈出)。Java Swing CardLayout:似乎同時顯示多張牌

package sscce; 

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
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.JPanel; 

public class MainFrame extends JFrame { 
    private CardLayout mainWindowLayout; 
    // mainPanel will be used as the MainFrame's main unit to manage Components 
    private JPanel mainPanel; 

    // Constructor 
    public MainFrame() { 
     setTitle("sscce"); 
     setPreferredSize(new Dimension(800, 600)); 
     setResizable(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     getContentPane().setLayout(new BorderLayout()); 

     mainPanel = new JPanel(); 
     mainPanel.setPreferredSize(getSize()); 
     mainWindowLayout = new CardLayout(); 
     mainPanel.setLayout(mainWindowLayout); 

     buildMainMenu(); 
     buildOptions(); 

     getContentPane().add(mainPanel); 
     mainPanel.setVisible(true); 
     // starting application it will "show" (container, 
     // contentIdentifier(String)) 
     mainWindowLayout.show(mainPanel, "2"); 
     pack(); 
     setVisible(true); 
    }// Constructor 

    private void buildMainMenu() { 
     JPanel panelMainMenu = new JPanel(new GridBagLayout()); 
     panelMainMenu.setBackground(Color.orange); 

     // 1 Button (centered) to go to Options-Card 
     JButton bnOptions = new JButton("Options"); 
     // Button Functionality 
     bnOptions.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       mainWindowLayout.show(mainPanel, "2"); 
      } 
     }); 
     panelMainMenu.add(bnOptions); 
     panelMainMenu.setOpaque(true); 
     // container content identifier(String) 
     mainPanel.add(panelMainMenu, "1"); 
     panelMainMenu.setVisible(true); 
    }// buildMainMenu 

    private void buildOptions() { 
     JPanel panelOptions = new JPanel(); 
     panelOptions.setLayout(new GridBagLayout()); 
     // standardized margins for all Elements: 
     final Insets gbcInsets = new Insets(5, 5, 5, 5); 
     panelOptions.setBackground(Color.white); 

     JPanel fillerRight = new JPanel(); 
     JPanel fillerTop = new JPanel(); 
     JButton bnOptBack = new JButton("Back"); 

     bnOptBack.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       mainWindowLayout.show(mainPanel, "1"); 
      } 
     }); 

     // add filler panels to keep button in position 
     fillerRight.setBackground(Color.red); 
     fillerRight.setOpaque(true); 
     panelOptions.add(fillerRight, new GridBagConstraints(1, 1, 1, 2, 1, 0, 
       GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets, 
       0, 0)); 
     fillerRight.setVisible(true); 

     fillerTop.setBackground(Color.pink); 
     fillerTop.setOpaque(true); 
     panelOptions.add(fillerTop, new GridBagConstraints(0, 0, 2, 1, 0, 1, 
       GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets, 
       0, 0)); 
     fillerTop.setVisible(true); 

     // 1 Button in lower left hand corner, sends you back to MainMenu-card 
     panelOptions.add(bnOptBack, new GridBagConstraints(0, 1, 1, 1, 0, 0, 
       GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets, 
       0, 0)); 
     bnOptBack.setVisible(true); 

     panelOptions.setOpaque(true); 
     // container content identifier(String) 
     mainPanel.add(panelOptions, "2"); 
     panelOptions.setVisible(true); 
    }// buildOptions 

    public static void main(String[] args) { 
     MainFrame m = new MainFrame(); 
    }// main 
}// MainFrame 

任何幫助,非常感謝。 在此先感謝:) 編輯:我想你不需要看看「buildMainMenu」和「buildOptions」方法太緊密,單個菜單頁面的設置似乎工作正常。

回答

5

它的工作原理在我的機器上如預期,當我註釋掉以下兩行

panelOptions.setVisible(true); 

panelMainMenu.setVisible(true); 

當使用CardLayout,你只需要添加的成分和使用CardLayout#show來決定哪些你展示的一個。首先調用setVisible似乎會導致問題(無論出於何種原因)。

確保了Swing代碼上觸發EDT也是一個不錯的主意:

public static void main(String[] args) { 

    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     MainFrame m = new MainFrame(); 
     } 
    }); 
+0

嗯..那我應該說的。工作正常,謝謝一堆:) – Almato 2015-02-11 18:12:04