[英]Making JButtons overlap
我正在Java Swing中創建一個虛擬鋼琴類型程序。 我現在的鋼琴鍵區域是一個JPanel,其水平BoxLayout包含白色JButtons作為白鍵。 我也想添加黑鍵,讓它們與白鍵重疊。
我嘗試過兩種不同的方法。 一個是使用OverlayLayout。 遺憾的是,OverlayLayout管理器在線沒有太多文檔,並且在NetBeans GUI構建器中不可用。 我不知道如何讓它發揮作用。 我嘗試過的第二件事是使用JLayeredPanes。 即使在Netbeans中弄亂它之后,我似乎無法想出那個。
所以我認為我的問題非常簡單。 如果有的話,在其他JButton之上添加JButton的最佳方法是什么? 或者也許有一個替代使用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);
}
}
多謝你們! 現在我需要以某種方式將監聽器和文本附加到這些按鈕。
我會編寫一個自定義的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);
注意: z順序決定了組件的繪制順序。 具有最高z次序塗料的組件首先塗漆,具有最低z次序塗料的組件最后塗漆。 在組件重疊的情況下,具有較低z次序的組件在具有較高z次序的組件上繪制。
這是一個丑陋的黑客,它使用null-layout來幫助你入門。
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);
}
}
這是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);
}
但是,您需要按正確的順序布置鋼琴鍵(:)):
除了編寫自己的布局管理器之外,您可以使用null
LayoutManager(即沒有自動布局管理)並手動定位鍵。 然后在容器上使用setComponentZOrder
以確保黑鍵出現在白色上方。
GridBag布局確實允許小部件重疊; 您可以使用重疊跨度來構建所需的布局。 但是,是的,編寫自己的布局管理器會更好。
我在Swing中做了幾個游戲,我發現不使用布局管理器或制作自己的游戲更容易。 例如,我有一個紙牌游戲和一個自定義布局管理器,可以查看卡片的播放位置,並根據該卡片和當前面板大小對其進行定位。
查看該帖子中的 Darryl解決方案(最后一個回復)。 它變得棘手並使用“按鈕”作為黑色按鈕,因此它繪制在白色“JButton”之上。 這可能不適用於允許混合AWT和Swing組件的JDK的新版本。
然而,整潔的部分是鍵在點擊時實際產生聲音。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.