الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيفية جعل ال KeyListener يؤثر على مفاتيح ال KeyBoard

بدأه mr.beshoy في 15 أبريل 2010 · 11 رد · 957 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

نستكمل معاً لعبة tetries التى تكلمنا عنها فى مشاركة سابقة .

هنا نحن أمام مرحلة تحريك الشكل - شكل المربع - على المسار الأفقى أثناء حركته رأسياً لإسفل .

كتبتُ دالة الحركة الأفقية و هى كالتالى :

--------------------------------------

العمود المبدأى الذى يقف عليه الشكل قيمته = 4

و بما أن الشكل مربع إذن هو يأخذ أربع خانات . خانتين فى الصف الأول و خانتين فى الصف الثانى .

فإذا أردنا الحركة يميناً علينا :

بزيادة قيمة العمود مرة بمقدار 2 أى 4+2 - حتى تُرسم أول خانة فى العمود ذات القيمة التى = 6

ولرسم الخانة الثانية نزد قيمة العمود بمقدار 3 أى 4+3 - حتى تُرسم ثانى خانة فى العمود ذات القيمة التى = 7

ثم نزيد قيمة الصف لرسم الخانتين الآخرتين فى نفس الأعمدة.

و هكذا إذا أردنا الحركة يساراً و لكن نطرح .

هل تفكيرى سليم أم لا ؟!

و بكل بساطة استعملنا ال KeyListener لجعل الأسم اليمنية و اليسارية تُحرِك الشكل عند الضغط عليها

و لكن لم تستجب لإى شئ

انظروا معنا و تأملوا المشهد - الدالة التى أضيفت فى الفئة MainFrameTetries

اسمها moveSquareHorizontal()

------------------------------------

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

enum Action {

    START, HELP, EXIT;
}

class MainGame extends JFrame {

    private JPanel mainPanel, buttonsPanel;
    private Box mainButtonsBox;
    private JButton[] buttons;
    private Action[] buttonsNames;
    private Action action;
    private MainFrameTetries mainFrameTetries;

    public MainGame() {
        createContainer();
        buttonsNames = Action.values();
        for (int i = 0; i < buttonsNames.length; ++i) {
            action = buttonsNames;
            createButtons(action);
        }
        getContentPane().add(mainPanel);
        //////////////////////////////////////////////////
    }

    public static void main(String[] args) {
        MainGame mainGame = new MainGame();
        mainGame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainGame.setSize(new Dimension(600, 300));
        mainGame.setLocationRelativeTo(null);
        mainGame.setExtendedState(MAXIMIZED_BOTH);
        mainGame.setVisible(true);
    }

    private void createContainer() {   // for createing container
        /////////////////////MainPanel/////////////////////////////
        mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(30, 30, 30, 30);
        //////////////////////Box&Panel fro buttons/////////////////////////////////////
        mainButtonsBox = Box.createHorizontalBox();
        buttonsPanel = new JPanel(new GridLayout(3, 1));
        mainButtonsBox.setBorder(BorderFactory.createLineBorder(Color.BLUE, 5));
        mainButtonsBox.setPreferredSize(new Dimension(400, 200));
        mainButtonsBox.add(buttonsPanel);
        ///////////////////////////////////////////////////////////////////////////////
        mainPanel.add(mainButtonsBox, c);
        //////////////////////////////////////////////////
        mainFrameTetries = new MainFrameTetries(this);
        mainFrameTetries.setVisible(false);
        mainPanel.add(mainFrameTetries);
    }

    private void createButtons(Action action) {
        buttons = new JButton[buttonsNames.length];
        for (int i = 0; i < 1; ++i) {
            buttons = new JButton(action.name());
            buttons.addActionListener(listenerFor(action));
            buttonsPanel.add(buttons);
        }
    }

    private ActionListener listenerFor(Action action) {
        switch (action) {
            case START:    // START BUTTON
                return new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        mainFrameTetries.setVisible(true);
                        mainButtonsBox.setVisible(false);
                    }
                };
            case HELP:   // HELP BUTTON
                return new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "HELP");
                    }
                };
            case EXIT:  // EXIT BUTTON
                return new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "EXIT");
                    }
                };
        }
        return null;
    }
}
-----------------------------------------------------------------------------------------------
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.Timer;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

class MainFrameTetries extends JPanel implements ActionListener {

    private int x, y;
    private int currentRow = 0, currentColumn = 4;
    private Timer timer;
    private int rows = 20, columns = 10;
    private JPanel[][] panel;
    private Random random;
    private Color randomColor;
    private MyKeyListener myKeyListener;

