Movement stuck when clicking buttons

时光毁灭记忆、已成空白 提交于 2021-01-07 04:12:13

问题


Created a Program similar to paint where there is a rectangle whose movement inside the screen can be controlled by "w,a,s,d" keys and its size increased or decreased using the scroller on the mouse. There are also several buttons of various colours which when pressed fills the rectangular shape with the respective colours. Now the problem is after clicking any colour button the movement is stopped ie. the rectangle doesn't move. You can increase and decrease its size but you can't move with "w,a,s,d" keys. Please do help me with that.

And also as an optional request, I'm also trying to paint with this rectangle ie. when I press the space bar I want to fill the colour which is selected at the specified area. Now even though I can do that. The next action I do ie. either pressing "w,a,s,d" keys or the scroller, the colour disappears. Now I know that the colour or fillRect() has to be saved somehow so that the next action doesn't affect it, but I've tried several ways but it isn't happening. I've commented the code for the painting below.

My first request is my main request, the second one if you are unable to understand what I mean or don't know the solution just leave it.

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

public class Animation extends Frame implements KeyListener,MouseWheelListener,ActionListener {
    int x,y,a,b;
    char choice1;
    int draw=1;
    int n=0;
    int color1,color2,color3;
    Button button1,button2,button3,button4,button5,button6,button7,button8,button9,button10;

    Animation() {
        setSize(1000, 1000);
        setVisible(true);
        x = 500;
        y = 500;
        a = 20;
        b = 50;
        addKeyListener(this);
        addMouseWheelListener(this);

         JFrame frame = new JFrame();

        frame.getContentPane().setLayout(null);

        button1 = new Button("Black");
        button2 = new Button("Blue");
        button3 = new Button("Green");
        button4 = new Button("Orange");
        button5 = new Button("Red");
        button6 = new Button("Yellow");
        button7 = new Button("Gray");
        button8 = new Button("Cyan");
        button9 = new Button("Magenta");
        button10 = new Button("Pink");

        add(button1);add(button2);add(button3);add(button4);add(button5);
        add(button6);add(button7);add(button8);add(button9);add(button10);

        button1.setBounds(50,680,50,20); button2.setBounds(120,680,50,20);
        button3.setBounds(190,680,50,20); button4.setBounds(260,680,50,20);
        button5.setBounds(330,680,50,20); button6.setBounds(400,680,50,20);
        button7.setBounds(470,680,50,20); button8.setBounds(540,680,50,20);
        button9.setBounds(610,680,50,20); button10.setBounds(680,680,50,20);

        button1.addActionListener(this);button2.addActionListener(this);
        button3.addActionListener(this);button4.addActionListener(this);
        button5.addActionListener(this);button6.addActionListener(this);
        button7.addActionListener(this);button8.addActionListener(this);
        button9.addActionListener(this);button10.addActionListener(this);
        addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }

            @Override
            public void windowClosed(WindowEvent e) {
            }

            @Override
            public void windowIconified(WindowEvent e) {
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
            }

            @Override
            public void windowActivated(WindowEvent e) {
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
            }
        });
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyPressed(KeyEvent e) {
    }
    @Override
    public void keyReleased(KeyEvent e) {
        choice1 = e.getKeyChar();
        if (choice1 == 'w') {
            y = y - 10;
        }
        if (choice1 == 's') {
            y = y + 10;
        }
        if (choice1 == 'a') {
            x = x - 10;
        }
        if (choice1 == 'd') {
            x = x + 10;
        }
        if(choice1 == ' '){
            draw=2;
        }
        repaint();
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        double p = e.getPreciseWheelRotation();
        if(p>0){
            a=a+5;
            b=b+5;
        } else{
            a=a-5;
            b=b-5;
        }
        repaint();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("Black")){
            color1 = 0;
            color2 = 0;
            color3 = 0;
        }
        if(e.getActionCommand().equals("Blue")){
            color1 = 0;
            color2 = 0;
            color3 = 255;
        }
        if(e.getActionCommand().equals("Green")){
            color1 = 0;
            color2 = 255;
            color3 = 0;
        }
        if(e.getActionCommand().equals("Orange")){
            color1 = 255;
            color2 = 165;
            color3 = 0;
        }
        if(e.getActionCommand().equals("Red")){
            color1 = 255;
            color2 = 0;
            color3 = 0;
        }
        if(e.getActionCommand().equals("Yellow")){
            color1 = 255;
            color2 = 255;
            color3 = 0;
        }
        if(e.getActionCommand().equals("Gray")){
            color1 = 169;
            color2 = 169;
            color3 = 169;
       }
        if(e.getActionCommand().equals("Cyan")){
            color1 = 0;
            color2 = 255;
            color3 = 255;
        }
        if(e.getActionCommand().equals("Magenta")){
            color1 = 255;
            color2 = 0;
            color3 = 255;
        }
        if(e.getActionCommand().equals("Pink")){
            color1 = 255;
            color2 = 192;
            color3 = 203;
        }
        repaint();

    }
    public void paint(Graphics g) {
        if(draw==1) {

            g.drawRect(x, y, a, b);
            g.setColor(new Color(color1,color2,color3));
            g.fillRect(x,y,a,b);

        }
//        if(draw==2){
//            fillColor(g);
//            draw=1;
//        }
    }

