【问题标题】:Java on screen virtual joystick controlJava 屏幕虚拟操纵杆控制
【发布时间】:2013-05-08 11:35:48
【问题描述】:

我需要一个屏幕虚拟操纵杆解决方案来控制外部设备 - 购物车。我的程序是用 Java/Swing 编写的,它可以在带有电阻式触摸屏的 Windows 坚固型平板电脑上运行。 Swing 中没有 x-y 滑块控件,无法通过 Google 找到它,所以可能我需要从头开始编写它。现在的问题是:编写此类控件的最佳方法是什么?我正在考虑放置两个 JSlider 控件,一个是水平的,第二个是垂直的,并制作自定义拇指,但我担心这会给我带来麻烦,因为它实际上是一个 hack。也许只是从头开始写?也许有一个现有的解决方案? 我将通过拇指拖动和触摸最终拇指位置来使用它。

【问题讨论】:

  • 我已经将这里的一些答案编译成一个可在此处查看的插入式组件:github.com/shanescarlett/JStick 复制组件文件或添加 Maven 依赖项,希望它可以避免某人的乏味。

标签: java swing touch 2d joystick


【解决方案1】:

例如

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleJoystickDemo extends JFrame {

    //I think that orginally made by @HFOE    

    private int displayWidth = 340;
    private int displayHeight = 550;
    private final Point position;

    public SimpleJoystickDemo() {
        super("SimpleJoystickDemo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(displayWidth, displayHeight);
        setLocationRelativeTo(null);
        position = new Point();
        SimpleJoystick myJoystick = new SimpleJoystick(150, position, 100);
        add(myJoystick, BorderLayout.PAGE_END);
        Drawing drawing = new Drawing(position);
        add(drawing);
    }

    public static void main(final String[] args) {
        Runnable gui = new Runnable() {
            @Override
            public void run() {
                new SimpleJoystickDemo().setVisible(true);
            }
        };
        SwingUtilities.invokeLater(gui);
    }

    private class Drawing extends JPanel {

        private static final long serialVersionUID = 1L;
        private final Point position;

        public Drawing(Point position) {
            this.position = position;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.RED);
            g2.fillOval(160 + position.x, 160 - position.y, 15, 15);
        }
    }
}

class SimpleJoystick extends JPanel {

    private static final long serialVersionUID = 1L;
    //Maximum value for full horiz or vert position where centered is 0:
    private int joyOutputRange;
    private float joySize;     //joystick icon size
    private float joyWidth, joyHeight;
    private float joyCenterX, joyCenterY;  //Joystick displayed Center
    //Display positions for text feedback values:
    private int textHorizPos, textVertPos;
    private int fontSpace = 12;
    private float curJoyAngle;    //Current joystick angle
    private float curJoySize;     //Current joystick size
    private boolean isMouseTracking;
    private boolean leftMouseButton;
    private int mouseX, mouseY;
    private Stroke lineStroke = new BasicStroke(10, BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND);
    private final Point position;

    public SimpleJoystick(final int joyOutputRange,
            final Point position, final int joySize) {
        this.joyOutputRange = joyOutputRange;
        this.position = position;
        this.joySize = joySize;
        joyWidth = joySize;
        joyHeight = joyWidth;
        setPreferredSize(new Dimension((int) joyWidth + 250,
                (int) joyHeight + 80));
        joyCenterX = getPreferredSize().width / 2;
        joyCenterY = getPreferredSize().height / 2;
        this.joySize = joyWidth / 2;
        setBackground(new Color(226, 226, 226));
        MouseAdapter mouseAdapter = new MouseAdapter() {
            @Override
            public void mouseMoved(final MouseEvent e) {
                mouseCheck(e);
            }

            @Override
            public void mousePressed(final MouseEvent e) {
                leftMouseButton = SwingUtilities.isLeftMouseButton(e);
                mouseCheck(e);
            }
        };
        addMouseMotionListener(mouseAdapter);
        addMouseListener(mouseAdapter);
    }