    public MainFrameTetries(MainGame mainGame) {
        myKeyListener = new MyKeyListener();
        random = new Random();
        createMainPanel(mainGame);
        creatwTetrisPanel();
        randomColor = randomColor();
        timer = new Timer(600, this);
        timer.start();
    }

    private void createMainPanel(MainGame mainGame) {
        setPreferredSize(new Dimension(200, 400));
        setSize(getPreferredSize());
        setLayout(new GridLayout(rows, columns));
        System.out.println(getPreferredSize().height);
        x = mainGame.getWidth() / 2 - getWidth() / 2;
        y = mainGame.getHeight() / 2 - getHeight() / 2;
        setLocation(x, y);

    }

    private void creatwTetrisPanel() {
        panel = new JPanel[rows][columns];
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j] = new JPanel();
                panel[j].setBackground(Color.WHITE);
                panel[j].setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
                add(panel[j]);
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        moveSquareVertical();
    }

    private Color randomColor() {
        return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
    }

    public void clearPanel() {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j].setBackground(Color.WHITE);
            }
        }
    }

    private void moveSquareVertical() {
        if (currentRow < rows - 1) {
            clearPanel();
            panel[currentRow][currentColumn].setBackground(randomColor);
            panel[currentRow][currentColumn + 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 1].setBackground(randomColor);
        } else {
            timer.stop();
        }
        currentRow++;
    }

    private void moveSquareHorizontal() {
        if (currentColumn > columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn + 2].setBackground(randomColor);
            panel[currentRow][currentColumn + 3].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 3].setBackground(randomColor);
            currentColumn++;
        } else {
            clearPanel();
            panel[currentRow][currentColumn - 1].setBackground(randomColor);
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
            currentColumn--;
        }

    }

    private class MyKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            super.keyPressed(e);
            int location = e.getKeyLocation();
            if (location == KeyEvent.KEY_LOCATION_RIGHT || location == KeyEvent.KEY_LOCATION_LEFT) {
                moveSquareHorizontal();
            }
        }

//        @Override
//        public void keyReleased(KeyEvent e) {
//            super.keyReleased(e);
//        }
    }
}

ال code مرفق أيضاً

----------------------------------------

شكراً ،،،،

TestrissGame.rar

تم تعديل هذه المشاركة بواسطة mr.beshoy في 15 أبريل 2010 في 14:27

#2
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT){
//do right movement
}
else if(key == KeyEvent.VK_LEFT){
//do left movement
}
#3

طبقت كما قولت :

    private class MyKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            super.keyPressed(e);
            int location = e.getKeyCode();
            if (location == KeyEvent.VK_RIGHT || location == KeyEvent.VK_LEFT) {
                moveSquareHorizontal();
            }
        }
    }

لكن لم تتأثر الزراير بأى شئ . هل الدالة الى كتبتها لجعل الشكل يتحرك على المسار الأفقى خاطئة ؟

---------------------------------------------------------------------------------

مرفق ال code مع تعديل هذه الجزئية .

شكراً،،،،

TestrissGame.rar

#4

ربما نسيت إضافة

addKeyListener(new MyKeyListener());

في داخل MainFrameTetris

#5

فعلاً أنا لم أكن ضايف السطر الذى قولته - فهو المسئول عن جعل الزراير تشعر بالحدث- . تمت إضافته و لكن المشكلة قائمة لم يتحرك الشكل .

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.Timer;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

class MainFrameTetries extends JPanel implements ActionListener {

    private int x, y;
    private int currentRow = 0, currentColumn = 4;
    private Timer timer;
    private int rows = 20, columns = 10;
    private JPanel[][] panel;
    private Random random;
    private Color randomColor;
    private MyKeyListener myKeyListener;

    public MainFrameTetries(MainGame mainGame) {
        myKeyListener = new MyKeyListener();
        addKeyListener(myKeyListener);
        random = new Random();
        createMainPanel(mainGame);
        creatwTetrisPanel();
        randomColor = randomColor();
        timer = new Timer(600, this);
        timer.start();
    }

    private void createMainPanel(MainGame mainGame) {
        setPreferredSize(new Dimension(200, 400));
        setSize(getPreferredSize());
        setLayout(new GridLayout(rows, columns));
        System.out.println(getPreferredSize().height);
        x = mainGame.getWidth() / 2 - getWidth() / 2;
        y = mainGame.getHeight() / 2 - getHeight() / 2;
        setLocation(x, y);

    }