//    public void fillColor(Graphics g){
//        g.setColor(Color.red);
//        int[] temp1 = new int[50];
//        temp1[n] = x;
//        int[] temp2 = new int[50];
//        temp2[n] = y;
//        int[] temp3 = new int[50];
//        temp3[n] = a;
//        int[] temp4 = new int[50];
//        temp4[n] = b;
//
//
//        n++;
//        for (int i=0;i<n;i++){
//            System.out.println("abcd");
//            g.fillRect(temp1[n],temp2[n],temp3[n],temp4[n]);
//        }
//
//    }

    public static void main(String[] args) {
        Animation animation = new Animation();

    }

}

回答1:


Short answer for the first. Add:

 button1.setFocusable(false);
    button2.setFocusable(false);
    button3.setFocusable(false);
    button4.setFocusable(false);
    button5.setFocusable(false);
    button6.setFocusable(false);
    button7.setFocusable(false);
    button8.setFocusable(false);
    button9.setFocusable(false);
    button10.setFocusable(false);



回答2:


First of all there are basic design issues:

  1. Don't extend Frame. There is no need to extend any class.

  2. Don't use AWT components in a Swing application. JFrame is Swing. "Button" is AWT. For Swing your should be using JButton.

  3. Don't use a null layout for the entire frame. Keep the default BorderLayout. Read the section from the Swing tutorial on How to Use BorderLayout.

  4. For the buttons you should create a JPanel (which by default uses a FlowLayout) and add your buttons to this panel.

Then you add this panel to your frame using:

frame.add(buttonPanel, BorderLayout.PAGE_END);
  1. Custom painting is done by extending JPanel and then you override the paintComponent(...) method. So you need to create a DrawingPanel to paint your rectangle. Read the Swing tutorial on Custom Painting for working examples to help you structure your code better.

Then you add the drawing panel to the frame using:

frame.add(drawingPanel, BorderLayout.CENTER):
  1. Don't use a WindowListener to close the frame.

When you create the frame you can set the close property:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  1. Using multiple nested if statements, like you do in the ActionListner is poor design. As you continue to support more colors the code just grows and grows. An alternative approach might be:

a) create a HashMap as an instance variable to contain the buttons and colors:

private HashMap<JButton, Color> buttonColors = new HashMap<>();
private Color rectangleColor = Color.BLACK;

b) now when you create each button you can update the hash map:

buttonColors.put(button1, Color.BLACK);

c) now the code in your ActionListener becomes:

JButton button = (JButton)e.getSource();
Color color = buttonColors.get(button);
rectangleColor = color;
repaint();

d) and the code in your paintComponent() method becomes:

//g.setColor(new Color(color1,color2,color3));
g.setColor( rectangleColor );
  1. Don't create your buttons by brute force. Create a method.

Code to invoke method

buttonsPanel.add( createButton("Black", Color.BLACK) );
buttonsPanel.add( createButton("Blue", Color.BLUE) );

and the createButton(..) method would look something like:

public JButton (String text, Color color)
{
    JButton button = new JButton( text );
    button.addActionListener(this);
    buttonColors.put(button, color);

    return button;
}

A lot of suggestions here. The code is posted without testing, so understand each concept and make a change one at a time and test to make sure you implement each step correctly.

Now the problem is after clicking any colour button the movement is stopped ie. the rectangle doesn't move.

A KeyEvent is only passed to the component with focus. When you click on a button the painting panel loses focus and no longer responds to events.

The better solution is to use Key Bindings. Key bindings will work even when a component doesn't have focus. See: Motion Using the Keyboard for more information and working examples.



来源:https://stackoverflow.com/questions/65158929/movement-stuck-when-clicking-buttons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!