JFrame无法按预期工作

时间:2015-01-23 16:01:06

标签: java swing jframe jpanel

我正在制作一个小程序,让您使用JPanel上的箭头键绘制线条。但是我遇到了2个问题。任何人都可以解释我的代码有什么问题吗?

  1. 即使添加的第一个点是宽度的一半和高度的一半,图形也不会从JPanel的中心开始。
  2. 这些线条只绘制一个线段并重置为原点,因此无法绘制。
  3. 以下是代码:

    import java.awt.event.*;
    import javax.swing.*;
    import java.awt.*;
    
    public class MyFrame extends JFrame{
        public MyFrame(){
            super("Drawing");
            add(new LinePanel());
        }
    
        public static void main(String[] args){
            MyFrame f = new MyFrame();
            f.setSize(500, 500);
            f.setLocationRelativeTo(null);
            f.setDefaultCloseOperation(MyFrame.EXIT_ON_CLOSE);
            f.setVisible(true);
        }
    
        class LinePanel extends JPanel{
            private Polygon points = new Polygon(new int[]{getWidth() / 2}, new int[]{getHeight() / 2}, 1);
    
            public LinePanel(){
                setFocusable(true);
                addKeyListener(new KeyAdapter(){
                    @Override 
                    public void keyPressed(KeyEvent e){
                        if(e.getKeyCode() == KeyEvent.VK_UP){
                            points.addPoint(points.xpoints[points.xpoints.length - 1], points.ypoints[points.ypoints.length - 1] - 10);
                        }else if(e.getKeyCode() == KeyEvent.VK_DOWN){
                            points.addPoint(points.xpoints[points.xpoints.length - 1], points.ypoints[points.ypoints.length - 1] + 10);
                        }else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
                            points.addPoint(points.xpoints[points.xpoints.length - 1] + 10, points.ypoints[points.ypoints.length - 1]);
                        }else if(e.getKeyCode() == KeyEvent.VK_LEFT){
                            points.addPoint(points.xpoints[points.xpoints.length - 1] - 10, points.ypoints[points.ypoints.length - 1]);
                        }
                        repaint();
                    }
                });
            }
    
            @Override
            protected void paintComponent(Graphics g){
                super.paintComponent(g);
                g.drawPolyline(points.xpoints, points.ypoints, points.npoints);
            }
        }
    }
    

2 个答案:

答案 0 :(得分:0)

尝试将Graphics对象转换为Graphics2D

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate((int) getWidth()/2, (int) getHeight()/2); // move to center
    g.drawPolyline(points.xpoints, points.ypoints, points.npoints);
}

答案 1 :(得分:0)

我对您的代码进行了一些更改。

  1. 我通过调用SwingUtilities invokeLater方法启动了Java Swing应用程序。您应该始终以这种方式启动Java Swing应用程序。

  2. 我使用了JFrame。除非覆盖其中一种方法,否则不应扩展Swing组件或任何Java类。

  3. 我使用了键绑定,因此我可以使用WASD键和箭头键。对于惯用左手的人来说,WASD键更方便。

  4. 我为每个键使用了抽象操作,将控制器逻辑与视图逻辑分开。

  5. 这是工作代码:

    package com.ggl.testing;
    
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.Polygon;
    import java.awt.event.ActionEvent;
    
    import javax.swing.AbstractAction;
    import javax.swing.InputMap;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.KeyStroke;
    import javax.swing.SwingUtilities;
    
    public class MyFrame implements Runnable {
    
        private JFrame frame;
    
        @Override
        public void run() {
            frame = new JFrame("Drawing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            LinePanel linePanel = new LinePanel();
            setKeyBindings(linePanel);
            frame.add(linePanel);
    
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private void setKeyBindings(LinePanel linePanel) {
            InputMap inputMap = linePanel
                    .getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(KeyStroke.getKeyStroke("W"), "up arrow");
            inputMap.put(KeyStroke.getKeyStroke("S"), "down arrow");
            inputMap.put(KeyStroke.getKeyStroke("A"), "left arrow");
            inputMap.put(KeyStroke.getKeyStroke("D"), "right arrow");
    
            inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
            inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
            inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
            inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
    
            inputMap = linePanel.getInputMap(JPanel.WHEN_FOCUSED);
            inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
            inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
            inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
            inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
    
            linePanel.getActionMap().put("up arrow", new UpArrowAction(linePanel));
            linePanel.getActionMap().put("down arrow",
                    new DownArrowAction(linePanel));
            linePanel.getActionMap().put("left arrow",
                    new LeftArrowAction(linePanel));
            linePanel.getActionMap().put("right arrow",
                    new RightArrowAction(linePanel));
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new MyFrame());
        }
    
        public class LinePanel extends JPanel {
    
            private static final long serialVersionUID = 2504617322590404776L;
    
            private Point lastPoint;
    
            private Polygon points;
    
            public LinePanel() {
                this.setPreferredSize(new Dimension(400, 400));
                this.lastPoint = new Point(200, 200);
                this.points = new Polygon();
                this.points.addPoint(200, 200);
            }
    
            public void addPoint(int x, int y) {
                lastPoint = new Point(x, y);
                points.addPoint(x, y);
            }
    
            public Point getPreviousPoint() {
                return lastPoint;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawPolyline(points.xpoints, points.ypoints, points.npoints);
            }
        }
    
        public class UpArrowAction extends AbstractAction {
    
            private static final long serialVersionUID = 8463453082541763265L;
    
            private LinePanel linePanel;
    
            public UpArrowAction(LinePanel linePanel) {
                this.linePanel = linePanel;
            }
    
            @Override
            public void actionPerformed(ActionEvent event) {
                Point p = linePanel.getPreviousPoint();
                p.y -= 10;
                linePanel.addPoint(p.x, p.y);
                linePanel.repaint();
            }
    
        }
    
        public class DownArrowAction extends AbstractAction {
    
            private static final long serialVersionUID = 3619846728122990617L;
    
            private LinePanel linePanel;
    
            public DownArrowAction(LinePanel linePanel) {
                this.linePanel = linePanel;
            }
    
            @Override
            public void actionPerformed(ActionEvent event) {
                Point p = linePanel.getPreviousPoint();
                p.y += 10;
                linePanel.addPoint(p.x, p.y);
                linePanel.repaint();
            }
    
        }
    
        public class LeftArrowAction extends AbstractAction {
    
            private static final long serialVersionUID = -2772213334907267331L;
    
            private LinePanel linePanel;
    
            public LeftArrowAction(LinePanel linePanel) {
                this.linePanel = linePanel;
            }
    
            @Override
            public void actionPerformed(ActionEvent event) {
                Point p = linePanel.getPreviousPoint();
                p.x -= 10;
                linePanel.addPoint(p.x, p.y);
                linePanel.repaint();
            }
    
        }
    
        public class RightArrowAction extends AbstractAction {
    
            private static final long serialVersionUID = 8463453082541763265L;
    
            private LinePanel linePanel;
    
            public RightArrowAction(LinePanel linePanel) {
                this.linePanel = linePanel;
            }
    
            @Override
            public void actionPerformed(ActionEvent event) {
                Point p = linePanel.getPreviousPoint();
                p.x += 10;
                linePanel.addPoint(p.x, p.y);
                linePanel.repaint();
            }
    
        }
    }