I am trying to create a virtual piano using java. i am having an issue with the layout however.
Here are the snippets which should be of interest:
The initialisation:
public class Piano extends JFrame implements KeyListener {
private PianoKeyboard keyboardPanel;
public Piano() {
super();
this.setTitle("Piano");
this.setName("Piano");
this.setSize(850,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
keyboardPanel = new PianoKeyboard(0);
keyboardPanel.addListener(this);
this.getContentPane().add(keyboardPanel);
this.setVisible(true);
}
}
The Layerd Pane:
public class PianoKeyboard extends JLayeredPane implements MouseListener{
public PianoKeyboard(int tempo){
super();
this.setEnabled(true);
this.setVisible(true);
createKeyboard();
}
privte void createKeyboard() {
setLayout(new GridLayout(25, 0));
int loc = 0;
for(int i = 0; i < 25; i++){
PianoKey k = new PianoKey(i+1,tempo);
k.addMouseListener(this);
if(i ==0){
k.setLocation(0);
}else{
if(PianoKey.isWhite(i+1) && PianoKey.isWhite(i)){
loc+=54;
}else if(PianoKey.isWhite(i+1) && !PianoKey.isWhite(i)){
loc+=15;
}else if(!PianoKey.isWhite(i+1) && PianoKey.isWhite(i)){
loc+=39;
}else if(!PianoKey.isWhite(i+1) && !PianoKey.isWhite(i)){
// impossible
}
k.setLocation(loc);
}
add(k,(PianoKey.isWhite(i+1))?new Integer(0):new Integer(1));
}
}
}
Here is the comonent for the individual key:
public class PianoKey extends JComponent {
public PianoKey(int pitch, int tempo) {
super();
this.pitch = pitch;
ClassLoader cl = this.getClass().getClassLoader();
try {
BufferedImage key;
if (isWhite(this.pitch)) {
key = ImageIO.read(cl.getResource(IMAGE_DIRECTORY
+ "/key/white.png"));
height = 150;
width = 54;
} else {
key = ImageIO.read(cl.getResource(IMAGE_DIRECTORY
+ "/key/black.png"));
height = 89;
width = 29;
}
Dimension sz = new Dimension(width, height);
System.out.println("Setting to: "+width+"; "+height);
setPreferredSize(sz);
setMinimumSize(sz);
setMaximumSize(sz);
setBounds(0,0,width,height);
setImage(key);
} catch (IOException e) {
Logger.getLogger(MusicNote.class).log(Level.WARNING,
"IO Error. Music Not duration. failed finding image");
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage key = (BufferedImage) getImage();
g.drawImage(key, offset, 0, width,height, null);
}
int offset = 0;
public void setLocation(int x){
offset = x;
setBounds(offset,0,width,height);
}
}
The y offset seems to be changing progressively and the height is completely wrong. the images have the following sizes: Black keys (29x89), White Keys (54x150)
If the gridlayout in the layered pane is removed, the notes i believe are all stacked on top of each other which makes only one note visible and clickable.
You're
GridLayout
is reversed. You haveThat will create 25 different lines. That's why your keys are "stepping down" - each are on a separate line
The above will give you one line with 25 columns