    private void creatwTetrisPanel() {
        panel = new JPanel[rows][columns];
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j] = new JPanel();
                panel[j].setBackground(Color.WHITE);
                panel[j].setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
                add(panel[j]);
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        moveSquareVertical();
    }

    private Color randomColor() {
        return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
    }

    public void clearPanel() {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j].setBackground(Color.WHITE);
            }
        }
    }

    private void moveSquareVertical() {
        if (currentRow < rows - 1) {
            clearPanel();
            panel[currentRow][currentColumn].setBackground(randomColor);
            panel[currentRow][currentColumn + 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 1].setBackground(randomColor);
        } else {
            timer.stop();
        }
        currentRow++;
    }

    private void moveSquareHorizontal() {
        if (currentColumn > columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn + 2].setBackground(randomColor);
            panel[currentRow][currentColumn + 3].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 3].setBackground(randomColor);
            currentColumn++;
        } else {
            clearPanel();
            panel[currentRow][currentColumn - 1].setBackground(randomColor);
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
            currentColumn--;
        }

    }

    private class MyKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            super.keyPressed(e);
            int location = e.getKeyCode();
            if (location == KeyEvent.VK_RIGHT) {
                moveSquareHorizontal();
            }
        }
    }
}

-------------------------------------

شكرا ،،،

#6

أعتقد أن حدث الحركة يجب أن يضاف إلى Frame أو إلى Component لديها التركيز Focus

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#7

حدث الحركة موضوع بطريقة سليمة يا باشمهندس علاء ، هو المشكلة تقريباً فى دالة الحركة الأفقية .

لو أى حد يعرف يفيدينا .

--------------------------------------------

شكراً،،،

تم تعديل هذه المشاركة بواسطة mr.beshoy في 16 أبريل 2010 في 00:54

#8
علاء الصالحي كتب:

أو إلى Component لديها التركيز Focus

+1

من يمتلك ال focus هو من يلتقط الحدث

	public MainFrameTetries(MainGame mainGame) {
		//.....
		myKeyListener = new MyKeyListener();
		addKeyListener(myKeyListener);
		setFocusable(true);
		requestFocusInWindow();
	}

تم تعديل هذه المشاركة بواسطة JustPassing في 16 أبريل 2010 في 00:58

#9

بصراحة أول مرة أعرف فكرة ال Focuse هذه ، و شكراً على المعلومة .

لكن فى سوالين عندى

---------------------------

الدالة التى تحرك الشكل - الذى على هيئة مربع - لليمين :

    private void move_Square_Right_Horizontal() {
        while (currentColumn > columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn + 2].setBackground(randomColor);
            panel[currentRow][currentColumn + 3].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 3].setBackground(randomColor);
        }
        currentColumn++;
    }

بتشتغل لما بضغط على الزر الأيمن ، لكن هل مضبوطة ؟! ياريت حد يجربها ويشوفها .

المشكلة فى الدالة التى تحرك المربع ناحية اليسار " عند الضغط على الزر اليسار يتوقف البرنامج كله و الشكل يتوقف عن الحركة " .

    private void move_Square_Left_Horizontal() {
        while (currentColumn < columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn - 1].setBackground(randomColor);
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
        }
        currentColumn--;
    }

هل الدالة نصها البرمجى خاطئ ؟!!

------------------------------------------------------------

المشهد الجديد :

---------------------

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.Timer;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

class MainFrameTetries extends JPanel implements ActionListener {

    private int x, y;
    private int currentRow = 0, currentColumn = 4;
    private Timer timer;
    private int rows = 20, columns = 10;
    private JPanel[][] panel;
    private Random random;
    private Color randomColor;
    private MyKeyListener myKeyListener = new MyKeyListener();

    public MainFrameTetries(MainGame mainGame) {
        //  myKeyListener = new MyKeyListener();
        addKeyListener(myKeyListener);
        setFocusable(true);
        requestFocusInWindow();
        random = new Random();
        createMainPanel(mainGame);
        creatwTetrisPanel();
        randomColor = randomColor();
        timer = new Timer(600, this);
        timer.start();
    }

    private void createMainPanel(MainGame mainGame) {
        setPreferredSize(new Dimension(200, 400));
        setSize(getPreferredSize());
        setLayout(new GridLayout(rows, columns));
        System.out.println(getPreferredSize().height);
        x = mainGame.getWidth() / 2 - getWidth() / 2;
        y = mainGame.getHeight() / 2 - getHeight() / 2;
        setLocation(x, y);

    }

