Java使用箭头键在gui中移动圆圈
我试图用一个keyEvent向左移动一个圆。到目前为止,圆圈是在窗口上绘制的,但它不会向左移动!我觉得问题在于如何将Window()构造函数添加到容器中。控制台上没有输出来告诉我它正在工作。所以我认为它甚至没有达到KeyEvent类。这是我的密码:Java使用箭头键在gui中移动圆圈,java,swing,user-interface,graphics2d,keyevent,Java,Swing,User Interface,Graphics2d,Keyevent,我试图用一个keyEvent向左移动一个圆。到目前为止,圆圈是在窗口上绘制的,但它不会向左移动!我觉得问题在于如何将Window()构造函数添加到容器中。控制台上没有输出来告诉我它正在工作。所以我认为它甚至没有达到KeyEvent类。这是我的密码: import java.awt.*; import java.awt.event.*; import java.awt.geom.Ellipse2D; import javax.swing.*; public class Window exten
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Window extends JPanel {
private static Ellipse2D.Double circle;
public Window() {
super();
int width = 400;
int height = 400;
circle = new Ellipse2D.Double(0.5 * width, 0.9 * height,
0.1 * width, 0.05 * height);
addKeyListener(new MoveCircle());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D brush = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g.clearRect(0, 0, width, height);
brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
brush.draw(circle);
}
public class MoveCircle implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Working on top!");
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Working on bottom!");
circle.x++;
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
public static void main(String[] args) {
Window window = new Window();
JFrame frame = new JFrame();
Container container = frame.getContentPane();
container.add(new Window());
frame.addKeyEvent(window.new MoveCircle());
frame.setSize(800, 700);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
只有聚焦组件才会获得关键事件。您需要在某个时候调用requestFocus()。只有聚焦的组件才会获得关键事件。您需要在某个时候调用requestFocus()。解决方案是将KeyListener添加到JFrame。这样,当JFrame具有焦点时,所有的击键都将抛出一个事件。解决方案是将KeyListener添加到JFrame。这样,当JFrame具有焦点时,所有按键都将抛出一个事件。实际上发生的是,您正在将
窗口添加到JFrame
,但焦点在于JFrame
,因此,当您在键盘上键入时,会转到JFrame
而不是keylister
附加到窗口的类。因此,为了克服它,只需在窗口
类的对象上调用requestFocusInWindow()
。试试这段代码,我对EDT和其他东西做了一些修改
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Window extends JPanel {
private static Ellipse2D.Double circle;
private JFrame frame;
public Window() {
super();
int width = 400;
int height = 400;
circle = new Ellipse2D.Double(0.5 * width, 0.9 * height,
0.1 * width, 0.05 * height);
}
public Dimension getPreferredSize()
{
return (new Dimension(frame.getWidth(), frame.getHeight()));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D brush = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g.clearRect(0, 0, width, height);
brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
brush.draw(circle);
}
public class MoveCircle implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Working on top!");
if (e.getKeyCode() == Event.ENTER) {
System.out.println("Working on bottom!");
double newX = circle.x - 1;
circle.x = newX;
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
private void createAndDisplayGUI(Window window)
{
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
window.addKeyListener(new MoveCircle());
frame.setSize(800, 700);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
window.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Window window = new Window();
window.createAndDisplayGUI(window);
}
});
}
}
实际上,您正在将窗口
添加到JFrame
,但重点在于JFrame
,因此当您在键盘
上键入内容时,它会转到JFrame
而不是窗口
类附带的按键侦听器
。因此,为了克服它,只需在窗口
类的对象上调用requestFocusInWindow()
。试试这段代码,我对EDT和其他东西做了一些修改
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Window extends JPanel {
private static Ellipse2D.Double circle;
private JFrame frame;
public Window() {
super();
int width = 400;
int height = 400;
circle = new Ellipse2D.Double(0.5 * width, 0.9 * height,
0.1 * width, 0.05 * height);
}
public Dimension getPreferredSize()
{
return (new Dimension(frame.getWidth(), frame.getHeight()));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D brush = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g.clearRect(0, 0, width, height);
brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
brush.draw(circle);
}
public class MoveCircle implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Working on top!");
if (e.getKeyCode() == Event.ENTER) {
System.out.println("Working on bottom!");
double newX = circle.x - 1;
circle.x = newX;
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
private void createAndDisplayGUI(Window window)
{
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
window.addKeyListener(new MoveCircle());
frame.setSize(800, 700);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
window.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Window window = new Window();
window.createAndDisplayGUI(window);
}
});
}
}
您是指frame.addKeyListeners(new MoveCircle());在main方法中?是的,这就是我的意思,但这可能不起作用,因为MoveCircle()只能从窗口调用。所以我的解决方案是:windowwindow=newwindow();容器。添加(窗口);frame.addKeyListener(window.new MoveCircle())代码>和是System.out.prints(…);执行?或者在JFrame上按Enter键时控制台是空的?您是指frame.addKeyListeners(new MoveCircle());在main方法中?是的,这就是我的意思,但这可能不起作用,因为MoveCircle()只能从窗口调用。所以我的解决方案是:windowwindow=newwindow();容器。添加(窗口);frame.addKeyListener(window.new MoveCircle())代码>和是System.out.prints(…);执行?或者当按下JFrame上的Enter键时控制台是空的?我修改了它,使它现在可以正常工作,圆圈现在可以左右移动。但是我试着做一些事情,比如newX=circle.x+5.0;这是什么也不做,唯一让圆移动的方法是circle.x++;我不喜欢它移动得有多慢…?你试过使用circle.x+=5代码>而不是newX=circle.x+5.0代码>?啊,是的,谢谢。我不知道为什么它不接受新的任务。你挽救了这一天,现在我将继续我的比赛。谢谢你,先生!呵呵,欢迎你,保持微笑:-),答案是当你写circle.x+=5时
您正在递增circle
对象的变量x
,否则必须写入circle.x=newX代码>使之工作:-)好例子;另请参见使用键绑定来避免问题的方法。我对其进行了修改,使其现在可以正常工作,圆圈现在可以左右移动。但是我试着做一些事情,比如newX=circle.x+5.0;这是什么也不做,唯一让圆移动的方法是circle.x++;我不喜欢它移动得有多慢…?你试过使用circle.x+=5代码>而不是newX=circle.x+5.0代码>?啊,是的,谢谢。我不知道为什么它不接受新的任务。你挽救了这一天,现在我将继续我的比赛。谢谢你,先生!呵呵,欢迎你,保持微笑:-),答案是当你写circle.x+=5时
您正在递增circle
对象的变量x
,否则必须写入circle.x=newX代码>使之工作:-)好例子;另请参见使用键绑定来避免问题的方法。