2010-11-25 2 views
5

Я создаю виртуальную программу типа пианино в Java Swing. Моя область для клавиш фортепиано прямо сейчас - JPanel с горизонтальным BoxLayout, содержащим белые JButtons в виде белых клавиш. Я хочу также добавить черные клавиши и наложить их на белые клавиши.Создание перекрытия JButtons

Есть два разных подхода, которые я пробовал. Один использует OverlayLayout. К сожалению, для менеджера OverlayLayout документации для документации недостаточно, и она недоступна в построителе GUI NetBeans. Я не знаю, как заставить его работать. Во-вторых, я пытался использовать JLayeredPanes. Кажется, я тоже не могу понять, что это произошло, даже после того, как он возился с ним в Netbeans.

Так что я думаю, что мой вопрос довольно прост. Каков наилучший подход, если он есть, добавить JButtons поверх других JButtons? Или, может быть, есть альтернатива использованию JButtons для клавиш фортепиано?

EDIT

Я объединил aioobe и коде dacwe, чтобы получить результат, я хотел. Я в основном использовал z-порядок dacwe с основными размерами aioobe (немного увеличен) и частью мода 7. Я также добавил некоторые переменные, чтобы сделать вещи более ясными. Это то, что у меня есть сейчас.

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-порядком, чем белые кнопки. Создайте свой собственный класс «ограничение», что позволяет добавлять компоненты, как это:

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

От Using Swing Components tutorial trail

Примечание: 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 2010-11-25 19:58:46

+0

вы думаете? Я думаю, он выглядит хорошо ... :) – aioobe 2010-11-25 19:59:15

+0

Ehhh, скомпилирован и запущен и перемещен над ним ... он отобразит кнопки в неправильном порядке, когда они будут повторно отображены. – dacwe 2010-11-25 20:01:48

0

компоновка GridBag действительно позволяет виджет перекрытия; Вы можете использовать перекрывающиеся промежутки для построения макета, который вы хотите. Но да, писать собственный менеджер компоновки будет лучше.

0

Я провел пару игр в Swing, и мне легче просто не использовать диспетчер компоновки или сделать свой собственный. Например, у меня есть карточная игра и пользовательский менеджер макетов, который смотрит, где была сыграна карта, и позиционирует ее на основе этого и текущего размера панели.

1

Помимо написания собственного менеджера макетов, вы можете просто использовать макет LayoutManager (то есть автоматическое управление макетами) и вручную поместить ключи. Затем используйте контейнер setComponentZOrder, чтобы убедиться, что черные клавиши отображаются над белыми.

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

Проверьте решение Darryl (последний ответ) в этом posting. Он становится сложным и использует «Button» в качестве черной кнопки, поэтому он рисует поверх белого «JButton». Вероятно, это не сработает в новых версиях JDK, которые позволяют смешивать компоненты AWT и Swing.

Однако аккуратная часть состоит в том, что клавиши на самом деле создают звук при нажатии.

Смежные вопросы