    private void mouseCheck(final MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
        float dx = mouseX - joyCenterX;
        float dy = mouseY - joyCenterY;
        if (leftMouseButton) {
            isMouseTracking = true;
        } else {
            isMouseTracking = false;
        }
        if (isMouseTracking) {
            curJoyAngle = (float) Math.atan2(dy, dx);
            curJoySize = (float) Point.distance(mouseX, mouseY,
                    joyCenterX, joyCenterY);
        } else {
            curJoySize = 0;
        }
        if (curJoySize > joySize) {
            curJoySize = joySize;
        }
        position.x = (int) (joyOutputRange * (Math.cos(curJoyAngle)
                * curJoySize) / joySize);
        position.y = (int) (joyOutputRange * (-(Math.sin(curJoyAngle)
                * curJoySize) / joySize));
        SwingUtilities.getRoot(SimpleJoystick.this).repaint();
    }

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.LIGHT_GRAY);
        g2.fillOval((int) (joyCenterX - joyWidth / 2),
                (int) (joyCenterY - joyHeight / 2),
                (int) joyWidth, (int) joyHeight);
        //rotate and draw joystick line segment:
        Graphics2D g3 = (Graphics2D) g2.create();
        g3.translate(joyCenterX, joyCenterY);
        g3.rotate(curJoyAngle);
        g3.setColor(Color.GRAY);
        g3.setStroke(lineStroke);
        g3.drawLine(0, 0, (int) curJoySize, 0);
        g3.dispose();
        //
        g2.setColor(Color.GRAY);
        g2.fillOval((int) joyCenterX - 10, (int) joyCenterY - 10, 20, 20);
        textHorizPos = 50;
        textVertPos = (int) (joyCenterY - 50);
        g2.drawString("Horizont:", textHorizPos, textVertPos);
        textHorizPos += (4 * fontSpace);
        g2.drawString(String.valueOf(position.x), textHorizPos, textVertPos);
        textHorizPos = 50;
        textVertPos += 12;
        g2.drawString("Vertical :", textHorizPos, textVertPos);
        textHorizPos += (4 * fontSpace);
        g2.drawString(String.valueOf(position.y), textHorizPos, textVertPos);
    }
}

