JNWarner
JNWarner

Reputation: 31

Changing the colour of a line in a draw program using events

I am trying to create a program which draws a line using points. I have done this bit. The line then needs to redraw itself when the program is minimized and maximized again. This is where my first problem is occurring. Say I draw 2 lines, the last point of the first line and the first point of my second line join together when it is maximized.

That is not my main problem however. I want to implement a key handler so that say, when keys 1-9 are pressed, each key represents a different color change for the line. I have tried implementing a key handler but there is obviously something going wrong as I can't quite get it working. Any help would be appreciated. My code is shown below.

package part2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.awt.Point;
import java.awt.Color;

public class ScribbleComponentRepaint extends JComponent implements Scribbler {
    int w = 640;
    int h = 360;
    Point c;
    ArrayList<Point> line;
    ArrayList<ArrayList<Point>> lines;

    public static void main(String[] args) {
        ScribbleComponentRepaint sc = new ScribbleComponentRepaint();
        new JEasyFrame(sc, "Scribble");
        sc.addMouseListener(new Clicker(sc));
        sc.addMouseMotionListener(new Mover(sc));
        sc.addKeyListener(new Keys(sc));
    }

    public ScribbleComponentRepaint() {
        line = new ArrayList<Point>();
        lines = new ArrayList<ArrayList<Point>>();
    }

    public void handleKey(int e) {

        switch (e) {
            case KeyEvent.VK_1:

                break;
            default: {
                System.out.println("Default");
            }
        }
    }


    public void paintComponent(Graphics g) {
        for (ArrayList<Point> line : lines) {
            int n = 0;
            int limit = 1;
            if (line.size() > 0) {
                for (Point p : line) {
                    Point c = line.get(Math.max(n - limit, 0));
                    n++;
                    g.setColor(Color.RED);
                    g.drawLine(c.x, c.y, p.x, p.y);
                }
            }
        }
    }

    public void penDown(Point p) {
        c = p;

    }

    public void penUp(Point p) {
        drawTo(p);
        c = null;

    }

    public void drawTo(Point p) {
        if (c != null) {
            Graphics g = getGraphics();
            g.setColor(Color.BLUE);
            g.drawLine(c.x, c.y, p.x, p.y);
            c = p;
        }
        line.add(c);
        lines.add(line);

    }

    public void drag(Point p) {
        //should not be null
        drawTo(p);
    }


    public Dimension getPreferredSize() {
        return new Dimension(w, h);
    }

}

package part2;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Keys extends KeyAdapter {

    Scribbler sc;

    public Keys(Scribbler sc){
        this.sc = sc;
    }

    public void keyPressed(KeyEvent e) {
        //System.out.println(k);
        sc.handleKey(e.getKeyCode());
    }
}

package part2;

import java.awt.*;

public interface Scribbler {
    public void paintComponent(Graphics g);
    public void penDown(Point p);
    public void drag(Point p);
    public void penUp(Point p);
    public void handleKey(int e);
}

Upvotes: 3

Views: 12846

Answers (2)

Andrew Thompson
Andrew Thompson

Reputation: 168825

At the end of main:

    sc.setFocusable(true);
    sc.requestFocusInWindow();

BTW

  • The GUI should be constructed on the EDT.
  • Consider using key bindings instead of a KeyListener
  • Nicely designed code (what with both defining an interface and coding to it), but for better help sooner, post an SSCCE. I had to make some changes to the code before I could test my theory that the problem with detecting keys was 'focus'.

Upvotes: 3

polypiel
polypiel

Reputation: 2341

Well, you just have to define a color variable. This varible will be set in your handling keys methods, and used in your paint method. Besides, you will need to refresh the screen after the a key is pressed.

 public class ScribbleComponentRepaint extends JComponent implements Scribbler {
   Color color = Color.BLUE; // var definition
 ...
    public void handleKey(int e) {

    switch (e) {
        case KeyEvent.VK_1:
            color = Color.RED; // setting the new color
            break;
        default: {
            System.out.println("Default");
        }
    }
    repaint(); // updates the screen
}
...
public void paintComponent(Graphics g) {
    for (ArrayList<Point> line : lines) {
        int n = 0;
        int limit = 1;
        if (line.size() > 0) {
            for (Point p : line) {
                Point c = line.get(Math.max(n - limit, 0));
                n++;
                g.setColor(color); // uses the color var
                g.drawLine(c.x, c.y, p.x, p.y);
            }
        }
    }
}
...

Upvotes: 2

Related Questions