我正在用Java创建一个虚拟钢琴类型程序。我现在用于钢琴键的区域是一个JPanel,它的水平BoxLayout包含白色JButtons作为白键。我也想添加黑键,并让它们与白键重叠。
我尝试过两种不同的方法。一种是使用OverlayLayout。不幸的是,OverlayLayout管理器的在线文档不多,而且在NetBeans GUI构建器中也不可用。我不知道该怎么做。我尝试过的第二件事是使用JLayeredPanes。我似乎也想不出这一点,即使在Netbeans中把它搞砸了。
所以我想我的问题很简单。如果有,在其他JButtons之上添加JButtons的最佳方法是什么?或者,除了用JButtons做钢琴键之外,还有别的选择吗?
编辑
为了得到我想要的结果,我已经把aioobe和dacwe的代码组合在一起。我基本上使用了dacwe的z排序和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);
}
}谢谢你们!现在我需要以某种方式将侦听器和文本附加到这些按钮上。
发布于 2010-11-25 19:34:30
我会写一个自定义的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);来自使用Swing组件教程跟踪
注意:z顺序决定了绘制组件的顺序.具有最高z阶涂料的组件首先使用z阶涂料,而最小z阶涂料的组件则是最后一个.当组件重叠时,具有较低z阶的组件在z阶较高的组件上绘制.
这里是一个丑陋的黑客,它使用空布局让您开始。
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);
}
}

发布于 2010-11-25 20:08:47
这是一个分层窗格的示例(如您所期望的那样工作):
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);
}但是,您需要按正确的顺序(:)排列钢琴键:

发布于 2010-11-25 19:39:11
除了编写您自己的布局管理器之外,您还可以使用一个null LayoutManager (即没有自动布局管理)并手动定位键。然后在容器上使用setComponentZOrder确保黑键出现在白色键的上方。
https://stackoverflow.com/questions/4280281
复制相似问题