2010-11-25 93 views
5

我正在Java Swing中創建一個虛擬鋼琴類型的程序。我現在的鋼琴鍵區域是一個帶有水平BoxLayout的JPanel,它包含白色JButtons作爲白色鍵。我想要添加黑鍵,並讓它們與白鍵重疊。使JButton重疊

我試過兩種不同的方法。一種是使用OverlayLayout。不幸的是,OverlayLayout管理器沒有太多的文檔在線,並且在NetBeans GUI構建器中不可用。我不知道如何使它工作。我試過的第二件事是使用JLayeredPanes。我似乎也無法弄清楚這一點,即使在Netbeans中搞亂了它。

所以我覺得我的問題很簡單。如果有的話,最好的方法是在其他JButton上添加JButtons?或者,也許有另一種方法來使用JButtons作爲鋼琴鍵?

編輯

我結合aioobe的和dacwe的代碼來獲得我想要的結果。我基本上使用了dacwe的z-ordering和aioobe的基本尺寸(放大一點)以及mod 7部分。我還添加了一些變量以使事情更加清晰。這是我現在擁有的。

import javax.swing.*; 
import java.awt.Color; 

public class Test2 { 

public static void main(String[] args) { 

    JFrame frame = new JFrame("Test"); 

    JLayeredPane panel = new JLayeredPane(); 
    frame.add(panel); 

    int maxKeys = 8; 

    int width = 60; 
    int height = 240; 

    for (int i = 0; i < maxKeys; i++) { 
     JButton b = new JButton(); 
     b.setBackground(Color.WHITE); 
     b.setLocation(i * width, 0); 
     b.setSize(width, height); 

     panel.add(b, 0, -1); 
    } 

    int width2 = 48; 
    int height2 = 140; 
    for (int i = 0; i < maxKeys; i++) { 
     int j = i % 7; 
     if (j == 2 || j == 6) 
      continue; 

     JButton b = new JButton(); 
     b.setBackground(Color.BLACK); 
     b.setLocation(i*(width) + (width2*3/4), 0); 
     b.setSize(width2, height2); 

     panel.add(b, 1, -1); 
    } 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(500,280); 
    frame.setVisible(true); 
    } 
} 

謝謝你們!現在我需要以某種方式將偵聽器和文本附加到這些按鈕。

回答

5

我會寫一個自定義的PianoLayoutManager並將黑鍵的位置設置得比白色按鈕的z更高。創建自己的「約束」類,允許你添加成分是這樣的:

add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 1); 
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 2); 
... 
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, n); 

add(new BlackKey(), new PianoLayoutConstraint(BLACK, 1); 
add(new BlackKey(), new PianoLayoutConstraint(BLACK, 2); 
... 
add(new BlackKey(), new PianoLayoutConstraint(BLACK, m); 

Using Swing Components tutorial trail

注: z順序確定部件被漆成順序。具有最高z順序的組件最先繪製,最後z順序最後繪製的組件。在組件重疊的地方,具有較低z-次序的組件繪製具有較高z-次序的組件。

這是一個醜陋的黑客使用null佈局,讓你開始。

import java.awt.Color; 
import javax.swing.*; 

class PianoComponent extends JPanel { 

    PianoComponent() { 

     setLayout(null); 

     for (int i = 0; i < 20; i++) { 
      JButton key = new JButton(); 
      key.setBackground(Color.WHITE); 
      key.setLocation(i * 20, 0); 
      key.setSize(20, 120); 
      add(key); 
      setComponentZOrder(key, i); 
     } 

     for (int i = 0; i < 20; i++) { 
      int j = i % 7; 
      if (j == 2 || j == 6) 
       continue; 

      JButton key = new JButton(); 
      key.setBackground(Color.BLACK); 
      key.setLocation(i * 20 + 12, 0); 
      key.setSize(16, 80); 
      add(key); 
      setComponentZOrder(key, 0); 
     } 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     JFrame jf = new JFrame("Piano!"); 
     jf.setSize(400, 200); 
     jf.add(new PianoComponent()); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jf.setVisible(true); 
    } 
} 

enter image description here

+0

組件z順序搞砸了! – dacwe 2010-11-25 19:58:46

+0

你覺得呢?我認爲它看起來不錯... :) – aioobe 2010-11-25 19:59:15

+0

Ehhh,編譯並運行並將鼠標移到它上面......當它們被重新渲染時,它會按錯誤順序渲染按鈕。 – dacwe 2010-11-25 20:01:48

0

網格包佈局確實允許插件重疊;你可以使用重疊跨度來構建你想要的佈局。但是,編寫自己的版面管理器會更好。

0

我在Swing中做過幾個遊戲,我發現只是不使用佈局管理器或自己創建遊戲更容易。例如,我有一個紙牌遊戲和一個自定義佈局管理器,用於查看卡片的播放位置並根據當前的面板大小對其進行定位。

1

除了編寫自己的佈局管理器之外,您還可以使用LayoutManager(即不進行自動佈局管理)並手動定位鍵。然後在容器上使用setComponentZOrder以確保黑鍵出現在白色的上方。

3

這是的layeredPane的例子(它可以作爲你期望的那樣):

public static void main(String[] args) { 

    JFrame frame = new JFrame("Test"); 

    JLayeredPane panel = new JLayeredPane(); 
    frame.add(panel); 


    for (int i = 0; i < 8; i++) { 
     JButton b = new JButton(); 
     b.setBackground(Color.WHITE); 
     b.setLocation(i * 20, 0); 
     b.setSize(20, 100); 

     panel.add(b, 0, -1); 
    } 

    for (int i = 0; i < 4; i++) { 
     JButton b = new JButton(); 
     b.setBackground(Color.BLACK); 
     b.setLocation(10 + i * 40, 0); 
     b.setSize(20, 70); 

     panel.add(b, 1, -1); 
    } 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(400, 300); 
    frame.setVisible(true); 
} 

不過,你需要制定出正確的順序鋼琴鍵(:)):

alt text

0

檢查出這個posting Darryl的解決方案(最後回覆)。它變得棘手,並使用「按鈕」作爲黑色按鈕,因此它在白色的「JButton」上繪畫。在JDK的新版本中,這可能無法使AWT和Swing組件混合使用。

然而,整潔的部分是,點擊時鍵實際上會產生聲音。