Move JButton with keyboard Arrows inside a Grid Pa

2020-05-01 01:41发布

问题:

i want to make a JButton that can be moved with keyboard arrows inside a grid panel. Any ideas on how to make this happen ?

Here is what i have done so far, but it does not really works

button.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                int key = e.getKeyCode();
                System.out.println("KEY ^$$#$#$@#$  " + key);
                int position = 0;
                int previousPosition = 0;
                int counter = 0;

                position = Integer.parseInt(button.getName());
                int nextPosition = position;
                if (key == KeyEvent.VK_LEFT) {



                    nextPosition = nextPosition - 1;
                    previousPosition = position;
                    System.out.println("PREVIOUS POSITION: " + position);
                    bt[1].setVisible(false);
                    System.out.println("POSITION: " + position);
                    button.setName("" + nextPosition);
                    bt[nextPosition].add(button);
                }
                else if (key == KeyEvent.VK_DOWN) {
                    counter++;
                    if (counter == 1) {
                         nextPosition = nextPosition + 6;
                    }
                    else if (counter == 2) {
                         nextPosition = nextPosition + 12;
                    }
                    else {
                        nextPosition = 18;
                    }
                    System.out.println("next position:" + nextPosition);
                    System.out.println("counter: " + counter);
                    System.out.println("DOWN ARROW");

                    System.out.println("DOWN ARROW");
                    System.out.println("POSITION VALUE: " + nextPosition);
                    bt[previousPosition].setVisible(false);
                    System.out.println("POSITION: " + nextPosition);
                    button.setName("" + nextPosition);
                    bt[nextPosition].add(button);
                    System.out.println("end");
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }
    });

Thanks for your help

回答1:

Well, it depends.

I would, how ever, recommend using Key Bindings over KeyListener as it doesn't suffer from focus issues.

This basically use a GridLayout and simply changes the z-order of the button...

You could achieve something similar with GridBagLayout with a little more work, but which would result in more flexible layout

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
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.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class MoveButtons {

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

    public MoveButtons() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JButton button;

        public TestPane() {
            setLayout(new GridLayout(4, 4));
            button = new JButton("...");
            add(button);
            for (int index = 0; index < (4 * 4) - 1; index++) {
                JPanel panel = new JPanel();
                panel.setBorder(new LineBorder(Color.GRAY));
                add(panel);
            }

            requestFocus();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");

            am.put("left", new MoveAction(-1));
            am.put("right", new MoveAction(1));
            am.put("down", new MoveAction(4));
            am.put("up", new MoveAction(-4));
        }

        public class MoveAction extends AbstractAction {

            private int delta;

            public MoveAction(int delta) {
                this.delta = delta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                int index = getComponentZOrder(button);
                index += delta;
                if (index < 0) {
                    index = 0;
                } else if (index >= getComponentCount()) {
                    index  = getComponentCount() - 1;
                }
                setComponentZOrder(button, index);
                revalidate();
            }
        }
    }
}


回答2:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MoveButton extends JFrame {

JButton button;
JPanel[] p = new JPanel[100];
int k = 0;

public MoveButton() {
    super();
    button = new JButton("G");
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
                    requestFocusInWindow();
        }
    });
    JPanel panel = new JPanel(new GridLayout(10, 10));
    for (int i = 0; i < 100; i++) {
        p[i] = new JPanel(new BorderLayout());
        p[i].setBorder(BorderFactory.createLineBorder(Color.RED));
        panel.add(p[i]);
    }

    p[0].add(button);

    setFocusable(true);
    requestFocusInWindow();
    addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
            try {
                if (k <= 99 && k >= 0) {
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        if (k + 1 <= 99) {
                            p[++k].add(button);
                        }
                        repaint();
                    } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        if (k - 1 >= 0) {
                            p[--k].add(button);
                        }
                        repaint();
                    } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                        if (k - 10 >= 0) {
                            p[k -= 10].add(button);
                        }
                        repaint();
                    } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                        if (k + 10 <= 99) {
                            p[k += 10].add(button);
                        }
                        repaint();
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }

    });
    setSize(600, 600);
    add(panel);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

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