椭圆形移动程序。椭圆不动,有啥我可以在这里炼制的吗?

Posted

技术标签:

【中文标题】椭圆形移动程序。椭圆不动,有啥我可以在这里炼制的吗?【英文标题】:Oval moving program. Oval not moving, anything I can refine here?椭圆形移动程序。椭圆不动,有什么我可以在这里炼制的吗? 【发布时间】:2019-05-12 22:34:44 【问题描述】:

我在这里需要一些关于我的代码的帮助。我完成了创建键盘事件的过程,如果我按下箭头键向下移动我的椭圆,如果我按下箭头键向上移动等等。但是,我一直无法这样做。有什么我可以从我的代码中改进的吗?还计划在两个按钮中实现它,右翻译左翻译按钮。

提前感谢您! Here is the example UI that I've made so far.

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class page309_4 extends JFrame  //implements ActionListener 
    private JButton btnLeftMvmt, btnRightMvmt;
    int oval_x = 150;
    int oval_y = 150;

    public page309_4()
        setTitle("Oval Mover");
        setSize(600, 150);
        setLayout(new BorderLayout());
        JPanel panel1, panel2;

        panel1 = new JPanel();
        panel2 = new JPanel();

        panel1.setSize(500,300);
        panel1.add(new MyPanel());
        panel1.addKeyListener(new KeyAdapter()
            public void keyPressed(KeyEvent e) 
            int keycode = e.getKeyCode();
            switch (keycode) 
            case KeyEvent.VK_UP:  oval_y += 10; break; 
            case KeyEvent.VK_DOWN: oval_y -= 10; break;
            case KeyEvent.VK_LEFT: oval_x -= 10; break;
            case KeyEvent.VK_RIGHT: oval_x += 10; break;
            
            
        );
        panel1.setBackground(Color.YELLOW);

        btnLeftMvmt = new JButton("Left Translation");
        btnRightMvmt = new JButton("Right Translation");
        btnLeftMvmt.addActionListener(bleft -> 


        );
        btnRightMvmt.addActionListener(bright -> 


        );


        panel2.add(btnLeftMvmt);
        panel2.add(btnRightMvmt);


        add(panel1);
        add(panel2, BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);

    

    class MyPanel extends JPanel 

        public MyPanel() 
            setPreferredSize(new Dimension(600, 150));
        

    @Override
    public void paintComponent(Graphics g) 
            super.paintComponents(g);
            g.setColor(Color.RED); 
            int oval_x = (getWidth() - 150) / 2;
            int oval_y = (getHeight() - 150) / 2;
            g.fillOval(oval_x, oval_y, 150, 150);
        
       

    public static void main (String[] args) 
        // TODO Auto-generated method stub
        page309_4 f = new page309_4();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    


【问题讨论】:

不要硬编码你的椭圆位置 椭圆的坐标应该由MyPanel 类维护。在KeyListener上使用key bindings api,它将解决焦点相关问题 【参考方案1】:

您不会在按键后重新绘制 panel1,因此您永远不会看到更改。要解决此问题,请在 keyPressed() 处理程序的末尾添加 panel1.repaint()。

【讨论】:

不会有所作为 这是问题的一部分,但需要进行更多更改才能使某些东西在这里起作用。【参考方案2】:

让我们从……开始吧

@Override
public void paintComponent(Graphics g) 
        super.paintComponents(g);
        g.setColor(Color.RED); 
        int oval_x = (getWidth() - 150) / 2;
        int oval_y = (getHeight() - 150) / 2;
        g.fillOval(oval_x, oval_y, 150, 150);
    
   

x/y 位置在方法中定义,因此无论您做什么,它都不会改变。

