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

1

Я пытаюсь заставить кнопки менять цвет при нажатии. Я создал следующий код:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class KeyboardTest extends JFrame {

    public static void main(String[] args) {
        new KeyboardTest();
    }

public KeyboardTest() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch (Exception ex) {
                try {
                    UIManager.setLookAndFeel(UIManager
                            .getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
            }
            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            frame.setBounds(100, 100, 650, 390);
        }
    });

}

public class TestPane extends JPanel {

    public TestPane() {
        JPanel contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        add(contentPane);
        contentPane.setLayout(null);

        JPanel keyboardPanel = new JPanel();
        keyboardPanel.setBounds(10, 122, 614, 181);
        contentPane.add(keyboardPanel);
        keyboardPanel.setLayout(new GridLayout(5, 0, 0, 0));

        ... adding panels and buttons...

        addKeyBinding(A, "A", KeyEvent.VK_A);
        addKeyBinding(B, "B", KeyEvent.VK_B);
        addKeyBinding(C, "C", KeyEvent.VK_C);
        addKeyBinding(D, "D", KeyEvent.VK_D);
        addKeyBinding(E, "E", KeyEvent.VK_E);

    }

    protected void addKeyBinding(JButton btn, String name, int virtualKey) {
        ActionMap am = getActionMap();
        InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);

        im.put(KeyStroke.getKeyStroke(virtualKey, 0, false), name
                + ".pressed");
        im.put(KeyStroke.getKeyStroke(virtualKey, 0, true), name
                + ".released");

        am.put(name + ".pressed", new KeyAction(btn, true));
        am.put(name + ".released", new KeyAction(btn, false));
    }

}

public class KeyAction extends AbstractAction {

    private JButton btn;
    private boolean highlight;

    public KeyAction(JButton btn, boolean highlight) {
        this.btn = btn;
        this.highlight = highlight;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (highlight) {
            btn.getModel().setPressed(true);
            btn.setBackground(Color.RED);
            btn.setOpaque(true);
        } else {
            btn.getModel().setPressed(false);
            btn.setBackground(null);
            btn.setOpaque(false);
        }
    }

}

}

Вот как он должен выглядеть:

Изображение 174551

Вот что на самом деле появляется:

Изображение 174551

Должен ли я прикреплять полный код? (это довольно долго...)

  • 0
    Избавиться от нулевого макета
  • 0
    Все появляется, но совершенно неорганизованно
Показать ещё 3 комментария
Теги:
swing
jpanel
jframe
jbutton

1 ответ

1
Лучший ответ

Не удается проверить ваш код (из-за недостающих компонентов). И я не буду о вас знать о нулевой макете. Но вот проблема и решение, основанное на том, что я смог проверить (используя собственные компоненты).

  • Я вижу бесполезную JPanel contentPane. Класс, который вы используете, уже является панелью, я не вижу смысла создавать другую, а затем переношу ее в другую. (Не вся проблема, хотя)

  • Класс TestPane имеет FlowLayout по умолчанию, что означает, что он будет contentPane предпочтительный размер компонентов внутри, который является панелью contentPane. Проблема в том, что он не будет иметь нужного размера. Вы устанавливаете размеры кнопок с помощью setBounds. Это не то же самое, что и preferredSize. Таким образом, для панели TestPane нет предпочтительного размера.

  • Простое исправление - установить макет TestPane на BorderLayout. Это не учитывает предпочтительный размер и растягивает ContentPane, чтобы вы могли его увидеть. Проблема с этим заключается в том, что вам нужно установить размер фрейма. pack() не будет работать, потому что весь предпочтительный размер сделки. Вот почему вы разорваетесь, когда вы его сначала открываете, потому что он сначала сокращается, а затем вы расширяете его с помощью setBounds.

Опять же, как я сказал, хотя в своем комментарии я бы держался подальше от нулевых макетов (по многим причинам). Вы можете увидеть хороший пример клавиатуры, используя GridBagLayout здесь, как опубликовано в моем комментарии, от самого безумного человека @MadProgrammer

Ещё вопросы

Сообщество Overcoder
Наверх
Меню