EventListner 在 Swing 中不起作用

问题描述 投票:0回答:1
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


class MainWindow extends JFrame implements KeyListener, ChangeListener {

    JLabel j;
    JLabel s1;
    int speed;
    JSlider s;
    MainWindow(){
        this.setVisible(true);
        this.setSize(500, 500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Todo Application");
        this.setLayout(null);
        this.addKeyListener(this);



        s = new JSlider(0,25,10);
        s.setLocation(50, 10);
        s.setSize(400, 100);
        s.addChangeListener(this);
        this.add(s);

        speed=s.getValue();

        s1 = new JLabel();
        s1.setText("Speed: " + speed);
        s1.setLocation(200, 50);
        s1.setSize(100,100);
        this.add(s1);

        j = new JLabel();
        j.setSize(100, 100);
        j.setBackground(Color.red);
        j.setOpaque(true);
        j.setLocation(200, 200);
        this.add(j);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyChar()) {
            case 'w' -> j.setLocation(j.getX(), j.getY() - speed);
            case 'd' -> j.setLocation(j.getX() + speed, j.getY());
            case 's' -> j.setLocation(j.getX(), j.getY() + speed);
            case 'a' -> j.setLocation(j.getX() - speed, j.getY());
            default -> System.out.println(speed);
        }
        System.out.println(e.getKeyChar());
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void stateChanged(ChangeEvent e) {
        speed = s.getValue();
        s1.setText("Speed: " + speed);
    }
}
public class Main {
    public static void main(String[] args) {
        new MainWindow();
    }
}

当我独立使用 keyPressEvent 和 ChnageEvent 时它可以工作,但是当我将两者结合起来时它就不起作用了。即使默认速度为 10,标签也不会移动,并且显示速度的标签根本不会出现。

java swing user-interface awt
1个回答
0
投票

我修改了您发布的代码以获得以下 GUI。

Oracle 有一个有用的教程,使用 Swing 创建 GUI。跳过使用 NetBeans IDE 学习 Swing 部分。

所有 Swing 应用程序都必须以调用

SwingUtilities

 
invokeLater
 方法开始。此方法确保 Swing 组件在 
Event Dispatch Thread 上创建并执行。

Swing 有一个漂亮的容器,称为

JPanel

。我为 
JPanel
 和速度 
JSlider
 创建了一个控件 
JLabel
。我为移动的
JPanel
创建了一个可移动的
JLabel
。通过创建两个 
JPanels
,我分离了我的关注点,并且能够一次专注于 GUI 的一部分。

我必须使用按键绑定而不是

KeyListener

,因为我无法将注意力集中在可移动的
JPanel
上。

这是完整的可运行代码。

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.InputMap; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class SpeedDisplay implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new SpeedDisplay()); } private int speed, x, y; private JLabel speedLabel, square; public SpeedDisplay() { this.speed = 10; this.x = 150; this.y = 150; } @Override public void run() { JFrame frame = new JFrame("Todo Application"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(createControlPanel(), BorderLayout.NORTH); frame.add(createMoveablePanel(), BorderLayout.CENTER); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } private JPanel createControlPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JSlider slider = new JSlider(0, 25, speed); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent event) { speed = slider.getValue(); speedLabel.setText("Speed: " + speed); } }); panel.add(slider, BorderLayout.NORTH); speedLabel = new JLabel(); speedLabel.setText("Speed: " + speed); panel.add(speedLabel, BorderLayout.SOUTH); return panel; } private JPanel createMoveablePanel() { JPanel panel = new JPanel(null); panel.setPreferredSize(new Dimension(400, 400)); createKeyBindings(panel); square = new JLabel(); square.setSize(100, 100); square.setBackground(Color.red); square.setOpaque(true); square.setLocation(x, y); panel.add(square); return panel; } private void createKeyBindings(JPanel panel) { InputMap inputMap = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = panel.getActionMap(); inputMap.put(KeyStroke.getKeyStroke("W"), "up"); inputMap.put(KeyStroke.getKeyStroke("S"), "down"); inputMap.put(KeyStroke.getKeyStroke("A"), "left"); inputMap.put(KeyStroke.getKeyStroke("D"), "right"); actionMap.put("up", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { y -= speed; square.setLocation(x, y); } }); actionMap.put("down", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { y += speed; square.setLocation(x, y); } }); actionMap.put("left", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { x -= speed; square.setLocation(x, y); } }); actionMap.put("right", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { x += speed; square.setLocation(x, y); } }); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.