(JAVA)移动通过的KeyListener剪裁区域((JAVA) moving clipping

2019-10-21 17:08发布

我的目标是使用箭头键同时移动剪切区域10个像素。 我得到了面板和裁剪区域上的图像是有太多,但事情是剪切区域不会移动。 这里是我的代码,希望对学习有什么不妥的地方。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class clipping_area extends JFrame{
    clipping_area(){
        setTitle("OpenChallenge");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500,500);
        add(new panelOC());
    }
    class panelOC extends JPanel{
        int xAxis=0;
        int yAxis=0;
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            Image img=(new ImageIcon("images/image1.jpg")).getImage();
            g.setClip(100+10*xAxis,100+10*yAxis,50,50);
            g.drawImage(img,0,0,getWidth(),getHeight(),this);
        }
        panelOC(){
            requestFocus();
            addKeyListener(new KeyAdapter(){
                public void keyPressed(KeyEvent KE){
                    if(KE.getKeyCode()==KeyEvent.VK_UP){
                        yAxis-=1;
                        repaint();
                    }
                    else if(KE.getKeyCode()==KeyEvent.VK_DOWN){
                        yAxis+=1;
                        repaint();
                    }
                    else if(KE.getKeyCode()==KeyEvent.VK_LEFT){
                        xAxis-=1;
                        repaint();
                    }
                    else if(KE.getKeyCode()==KeyEvent.VK_RIGHT){
                        xAxis+=1;
                        repaint();
                    }
                }
            });
        }
    }
    public static void main(String[] args){
        new clipping_area();
    }
}

Answer 1:

KeyListener是在,好了,重点领域一个真正的痛苦。 如果附着的组件不可作为焦点和具有键盘焦点,它不会触发事件,这就是它设计的方式。 相反,使用的键绑定API,它被设计为克服这一点。

请参阅如何使用按键绑定更多细节

警惕修改的clip一个的Graphics上下文,一个Graphics上下文共享资源,这意味着,这将是过去其他组件。 你也可以,如果你不小心,大小在这样的剪辑掉的油漆超越组件的范围,导致一些奇怪的图形故障,就个人而言,我远离它。

如果您使用ImageIO.read相反,你可以得到一个参考BufferedImage和使用getSubImage为“假”它,而不是

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import static javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClippingArea extends JFrame {

    ClippingArea() {
        setTitle("OpenChallenge");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new PanelOC());
        pack();
        setVisible(true);
    }

    class PanelOC extends JPanel {

        int xAxis = 0;
        int yAxis = 0;
        private BufferedImage img;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {

                int width = 50;
                if (xAxis + width > img.getWidth()) {
                    width = img.getWidth() - xAxis;
                }
                int height = 50;
                if (yAxis + height > img.getHeight()) {
                    height = img.getHeight() - yAxis;
                }

                if (width > 0 && height > 0) {

                    BufferedImage subImage = img.getSubimage(xAxis, yAxis, width, height);
                    g.drawImage(subImage, xAxis, yAxis, this);

                }

            }

        }

        protected void registerKeyBinding(String name, KeyStroke keyStroke, Action action) {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(keyStroke, name);
            am.put(name, action);
        }

        public PanelOC() {

            try {
                img = ImageIO.read(new File("C:\\hold\\thumbnails\\_cg_836___Tilting_Windmills___by_Serena_Clearwater.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            registerKeyBinding("moveClip.up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), new YKeyAction(-10));
            registerKeyBinding("moveClip.down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), new YKeyAction(10));
            registerKeyBinding("moveClip.left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), new XKeyAction(-10));
            registerKeyBinding("moveClip.right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), new XKeyAction(10));
        }

        public class XKeyAction extends AbstractAction {

            private int delta;

            public XKeyAction(int delta) {
                this.delta = delta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                xAxis += delta;
                if (yAxis > getWidth()) {
                    yAxis = getWidth() - 50;
                } else if (yAxis < 0) {
                    yAxis = 0;
                }
                repaint();
            }

        }

        public class YKeyAction extends AbstractAction {

            private int delta;

            public YKeyAction(int delta) {
                this.delta = delta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                yAxis += delta;
                if (yAxis > getHeight()) {
                    yAxis = getHeight() - 50;
                } else if (yAxis < 0) {
                    yAxis = 0;
                }
                repaint();
            }

        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                ClippingArea ca = new ClippingArea();
            }
        });
    }
}

看看读/加载图像了解更多详情

你也应该创建,并从事件指派线程的上下文中modiying你的用户界面,看到初始线程的详细信息



Answer 2:

代替使用面板上的的KeyListener使用AWTEventListener所(这会抓住一个特定类型的所有事件

java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
    toolkit.addAWTEventListener(new AWTEventListener() {
        @Override
        public void eventDispatched(AWTEvent ae) {
            if (ae instanceof KeyEvent) {
                KeyEvent KE = (KeyEvent) ae;
                if (KE.getID() == KeyEvent.KEY_PRESSED) {
                    switch(KE.getKeyCode()) {
                        case KeyEvent.VK_UP:
                            yAxis -= 1;
                            break;
                        case KeyEvent.VK_DOWN:
                            yAxis += 1;
                            break;
                        case KeyEvent.VK_LEFT:
                            xAxis -= 1;
                            break;
                        case KeyEvent.VK_RIGHT:
                            xAxis += 1;
                            break;
                    }
                    repaint();
                }
            }
        }
    }, AWTEvent.KEY_EVENT_MASK);

和第二编辑,我换成你,如果有switch语句(其显著清洁阅读和便于以后修改。



文章来源: (JAVA) moving clipping area by keylistener