Java Swing-MIDI钢琴第一步
我只是在我创建这个项目的第一阶段,但我已经迷路了。在我的课堂上,我们主要关注AWT,但在这个项目中,我被告知要学习swing 现在,我正在试验布局,将按键放置在正常键盘的正确位置。我真的需要你帮我把布局弄清楚。如果有人能解释并提供代码,那就太棒了。谢谢 代码:Java Swing-MIDI钢琴第一步,java,swing,Java,Swing,我只是在我创建这个项目的第一阶段,但我已经迷路了。在我的课堂上,我们主要关注AWT,但在这个项目中,我被告知要学习swing 现在,我正在试验布局,将按键放置在正常键盘的正确位置。我真的需要你帮我把布局弄清楚。如果有人能解释并提供代码,那就太棒了。谢谢 代码: 布局管理器实际上是为组件的二维定位而设计的 对于钢琴来说,您希望黑键位于白键之上,因此在这种情况下,您可能希望使用空布局,以便可以控制每个组件的位置。这意味着您现在负责设置每个组件的大小/位置 首先将黑键添加到面板,然后添加白键 我给你一
布局管理器实际上是为组件的二维定位而设计的 对于钢琴来说,您希望黑键位于白键之上,因此在这种情况下,您可能希望使用空布局,以便可以控制每个组件的位置。这意味着您现在负责设置每个组件的大小/位置 首先将黑键添加到面板,然后添加白键 我给你一点提示。您的主面板将如下所示:
JPanel contentPane = new JPanel(null)
{
@Override
public Dimension getPreferredSize()
{
int count = getComponentCount();
Component last = getComponent(count - 1);
Rectangle bounds = last.getBounds();
int width = 10 + bounds.x + bounds.width;
int height = 10 + bounds.y + bounds.height;
return new Dimension(width, height);
}
@Override
public boolean isOptimizedDrawingEnabled()
{
return false;
}
};
package experimental;
import static experimental.Experimental.KeyColor.BLACK;
import static experimental.Experimental.KeyColor.WHITE;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
class Experimental {
static final int WHITE_KEY_WIDTH = 48;
static final int WHITE_KEY_HEIGHT = 300;
static final int BLACK_KEY_WIDTH = 32;
static final int BLACK_KEY_HEIGHT = 210;
enum KeyColor { WHITE, BLACK };
enum PitchClass {
A("A", WHITE),
A_SHARP("A#", BLACK),
B("B", WHITE),
C("C", WHITE),
C_SHARP("C#", BLACK),
D("D", WHITE),
D_SHARP("D#", BLACK),
E("E", WHITE),
F("F", WHITE),
F_SHARP("F#", BLACK),
G("G", WHITE),
G_SHARP("G#", BLACK),
;
final String name;
final KeyColor color;
PitchClass(String name, KeyColor color) {
this.name = name;
this.color = color;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Keyboard");
JLayeredPane keyboard = new JLayeredPane();
frame.add(keyboard);
addKeys(keyboard);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(2000, 500);
frame.setVisible(true);
}
private void addKeys(JLayeredPane keyboard) {
int x = 0;
int keyCount = 0;
for (int octave = 1; ; ++octave) {
for (PitchClass note : PitchClass.values()) {
JButton key = new JButton(note.name);
key.setOpaque(true);
key.setActionCommand(String.format("%d/%s", octave, note.name));
if (note.color == WHITE) {
key.setBounds(x, 0, WHITE_KEY_WIDTH, WHITE_KEY_HEIGHT);
keyboard.add(key, new Integer(0));
x += WHITE_KEY_WIDTH;
} else {
key.setBounds(x - BLACK_KEY_WIDTH / 2, 0, BLACK_KEY_WIDTH, BLACK_KEY_HEIGHT);
keyboard.add(key, new Integer(1));
}
key.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
if (e.getButton() == 1) {
System.out.println("Press: "+ ((JButton) e.getSource()).getActionCommand());
}
}
@Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
if (e.getButton() == 1) {
System.out.println("Release: "+ ((JButton) e.getSource()).getActionCommand());
}
}
});
if (++keyCount == 40) return;
}
}
}
});
}
}
由于白键是最后添加的,因此面板上的最后一个组件将是白键。因此,该组件用于确定面板的首选尺寸,以适合所有白键
isOptimizedDrawingEnabled()
方法将被重写,因为组件将堆叠在另一个组件之上。这将确保黑键始终绘制在白键之上。实际上,JLayeredPane设计用于实现您想要的功能:按指定的z顺序重叠小部件。大概是这样的:
JPanel contentPane = new JPanel(null)
{
@Override
public Dimension getPreferredSize()
{
int count = getComponentCount();
Component last = getComponent(count - 1);
Rectangle bounds = last.getBounds();
int width = 10 + bounds.x + bounds.width;
int height = 10 + bounds.y + bounds.height;
return new Dimension(width, height);
}
@Override
public boolean isOptimizedDrawingEnabled()
{
return false;
}
};
package experimental;
import static experimental.Experimental.KeyColor.BLACK;
import static experimental.Experimental.KeyColor.WHITE;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
class Experimental {
static final int WHITE_KEY_WIDTH = 48;
static final int WHITE_KEY_HEIGHT = 300;
static final int BLACK_KEY_WIDTH = 32;
static final int BLACK_KEY_HEIGHT = 210;
enum KeyColor { WHITE, BLACK };
enum PitchClass {
A("A", WHITE),
A_SHARP("A#", BLACK),
B("B", WHITE),
C("C", WHITE),
C_SHARP("C#", BLACK),
D("D", WHITE),
D_SHARP("D#", BLACK),
E("E", WHITE),
F("F", WHITE),
F_SHARP("F#", BLACK),
G("G", WHITE),
G_SHARP("G#", BLACK),
;
final String name;
final KeyColor color;
PitchClass(String name, KeyColor color) {
this.name = name;
this.color = color;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Keyboard");
JLayeredPane keyboard = new JLayeredPane();
frame.add(keyboard);
addKeys(keyboard);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(2000, 500);
frame.setVisible(true);
}
private void addKeys(JLayeredPane keyboard) {
int x = 0;
int keyCount = 0;
for (int octave = 1; ; ++octave) {
for (PitchClass note : PitchClass.values()) {
JButton key = new JButton(note.name);
key.setOpaque(true);
key.setActionCommand(String.format("%d/%s", octave, note.name));
if (note.color == WHITE) {
key.setBounds(x, 0, WHITE_KEY_WIDTH, WHITE_KEY_HEIGHT);
keyboard.add(key, new Integer(0));
x += WHITE_KEY_WIDTH;
} else {
key.setBounds(x - BLACK_KEY_WIDTH / 2, 0, BLACK_KEY_WIDTH, BLACK_KEY_HEIGHT);
keyboard.add(key, new Integer(1));
}
key.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
if (e.getButton() == 1) {
System.out.println("Press: "+ ((JButton) e.getSource()).getActionCommand());
}
}
@Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
if (e.getButton() == 1) {
System.out.println("Release: "+ ((JButton) e.getSource()).getActionCommand());
}
}
});
if (++keyCount == 40) return;
}
}
}
});
}
}