话虽如此,MyPanel 应该直接负责管理 x/y 位置,这意味着应该在其中定义 oval_xoval_y 变量。然后,您应该定义可以更改这些值的功能,例如...

  class MyPanel extends JPanel 

    private int oval_x = 150;
    private int oval_y = 150;

    public MyPanel() 
    

    @Override
    public Dimension getPreferredSize() 
      return new Dimension(600, 150);
    

    public void moveVerticallyBy(int delta) 
      oval_y += delta;
      repaint();
    

    public void moveHorizontallyBy(int delta) 
      oval_x += delta;
      repaint();
    

    @Override
    protected void paintComponent(Graphics g) 
      super.paintComponents(g);
      g.setColor(Color.RED);
      g.fillOval(oval_x, oval_y, 150, 150);
    
  

这是封装的基本概念

接下来,我强​​烈建议使用key bindings API 而不是KeyListener,因为它可以解决焦点相关的问题。

例如...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Page309_4 extends JFrame  //implements ActionListener 

  private JButton btnLeftMvmt, btnRightMvmt;
  private MyPanel myPanel;

  public Page309_4() 
    setTitle("Oval Mover");
    setSize(600, 150);
    setLayout(new BorderLayout());
    JPanel panel1, panel2;

    panel2 = new JPanel();

    myPanel = new MyPanel();
    InputMap im = myPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    ActionMap am = myPanel.getActionMap();

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

    am.put("Pressed.up", new VerticalMovementAction(-10, myPanel));
    am.put("Pressed.down", new VerticalMovementAction(10, myPanel));
    am.put("Pressed.left", new HorizontalMovementAction(-10, myPanel));
    am.put("Pressed.right", new HorizontalMovementAction(10, myPanel));

    btnLeftMvmt = new JButton("Left Translation");
    btnRightMvmt = new JButton("Right Translation");
    btnLeftMvmt.addActionListener(bleft -> 

    );
    btnRightMvmt.addActionListener(bright -> 

    );

    panel2.add(btnLeftMvmt);
    panel2.add(btnRightMvmt);

    add(myPanel);
    add(panel2, BorderLayout.SOUTH);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);

  

  public class VerticalMovementAction extends AbstractAction 

    private int delta;
    private MyPanel myPanel;

    public VerticalMovementAction(int delta, MyPanel myPanel) 
      this.delta = delta;
      this.myPanel = myPanel;
    

    @Override
    public void actionPerformed(ActionEvent e) 
      myPanel.moveVerticallyBy(delta);
    

  

  public class HorizontalMovementAction extends AbstractAction 

    private int delta;
    private MyPanel myPanel;

    public HorizontalMovementAction(int delta, MyPanel myPanel) 
      this.delta = delta;
      this.myPanel = myPanel;
    

    @Override
    public void actionPerformed(ActionEvent e) 
      myPanel.moveHorizontallyBy(delta);
    

  

  class MyPanel extends JPanel 

    private int oval_x = (600 - 150) / 2;
    private int oval_y = (300 - 150) / 2;

    public MyPanel() 
      setBackground(Color.YELLOW);
    

    @Override
    public Dimension getPreferredSize() 
      return new Dimension(600, 300);
    

    public void moveVerticallyBy(int delta) 
      oval_y += delta;
      repaint();
    

    public void moveHorizontallyBy(int delta) 
      oval_x += delta;
      repaint();
    

    @Override
    protected void paintComponent(Graphics g) 
      super.paintComponents(g);
      g.setColor(Color.RED);
      g.fillOval(oval_x, oval_y, 150, 150);
    
  

  public static void main(String[] args) 

    EventQueue.invokeLater(new Runnable() 
      @Override
      public void run() 
        // TODO Auto-generated method stub
        Page309_4 f = new Page309_4();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
    );
  

【讨论】:

非常感谢!我从来不知道键绑定 API,因为我的校园没有教授它。再次感谢您,对您有很大帮助!

以上是关于椭圆形移动程序。椭圆不动,有啥我可以在这里炼制的吗?的主要内容,如果未能解决你的问题,请参考以下文章

Arcgis中怎么画椭圆

C++抽象类

椭圆拟合过程中的椭圆倾角计算问题

计算给定球体上扭曲椭圆的偏移量

在 UWP 应用程序的椭圆元素中放置一个 BitmapIcon

在 C++ 中填充椭圆