2010-11-25 2 views
5

저는 Java Swing에서 가상 피아노 유형 프로그램을 만들고 있습니다. 내 피아노 키 영역은 흰색 JButton을 흰색 키로 포함하는 가로형 BoxLayout이있는 JPanel입니다. 검정색 키를 추가하고 흰색 키가 겹치도록하고 싶습니다.JButton을 겹치게 만들기

내가 시도한 두 가지 접근 방식이 있습니다. 하나는 OverlayLayout을 사용하고 있습니다. 불행히도 OverlayLayout 관리자에게는 온라인 설명서가 많지 않으며 NetBeans GUI 빌더에서는 사용할 수 없습니다. 나는 그것이 작동하도록하는 방법을 알지 못합니다. 두 번째로 시도한 것은 JLayeredPanes를 사용하는 것입니다. 나는 Netbeans에서 그것을 뒤범벅 한 후에도 그 중 하나를 찾아 낼 수 없다.

제 질문은 꽤 간단하다고 생각합니다. 다른 JButton 위에 JButton을 추가하는 가장 좋은 방법은 무엇입니까? 또는 JButton을 피아노 키로 사용하는 다른 방법이 있습니까?

내가 함께 한

편집 aioobe의 내가 원하는 결과를 얻기 dacwe의 코드. 나는 기본적으로 aioobe의 기본 치수 (비트 확장)와 mod 7 파트를 사용하여 dacwe의 z- 순서를 사용했습니다. 또한 변수를 추가하여 더 명확하게했습니다. 이것은 내가 지금 가지고있는 것입니다.

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

감사합니다! 이제는 어떻게 든이 버튼에 리스너와 텍스트를 첨부해야합니다.

답변

5

사용자 정의 PianoLayoutManager을 작성하고 흰색 키보다 높은 z 순서로 검은 색 키를 배치합니다. Using Swing Components tutorial trail

주에서

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

:이 같은 구성 요소를 추가 할 수 있습니다 자신의 "제약"클래스를 만들기 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); 
    } 
} 

enter image description here

+0

구성 요소 z 주문이 엉망입니다! – dacwe

+0

생각하십니까? 나는 그것이 좋게 보인다라고 생각한다. .. :) – aioobe

+0

Ehhh, 그것 위에 컴파일되고, 움직이고, 움직이게된다. .. 그들이 re-rendered 할 때 틀린 순서로 버튼을 표현할 것이다. – dacwe

0

구라 레이아웃 위젯 중첩을 허용하며; 겹치는 범위를 사용하여 원하는 레이아웃을 구성 할 수 있습니다. 하지만 네, 자신의 레이아웃 매니저를 작성하는 것이 더 좋을 것입니다.

0

저는 Swing에서 몇 가지 게임을했는데, 레이아웃 관리자를 사용하거나 직접 만들지 않는 것이 더 쉽습니다. 예를 들어, 카드 게임과 카드가 재생 된 위치를보고 레이아웃과 현재 패널 크기에 따라 배치하는 사용자 정의 레이아웃 관리자가 있습니다.

1

레이아웃 관리자를 직접 작성하는 것 외에도 null LayoutManager (즉, 자동 레이아웃 관리가 필요 없음)를 사용하고 수동으로 키를 배치 할 수 있습니다. 그런 다음 컨테이너에 setComponentZOrder을 사용하여 검정색 키가 흰색 키 위에 나타나는지 확인하십시오.

+0

aioobe의 문제점을 어떻게 처리합니까? – dacwe

+0

흠, 1.6.0_22를 실행중인 OSX에서 Z 순서와 관련된 문제는 없습니다. – jackrabbit

3

이의 layeredPane의 예입니다 (이 예상대로 작동) : 그러나

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

, 당신은 (:)) 올바른 순서로 피아노 키를 배치해야합니다

alt text

+0

우수! 이것은 어리석은 질문처럼 보일지 모르겠지만 ActionListeners와 텍스트를 익명 JButton에 할당 할 수 있습니까? – aharlow

+0

다른 질문을 올리면 받아 들일 수 있습니다! ;) 네, 단지'b.addActionListener (새로운 ActionListener() {public void actionPerformed (ActionEvent ae) {/ * your code * /}}))'를 추가하십시오. – dacwe

0

posting에서 Darryl의 해결책 (마지막 답글)을 확인하십시오. 그것은 까다로워지며 "Button"을 검정색 버튼으로 사용하여 흰색 "JButton"위에 칠합니다. AWT와 Swing 컴퍼넌트를 혼재 할 수 있도록 (듯이)하는 JDK의 새로운 버젼에서는, 아마이 기능은 동작하지 않습니다.

그러나 깔끔한 부분은 실제로 클릭하면 소리가납니다.