【讨论】:

    【解决方案2】:

    来自@tutejszy 的重新编写的代码。删除了警告并添加了缺少的 PointChangeEvent。

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public class VJoystick extends JPanel implements ChangeListener 
    {    
        private JLabel lblPosition;
        private static final long serialVersionUID = 1L;
        public VJoystick() 
        {
            setLayout(new BorderLayout(0, 0));
            SimpleJoystick myJoystick = new SimpleJoystick(150);
            myJoystick.setPreferredSize(new Dimension(100,100));
            myJoystick.addChangeListener(this);
            add(myJoystick, BorderLayout.CENTER);
    
            lblPosition = new JLabel("position");
            add(lblPosition, BorderLayout.SOUTH);
        }
    
        @Override
        public void stateChanged(ChangeEvent ev) {
            Point p = null;
            try {
                p = ((PointChangeEvent)ev).p;
            } catch (Exception e) {
                return;
            }
            lblPosition.setText("x="+p.x+" y="+p.y);
        }
    }
    
    class SimpleJoystick extends JPanel 
    {
        private static final long serialVersionUID = 1L;
        /** Maximum value for full horiz or vert position where centered is 0 */
        private int joyOutputRange;
        /** max x and y value, in pixels */
        private int joyRadius; 
        /** Joystick displayed Center, in pixels */
        private int joyCenterX, joyCenterY; 
        /** joystick output position scaled to given joyOutputRange */
        private Point position = new Point();
        /** joystick x axis value in pixels */
        private int dx = 0;
        /** joystick y axis value in pixels */
        private int dy = 0;
    
        /**
         * @param joyOutputRange
         */
        public SimpleJoystick(final int joyOutputRange) {
            this.joyOutputRange = joyOutputRange;
            setBackground(new Color(226, 226, 226));
            MouseAdapter mouseAdapter = new MouseAdapter() {
    
                @Override
                public void mousePressed(final MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e) && cursorChanged(e.getX(), e.getY())) {
                        SwingUtilities.getRoot(SimpleJoystick.this).repaint();
                        fireStateChanged();
                    }
                }
    
                @Override
                public void mouseDragged(MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e) && cursorChanged(e.getX(), e.getY())) {
                        SwingUtilities.getRoot(SimpleJoystick.this).repaint();
                        fireStateChanged();
                    }
                }
            };
            addMouseMotionListener(mouseAdapter);
            addMouseListener(mouseAdapter);
        }
    
        private boolean cursorChanged(int mouseX, int mouseY) {
            if (joyRadius == 0) return false;
    
            dx = mouseX - joyCenterX;
            dy = mouseY - joyCenterY;
            if (dx > joyRadius) dx = joyRadius;
            if (dy > joyRadius) dy = joyRadius;
            if (dx < -joyRadius) dx = -joyRadius;
            if (dy < -joyRadius) dy = -joyRadius;
    
            position.x = joyOutputRange * dx / joyRadius;
            position.y = -joyOutputRange * dy / joyRadius;
    
            return true;
        }
    
        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            int joyWidth = getSize().width;
            int joyHeight = getSize().height;
            joyRadius = Math.min(joyWidth, joyHeight) / 2;
            if (joyRadius == 0) return;
    
            joyCenterX = joyWidth / 2;
            joyCenterY = joyHeight / 2;
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
            int diameter; 
    
            //background
            g2.setColor(Color.LIGHT_GRAY);
            diameter = joyRadius*2;
            g2.fillOval(joyCenterX - diameter/2 , joyCenterY - diameter/2, diameter, diameter);
    
            g2.setColor(Color.RED);
            diameter = 40;
            g2.fillOval(joyCenterX + dx - diameter/2 , joyCenterY + dy - diameter/2, diameter, diameter);
    
            //thumb
            g2.setColor(Color.GRAY);
            diameter = 20;
            g2.fillOval(joyCenterX - diameter/2 , joyCenterY - diameter/2, diameter, diameter);
        }
    
        void addChangeListener(ChangeListener listener) {
            listenerList.add(ChangeListener.class, listener);
        }
    
        void removeChangeListener(ChangeListener listener) {
            listenerList.remove(ChangeListener.class, listener);
        }
    
        protected void fireStateChanged() {
            ChangeEvent e = new PointChangeEvent(this, position);
            Object[] listeners = listenerList.getListenerList();
            for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i] == ChangeListener.class) {
                    ((ChangeListener) listeners[i + 1]).stateChanged(e);
                }
            }
        }        
    }
    
    class PointChangeEvent extends ChangeEvent
    {
        private static final long serialVersionUID = 1L;
        public Point p;
    
        public PointChangeEvent(Object source, Point p)
        {
            super(source);
            this.p=p;
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是来自@mKorbel 的重新编写的代码,它基于事件且更面向摇摆,没有浮动:

      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Point;
      import java.awt.RenderingHints;
      import java.awt.event.MouseAdapter;
      import java.awt.event.MouseEvent;
      
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.SwingUtilities;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;
      
      class JoyDemo extends JPanel implements ChangeListener {    
          private JLabel lblPosition;
      
          public JoyDemo() {
              setLayout(new BorderLayout(0, 0));
              SimpleJoystick myJoystick = new SimpleJoystick(150);
              myJoystick.setPreferredSize(new Dimension(100,100));
              myJoystick.addChangeListener(this);
              add(myJoystick, BorderLayout.CENTER);
      
              lblPosition = new JLabel("position");
              add(lblPosition, BorderLayout.SOUTH);
          }
      
          @Override
          public void stateChanged(ChangeEvent ev) {
              Point p = null;
              try {
                  p = ((PointChangeEvent)ev).p;
              } catch (Exception e) {
                  return;
              }
              lblPosition.setText("x="+p.x+" y="+p.y);
          }
      }
      
      class SimpleJoystick extends JPanel {
          /** Maximum value for full horiz or vert position where centered is 0 */
          private int joyOutputRange;
          /** max x and y value, in pixels */
          private int joyRadius; 
          /** Joystick displayed Center, in pixels */
          private int joyCenterX, joyCenterY; 
          /** joystick output position scaled to given joyOutputRange */
          private Point position = new Point();
          /** joystick x axis value in pixels */
          private int dx = 0;
          /** joystick y axis value in pixels */
          private int dy = 0;
      
          /**
           * @param joyOutputRange
           */
          public SimpleJoystick(final int joyOutputRange) {
              this.joyOutputRange = joyOutputRange;
              setBackground(new Color(226, 226, 226));
              MouseAdapter mouseAdapter = new MouseAdapter() {
      
                  @Override
                  public void mousePressed(final MouseEvent e) {
                      if (SwingUtilities.isLeftMouseButton(e) && cursorChanged(e.getX(), e.getY())) {
                          SwingUtilities.getRoot(SimpleJoystick.this).repaint();
                          fireStateChanged();
                      }
                  }
      
                  @Override
                  public void mouseDragged(MouseEvent e) {
                      if (SwingUtilities.isLeftMouseButton(e) && cursorChanged(e.getX(), e.getY())) {
                          SwingUtilities.getRoot(SimpleJoystick.this).repaint();
                          fireStateChanged();
                      }
                  }
              };
              addMouseMotionListener(mouseAdapter);
              addMouseListener(mouseAdapter);
          }
      
          private boolean cursorChanged(int mouseX, int mouseY) {
              if (joyRadius == 0) return false;
      
              dx = mouseX - joyCenterX;
              dy = mouseY - joyCenterY;
              if (dx > joyRadius) dx = joyRadius;
              if (dy > joyRadius) dy = joyRadius;
              if (dx < -joyRadius) dx = -joyRadius;
              if (dy < -joyRadius) dy = -joyRadius;
      
              position.x = joyOutputRange * dx / joyRadius;
              position.y = -joyOutputRange * dy / joyRadius;
      
              return true;
          }
      
          @Override
          protected void paintComponent(final Graphics g) {
              super.paintComponent(g);
              int joyWidth = getSize().width;
              int joyHeight = getSize().height;
              joyRadius = Math.min(joyWidth, joyHeight) / 2;
              if (joyRadius == 0) return;
      
              joyCenterX = joyWidth / 2;
              joyCenterY = joyHeight / 2;
              Graphics2D g2 = (Graphics2D) g;
              g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      
              int diameter; 
      
              //background
              g2.setColor(Color.LIGHT_GRAY);
              diameter = joyRadius*2;
              g2.fillOval(joyCenterX - diameter/2 , joyCenterY - diameter/2, diameter, diameter);
      
              g2.setColor(Color.RED);
              diameter = 40;
              g2.fillOval(joyCenterX + dx - diameter/2 , joyCenterY + dy - diameter/2, diameter, diameter);
      
              //thumb
              g2.setColor(Color.GRAY);
              diameter = 20;
              g2.fillOval(joyCenterX - diameter/2 , joyCenterY - diameter/2, diameter, diameter);
          }
      
          void addChangeListener(ChangeListener listener) {
              listenerList.add(ChangeListener.class, listener);
          }
      
          void removeChangeListener(ChangeListener listener) {
              listenerList.remove(ChangeListener.class, listener);
          }
      
          protected void fireStateChanged() {
              ChangeEvent e = new PointChangeEvent(this, position);
              Object[] listeners = listenerList.getListenerList();
              for (int i = listeners.length - 2; i >= 0; i -= 2) {
                  if (listeners[i] == ChangeListener.class) {
                      ((ChangeListener) listeners[i + 1]).stateChanged(e);
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        这是我的解决方案。请注意,我修改了@Dark.Rider 的答案,谁修改了@tutejszy 的答案,谁修改了@mKorbel 的答案......

        我制作了 2 个文件。一个叫 Joystick.java

        import java.awt.Color;
        import java.awt.Graphics;
        import java.awt.Point;
        import java.awt.event.MouseAdapter;
        import java.awt.event.MouseEvent;
        import java.beans.PropertyChangeListener;
        import javax.swing.event.SwingPropertyChangeSupport;
        import javax.swing.SwingUtilities;
        
        public class Joystick extends javax.swing.JPanel {
        
            private final int outputMax;
            private final int thumbDiameter;
            private final int thumbRadius;
            private final int panelWidth;
            private final int arrowRadius;
            private final int BORDER_THICKNESS = 2;
        
            private final Point thumbPos = new Point();
            protected SwingPropertyChangeSupport propertySupporter = new SwingPropertyChangeSupport(this);
        
        
            /**
             * @param output_max The maximum value to scale output to. If this value was
             * 5 and the joystick thumb was dragged to the top-left corner, the output 
             * would be (-5,5)
             * @param panel_width how big the JPanel will be. The sizes of the joystick's
             * visual components are proportional to this value
             */
            public Joystick(int output_max, int panel_width) {
        
                assert output_max > 0;
                assert panel_width > 0;
        
                outputMax = output_max;
                panelWidth = panel_width;
                thumbDiameter = panel_width/4;
                thumbRadius = thumbDiameter/2;
                arrowRadius = panel_width/24;
        
                MouseAdapter mouseAdapter = new MouseAdapter() {
        
                    private void repaintAndTriggerListeners(){
                        SwingUtilities.getRoot(Joystick.this).repaint();
                        propertySupporter.firePropertyChange(null, null, getOutputPos());
                    }
        
                    @Override
                    public void mousePressed(final MouseEvent e) {
                        if (SwingUtilities.isLeftMouseButton(e)) {
                            updateThumbPos(e.getX(), e.getY());
                            repaintAndTriggerListeners();
                        }
                    }
        
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        if (SwingUtilities.isLeftMouseButton(e)) {
                            updateThumbPos(e.getX(), e.getY());
                            repaintAndTriggerListeners();
                        }
                    }
        
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        if (SwingUtilities.isLeftMouseButton(e)) {
                            centerThumbPad();
                            repaintAndTriggerListeners();
                        }
                    }
                };
                addMouseMotionListener(mouseAdapter);
                addMouseListener(mouseAdapter);
                setPreferredSize(new java.awt.Dimension(panel_width, panel_width));
                setOpaque(false);
        
                centerThumbPad();
            }
        
            private void centerThumbPad(){
                thumbPos.x = panelWidth/2;
                thumbPos.y = panelWidth/2;
            }
        
            /**
             * update both thumbPos
             * @param mouseX the x position of cursor that has clicked in the joystick panel
             * @param mouseY the y position of cursor that has clicked in the joystick panel
             * @return 
             */
            private void updateThumbPos(int mouseX, int mouseY) {
                // if the cursor is clicked out of bounds, we'll modify the position
                // to be the closest point where we can draw the thumb pad completely
                if (mouseX < thumbRadius)
                    mouseX = thumbRadius;
                else if(mouseX > panelWidth - thumbRadius)
                    mouseX = panelWidth - thumbRadius;
        
                if (mouseY < thumbRadius)
                    mouseY = thumbRadius;
                else if(mouseY > panelWidth - thumbRadius)
                    mouseY = panelWidth - thumbRadius;
        
                thumbPos.x = mouseX;
                thumbPos.y = mouseY;
            }
        
            /**
             * @return the scaled position of the joystick thumb pad
             */
            Point getOutputPos(){
                Point result = new Point();
                result.x = outputMax * (thumbPos.x - panelWidth/2) / (panelWidth/2-thumbDiameter/2);
                result.y = -outputMax * (thumbPos.y - panelWidth/2) / (panelWidth/2-thumbDiameter/2);
                return result;
            }
        
            @Override
            protected void paintComponent(final Graphics g) {
                super.paintComponent(g);
        
                //joystick background border
                g.setColor(Color.BLACK);
                g.fillOval(thumbRadius, thumbRadius, panelWidth-thumbDiameter, panelWidth-thumbDiameter);
        
                //joystick background color
                g.setColor(Color.GRAY);
                g.fillOval(thumbRadius+BORDER_THICKNESS, thumbRadius+BORDER_THICKNESS, panelWidth-thumbDiameter-BORDER_THICKNESS*2, panelWidth-thumbDiameter-BORDER_THICKNESS*2);
        
                //joystick background arrows
                g.setColor(Color.BLACK);
                int[] left_x = {thumbDiameter-arrowRadius,thumbDiameter+arrowRadius,thumbDiameter+arrowRadius};
                int[] left_y = {panelWidth/2,panelWidth/2+arrowRadius,panelWidth/2-arrowRadius};
                g.fillPolygon(left_x, left_y,3);
                int[] right_x = {panelWidth-thumbDiameter+arrowRadius,panelWidth-thumbDiameter-arrowRadius,panelWidth-thumbDiameter-arrowRadius};
                int[] right_y = {panelWidth/2,panelWidth/2+arrowRadius,panelWidth/2-arrowRadius};
                g.fillPolygon(right_x, right_y,3);
                int[] up_x = left_y;
                int[] up_y = left_x;
                g.fillPolygon(up_x, up_y,3);  
                int[] down_x = right_y;
                int[] down_y = right_x;
                g.fillPolygon(down_x, down_y,3);  
        
                //thumb pad border
                g.setColor(Color.BLACK);
                g.fillOval(thumbPos.x - thumbRadius - BORDER_THICKNESS, thumbPos.y - thumbRadius - BORDER_THICKNESS, thumbRadius*2+BORDER_THICKNESS*2, thumbRadius*2+BORDER_THICKNESS*2);
        
                //thumb pad color
                g.setColor(Color.GRAY);
                g.fillOval(thumbPos.x - thumbRadius, thumbPos.y - thumbRadius, thumbRadius*2, thumbRadius*2);
            }
        
            @Override
            public void addPropertyChangeListener(PropertyChangeListener listener) {
                propertySupporter.addPropertyChangeListener(listener);
            }
        
            @Override
            public void removePropertyChangeListener(PropertyChangeListener listener) {
                propertySupporter.removePropertyChangeListener(listener);
            }
        }
        
        

        还有一个叫 JoystickOutputContainer.java(用来制作示例图片)

        import java.awt.BorderLayout;
        import java.awt.Point;
        import java.beans.PropertyChangeListener;
        import javax.swing.JLabel;
        import javax.swing.JPanel;
        
        public class JoystickOutputContainer extends JPanel {
        
            private Joystick myJoystick = new Joystick(100, 140);
            private JLabel lblPosition = new JLabel("x=0 y=0");
        
            public JoystickOutputContainer() {
                setLayout(new BorderLayout(0, 0));
                add(myJoystick, BorderLayout.CENTER);
                add(lblPosition, BorderLayout.SOUTH);
                myJoystick.addPropertyChangeListener(updateConsoleListener);
            }
        
            private final PropertyChangeListener updateConsoleListener = (evt) -> {
                updateConsoleCallback( (Point) evt.getNewValue() );
            };
        
            private void updateConsoleCallback(Point p){
                lblPosition.setText("x="+p.x+" y="+p.y);
            }
        
        }
        
        

        【讨论】:

          猜你喜欢
          • 2018-01-13
          • 2011-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-07
          • 1970-01-01
          相关资源
          最近更新 更多