Reputation: 4156
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.
Upvotes: 0
Views: 1052
Reputation: 209002
You're GridLayout
is reversed. You have
setLayout(new GridLayout(25, 0));
That will create 25 different lines. That's why your keys are "stepping down" - each are on a separate line
setLayout(new GridLayout(1, 25));
The above will give you one line with 25 columns
Upvotes: 2