    private void creatwTetrisPanel() {
        panel = new JPanel[rows][columns];
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j] = new JPanel();
                panel[j].setBackground(Color.WHITE);
                panel[j].setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
                add(panel[j]);
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        moveSquareVertical();
    }

    private Color randomColor() {
        return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
    }

    public void clearPanel() {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                panel[j].setBackground(Color.WHITE);
            }
        }
    }

    private void moveSquareVertical() {
        if (currentRow < rows - 1) {
            clearPanel();
            panel[currentRow][currentColumn].setBackground(randomColor);
            panel[currentRow][currentColumn + 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 1].setBackground(randomColor);
        } else {
            timer.stop();
        }
        currentRow++;
    }

    private void move_Square_Right_Horizontal() {
        while (currentColumn > columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn + 2].setBackground(randomColor);
            panel[currentRow][currentColumn + 3].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 3].setBackground(randomColor);
        }
        currentColumn++;
    }

    private void move_Square_Left_Horizontal() {
        while (currentColumn < columns - 1) {
            clearPanel();
            panel[currentRow][currentColumn - 1].setBackground(randomColor);
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 1].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
        }
        currentColumn--;
    }

    private class MyKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            super.keyPressed(e);
            int location = e.getKeyCode();
            if (location == KeyEvent.VK_RIGHT) {
                move_Square_Right_Horizontal();
            } else if (location == KeyEvent.VK_LEFT) {
                move_Square_Left_Horizontal();
            }
        }
    }
}

ال code بعد التعديل الجديد .

----------------------------------------------

شكراً ،،،

TestrissGame.rar

تم تعديل هذه المشاركة بواسطة mr.beshoy في 16 أبريل 2010 في 01:28

#10

بصراحة ، الحركة على المسار الأفقى مش شغالة خالص .

جربت طرق و لكنها لم تنفع .

دالة الحركة الرئسية شغالة أم الأفقية عندما أضغط على الزر الأيمن فهى تعمل أم الأيسر فلا يتحرك الشكل و البرنامج يقف تماماً .

    private void move_Square_Right_Horizontal() {
        while (currentColumn > columns - 1) {
            clearPanel();
            panel[currentRow ][currentColumn + 2].setBackground(randomColor);
            panel[currentRow][currentColumn + 2].setBackground(randomColor);
            panel[currentRow+1][currentColumn + 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn + 2].setBackground(randomColor);
        }
        currentColumn++;
    }

    private void move_Square_Left_Horizontal() {
        while (currentColumn < columns ) {
            clearPanel();
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
            panel[currentRow + 1][currentColumn - 2].setBackground(randomColor);
        }
        currentColumn--;
    }

تفسيرى للدالة :

فرضاً المربع محتل العمودين الرابع و الخامس

إذن حتى يتحرك يميناً علينا بزيادة كل عمود بمقدار درجتين أى نضيف على الرابع 2

و الخامس أيضاً نضيف عليه 2

و العكس إذا كنا نريد الحركة يساراً نطرح من الرابع و الخامس القيمة 2 .

------------------------------

ال code مرفق بتعديله .

أرجو من يفيدنا فى هذا الأمر .

شكراً لكم جميعاً

TestrissGame.rar

تم تعديل هذه المشاركة بواسطة mr.beshoy في 16 أبريل 2010 في 14:34

#11
	private void moveSquareLeft() {
		clearPanel();
		currentColumn--;
		panel[currentRow][currentColumn].setBackground(randomColor);
		panel[currentRow][currentColumn + 1].setBackground(randomColor);
		panel[currentRow + 1][currentColumn].setBackground(randomColor);
		panel[currentRow + 1][currentColumn + 1].setBackground(randomColor);
		repaint();
	}

	private void moveSquareRight() {
		clearPanel();
		currentColumn++;
		panel[currentRow][currentColumn].setBackground(randomColor);
		panel[currentRow][currentColumn + 1].setBackground(randomColor);
		panel[currentRow + 1][currentColumn].setBackground(randomColor);
		panel[currentRow + 1][currentColumn + 1].setBackground(randomColor);
		repaint();
	}

	private class MyKeyListener extends KeyAdapter {

		@Override
		public void keyPressed(KeyEvent e) {
			int keyCode = e.getKeyCode();
			if (keyCode == KeyEvent.VK_LEFT && currentColumn > 0) {
				moveSquareLeft();
			} else if (keyCode == KeyEvent.VK_RIGHT && currentColumn < columns + 2) {
				moveSquareRight();
			}
		}
	}

تم تعديل هذه المشاركة بواسطة JustPassing في 16 أبريل 2010 في 14:45

#12

شكراً ، لقد أدركت أين الخطاً . و لنا رجعة مع هذا الموضوع .

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…