Java Swing - MIDI钢琴的第一步

时间:2017-08-22 01:54:16

标签: java swing

我只是在创建这个项目的第一阶段,但我已经迷失了。在我的课堂上,我们主要关注AWT,但是对于这个项目,我被告知要学习挥杆。

现在我正在尝试使用Layouts将键定位在正常位置,就像普通键盘一样。我真的需要帮助我的布局。如果有人可以解释并提供非常棒的代码。感谢

代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class main extends JFrame implements ActionListener
{
private JButton a1,a1s,b1,c1,c1s,d1,d1s,e1,f1,f1s,g1,g1s;
private JPanel panel;
private int x_pos = 50;
String title = "INTERACTIVE PIANO";    


private void createGUI()
{
  setDefaultCloseOperation(EXIT_ON_CLOSE);
  Container window = getContentPane();
  window.setLayout(new FlowLayout() );

  /*  panel = new JPanel();   
  panel.setPreferredSize(new Dimension(800, 700));
  panel.setBackground(Color.white);
  panel.setLayout(null);
  panel.setBackground(Color.gray);
  window.add(panel); */
  addKeys(); 
  }

  public void addKeys()
  {
    a1 = new JButton("A"); 
    {
      a1.setBackground(Color.white);
      a1.setPreferredSize(new Dimension(50, 150));
      a1.setLayout(null);
      a1.addActionListener(this);
      add(a1);

    } 


    a1s = new JButton("A#");
    {
      a1s.setBackground(Color.black);
      a1s.setPreferredSize(new Dimension(50, 100));
      a1s.setLayout(null);
      a1s.addActionListener(this);
      add(a1s);
    } 


    b1 = new JButton("B"); 
    {
      b1.setBackground(Color.white);
      b1.setPreferredSize(new Dimension(50, 150));
      b1.setLayout(null);
      b1.addActionListener(this);
      add(b1);
    }  

    c1 = new JButton("C"); 
    {
      c1.setBackground(Color.white);
      c1.setPreferredSize(new Dimension(50, 150));
      c1.setLayout(null);
      c1.addActionListener(this);
      add(c1);
    }  

    c1s = new JButton("C#");
    {
      c1s.setBackground(Color.black);
      c1s.setPreferredSize(new Dimension(50, 100));
      c1s.setLayout(null);
      c1s.addActionListener(this);
      add(c1s);
    } 

    d1 = new JButton("D"); 
    {
      d1.setBackground(Color.white);
      d1.setPreferredSize(new Dimension(50, 150));
      d1.setLayout(null);
      d1.addActionListener(this);
      add(d1);
    }  

    d1s = new JButton("D#");
    {
      d1s.setBackground(Color.black);
      d1s.setPreferredSize(new Dimension(50, 100));
      d1s.setLayout(null);
      d1s.addActionListener(this);
      add(d1s);
    } 

    e1 = new JButton("E"); 
    {
      e1.setBackground(Color.white);
      e1.setPreferredSize(new Dimension(50, 150));
      e1.setLayout(null);
      e1.addActionListener(this);
      add(e1);
    } 

    f1 = new JButton("F"); 
    {
      f1.setBackground(Color.white);
      f1.setPreferredSize(new Dimension(50, 150));
      f1.setLayout(null);
      f1.addActionListener(this);
      add(f1);
    }  

    f1s = new JButton("F#");
     {
      f1s.setBackground(Color.black);
      f1s.setPreferredSize(new Dimension(50, 100));
      f1s.setLayout(null);
      f1s.addActionListener(this);
      add(f1s);
    }  

    g1 = new JButton("G"); 
    {
      g1.setBackground(Color.white);
      g1.setPreferredSize(new Dimension(50, 150));
      g1.setLayout(null);
      g1.addActionListener(this);
      add(g1);
    }  

    g1s = new JButton("G#");
    {
      g1s.setBackground(Color.black);
      g1s.setPreferredSize(new Dimension(50, 100));
      g1s.setLayout(null);
      g1s.addActionListener(this);
      add(g1s);
    }  

 }
  public void actionPerformed(ActionEvent event)
  {
   //  Graphics paper = panel.getGraphics(); 
   if (event.getSource() == a1)
   {

   }


  } 
 public static void main(String[] args)
 {
  main frame = new main();
  frame.setTitle("Interactive Piano v1.0");
  frame.setSize(800, 700);
  frame.setMinimumSize(new Dimension(800, 700));
  frame.createGUI();
  frame.setVisible(true);
  frame.setLayout(null);
 }
}

2 个答案:

答案 0 :(得分:1)

布局管理器实际上是为组件的二维定位而设计的。

对于钢琴,您需要白键顶部的黑键,因此您可能希望使用空布局,以便控制每个组件的位置。这意味着您现在负责设置每个组件的大小/位置。

首先将黑键添加到面板,然后添加白键。

我会给你一点提示。您的主面板看起来像这样:

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;
    }
};

由于最后添加了白键,因此面板上的最后一个组件将是白键。因此,此组件用于确定面板的首选大小以适合所有白键。

覆盖isOptimizedDrawingEnabled()方法,因为组件将堆叠在一起。这将确保黑键始终涂在白键的顶部。

答案 1 :(得分:1)

实际上,JLayeredPane旨在满足您的需求:使用规定的z顺序重叠小部件。像这样:

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;
          }
        }
      }
    });
  }
}