Domanda

This is my first time asking on stackoverflow, so please tell me if I am doing something wrong.

I am writing a program that implements a key listener, and I am trying to get it to change a color according to which key is pressed. (see code below) However, it does not change the color, but it still registers the key pressing. The way I am trying to test this is with the 'b' key, as seen in the code. Thanks in advance.

import java.awt.*;
import java.awt.event.*;

import javax.swing.JFrame;
import javax.swing.JPanel;

class Spring extends JPanel implements KeyListener {
    private char f = 'a';
    private int a = 0, b = 0, c = 0;
    private Color flower = new Color(a,b,c);

    public Spring() {  //Constructor
        this.setPreferredSize(new Dimension(500, 500));
        addKeyListener(this);
    }

    public void addNotify() { //the focus
        super.addNotify();
        requestFocus();
    }

    public void paintComponent(Graphics g) {
        g.clearRect(0, 0, getWidth(), getHeight()); //clear before next press
        g.drawString("the key that pressed is " + f, 0, 10);
        g.setColor(flower);
        Polygon flowa = new Polygon();
        flowa.addPoint(220,270);
        flowa.addPoint(250,300);
        flowa.addPoint(270,270);
        flowa.addPoint(250,300);
        g.fillPolygon(flowa);
        g.fillRect(250,300,30,30);

    }

    public void keyPressed(KeyEvent e) { }
    public void keyReleased(KeyEvent e) { }
    public void keyTyped(KeyEvent e) { //when key is typed, do something
        f = e.getKeyChar(); //modify value of f
        switch (f){
        case 'a': 
            a = 10;
            b = 10;
            c = 10;
        case 'b': 
            a = 223;
            b = 45;
            c = 45;
            System.out.println("Bals");
        case 'c': 
            a = 10;
            b = 10;
            c = 10;
        case 'd': 
            a = 10;
            b = 10;
            c = 10;
        case 'e': 
            a = 10;
            b = 10;
            c = 10;
        case 'f': 
            a = 10;
            b = 10;
            c = 10;
        case 'g': 
            a = 10;
            b = 10;
            c = 10;
        case 'h': 
            a = 10;
            b = 10;
            c = 10;
        case 'i': 
            a = 10;
            b = 10;
            c = 10;
        case 'j': 
            a = 10;
            b = 10;
            c = 10;
        case 'k': 
            a = 10;
            b = 10;
            c = 10;
        case 'l': 
            a = 10;
            b = 10;
            c = 10;
        case 'm': 
            a = 10;
            b = 10;
            c = 10;
        }
        repaint();
    }

    public static void main(String[] s) { //main method, creates the frame
        JFrame f = new JFrame();
        f.getContentPane().add(new Spring());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}
È stato utile?

Soluzione

You are just setting the variables a, b, and c. Changing these variables won't change the numbers used by flower, because flower is using the numbers you passed in, not the variables you are using.

You need to create a new Color object in each instance, something like this:

flower = new Color(20, 230, 210);

Also, don't forget to add in break; lines between cases; otherwise, your flower object will be the color that you last listed.

Also, you might want to use an implementation of the KeyAdapter class, which allows you to define only the methods you want to use instead of all the methods, instead of having your own class KeyListener.

Altri suggerimenti

saiarcot895 answer is correct in that it solves the problem at hand (+1). This is an example of how it might be achieved using a the Key Bindings API

KeyListener is generally a poor choice for monitoring key events as it suffers from focus related issues, which you are attempting to resolve, but are not gurenteed to work.

A better solution is to use the Key Bindings API, which provides you with the ability to configure the focus level at which key events are triggered.

The problem you will have is the fact that you have a large number of possible key strokes to use. To this end, I simply used a Map to map the key code to an Action which was used to set the desired color

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Spring extends JPanel {

    private Color flower = Color.BLACK;
    private String key;

    public Spring() {
        Map<Integer, ColorAction> mapColors = new HashMap<>(25);
        mapColors.put(KeyEvent.VK_F, new ColorAction(this, "F", new Color(10, 10, 10)));
        mapColors.put(KeyEvent.VK_B, new ColorAction(this, "B", new Color(223, 45, 45)));

        InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = getActionMap();

        for (Integer keyCode : mapColors.keySet()) {

            KeyStroke ks = KeyStroke.getKeyStroke(keyCode, 0);
            im.put(ks, ks);
            am.put(ks, mapColors.get(keyCode));

        }
    }

    public void update(String ks, Color color) {
        flower = color;
        key = ks;
        repaint();
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString("the key that pressed is " + key, 0, 10);
        g.setColor(flower);
        Polygon flowa = new Polygon();
        flowa.addPoint(220, 270);
        flowa.addPoint(250, 300);
        flowa.addPoint(270, 270);
        flowa.addPoint(250, 300);
        g.fillPolygon(flowa);
        g.fillRect(250, 300, 30, 30);

    }

    public static void main(String[] s) { //main method, creates the frame
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame f = new JFrame();
                f.getContentPane().add(new Spring());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setVisible(true);
            }
        });
    }

    public class ColorAction extends AbstractAction {

        private Spring spring;
        private String key;
        private Color color;

        private ColorAction(Spring spring, String ks, Color color) {
            this.spring = spring;
            this.key = ks;
            this.color = color;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            spring.update(key, color);
        }

    }
}

If you find it useful, an up-vote would be welcome, but saiarcot895 answer should remain marked as correct

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top