Клавиши фортепиано не перекрываются и теперь не отображаются

Примечание: я работаю с jFugue.

public class Piano extends JFrame implements KeyListener {
    ArrayList<Keys> keys = new ArrayList<Keys>();
    Player playNote = new Player();

    public Piano() {
        drawGrid();
        this.addKeyListener(this);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
    }
    public void drawGrid() {
        pane = new JLayeredPane();
        this.setLayout(null);

        keys.add(new Key(new Rectangle(0, 0, 50, 300), new Pattern("V0 I[Piano] C5q"), Color.white));
        keys.add(new Key(new Rectangle(25, 0, 25, 180), new Pattern("V0 I[Piano] C#5q"), Color.white));
        keys.add(new Key(new Rectangle(50, 0, 50, 300), new Pattern("V0 I[Piano] D5q"), Color.white));
        keys.add(new Key(new Rectangle(75, 0, 25, 180), new Pattern("V0 I[Piano] D#5q"), Color.white));
        keys.add(new Key(new Rectangle(100, 0, 50, 300), new Pattern("V0 I[Piano] E5q"), Color.white));
        keys.add(new Key(new Rectangle(150, 0, 50, 300), new Pattern("V0 I[Piano] F5q"), Color.white));
        keys.add(new Key(new Rectangle(175, 0, 25, 180), new Pattern("V0 I[Piano] F#5q"), Color.white));
        keys.add(new Key(new Rectangle(200, 0, 50, 300), new Pattern("V0 I[Piano] G5q"), Color.white));
        keys.add(new Key(new Rectangle(225, 0, 25, 180), new Pattern("V0 I[Piano] G#5q"), Color.white));
        keys.add(new Key(new Rectangle(250, 0, 50, 300), new Pattern("V0 I[Piano] A5q"), Color.white));
        keys.add(new Key(new Rectangle(275, 0, 25, 180), new Pattern("V0 I[Piano] A#5q"), Color.white));
        keys.add(new Key(new Rectangle(300, 0, 50, 300), new Pattern("V0 I[Piano] B5q"), Color.white));

        this.add(keys.get(0));

        for (Key w: keys) {

            w.setBounds(w.getRectangle());
            this.getContentPane().add(w);

            w.addMouseListener(w);
            w.setPlayer(playNote);

        }

    }

    public static void main(String[] args) {
        Piano yamaha = new Piano();
        yamaha.setSize(1000, 500);
    }
}

Вот часть ключевого класса:

public class Key extends JLayeredPane implements MouseListener {
    Player player;
    Rectangle rectangle;
    Pattern pattern;
    Color color;

    public Key(Rectangle r, Pattern p, Color c) {
        rectangle = r;
        pattern = p;
        color = c;
    }

    public void paintComponent(Graphics g) {
        g.setColor(color);
        g.fillRect((int) rectangle.getX() - 1, (int) rectangle.getY() - 1, (int) rectangle.getWidth() - 1, (int) rectangle.getHeight() - 1);
        g.setColor(Color.BLACK);
        g.drawRect((int) rectangle.getX(), (int) rectangle.getY(), (int) rectangle.getWidth() - 1, (int) rectangle.getHeight() - 1);
        repaint();
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    public void setRectangle(Rectangle rectangle) {
        this.rectangle = rectangle;
    }
}

В рамке появится первая белая клавиша, а остальные нет. Я пробовал JLayeredPane, OverlayLayout, GridLayout и еще несколько.

Может ли кто-нибудь помочь мне с этим?


person Artemis    schedule 14.06.2016    source источник
comment
Я отредактировал ваш пост, удалил ненужную информацию и добавил тег Swing. Обратите внимание, что вы не должны использовать JLayeredPane для представления каждой клавиши, так как это работает в обратном порядке. Вместо этого рассмотрите возможность использования ОДНОЙ панели JLayeredPane и добавления к ней компонентов. Также не переопределяйте paintComponent JLayerdPane. Кроме того, если вы когда-либо переопределяете paintComponent в других своих компонентах, всегда вызывайте метод super и никогда не вызывайте repaint() из него. Прочтите руководства по Swing, так как они не подведут вас неправильно.   -  person Hovercraft Full Of Eels    schedule 15.06.2016


Ответы (1)


Если вы собираетесь рисовать на заказ, вам нужно просто переопределить метод paintComponent(...) для JPanel. Эта панель (не JFrame) должна содержать ваши "ключи" ArrayList. Затем метод paintComponent(...) будет перебирать ваш ArrayList «keys», чтобы нарисовать каждую клавишу пианино в нужном месте.

Посмотрите DrawOnComponent пример из Подходы к рисованию на заказ для пример такого подхода к живописи.

Затем для вашего кода MouseListener вы должны перебирать «ключи» ArrayList в обратном порядке, чтобы найти ключ, содержащий точку мыши. Таким образом, вы просто использовали бы метод Rectangle.contains(...), чтобы определить, какая клавиша была нажата.

Или другой подход заключается в добавлении на панель реальных компонентов Swing. Тогда вам не нужно выполнять какую-либо пользовательскую логику рисования или поиска, чтобы определить, какая клавиша была нажата. Все, о чем вам нужно беспокоиться, это расположение каждого компонента.

Для примера этого подхода ознакомьтесь с: для создания фортепиано с использованием JScrollPane и JLayeredPane

person camickr    schedule 14.06.2016