How to draw two lines in java with swing and arrays - java

so i am trying to make a program that will draw a line when you call the static void and it will send the coordinates of the line into an array to draw it in the panel class when i call it once it draws a line but when i call it twice it does not draw the first line only the second.
main class
package main;
import javax.swing.*;
public class VB {
public static int[] POS_x1;
public static int[] POS_y1;
public static int[] POS_x2;
public static int[] POS_y2;
public static int PosCount;
VB(){
}
public static void NewWindow(String Title, String LogoPath, int x, int y, int Width, int Height){
Panel panel = new Panel();
ImageIcon image = new ImageIcon(LogoPath);
JFrame frame = new JFrame();
frame.setIconImage(image.getImage());
frame.setTitle(Title);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel);
frame.setBounds(x, y, Width, Height);
frame.setResizable(false);
frame.setVisible(true);
}
public static void DrawLine(int x1, int y1, int x2, int y2) {
POS_x1 = new int[256];
POS_y1 = new int[256];
POS_x2 = new int[256];
POS_y2 = new int[256];
POS_x1[PosCount] = x1;
POS_y1[PosCount] = y1;
POS_x2[PosCount] = x2;
POS_y2[PosCount] = y2;
PosCount++;
System.out.println(PosCount);
}
public static void main(String[] args) {
VB.NewWindow("window", "res/img/saullularphone.PNG", 100, 100, 500, 500);
VB.DrawLine(0, 0, 100, 50);
VB.DrawLine(0, 50, 100, 50);
}
}
Panel class
package main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Panel extends JPanel {
Panel(){
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int pos = 0; pos < VB.PosCount; pos++) {
g2.setColor(Color.black);
g2.drawLine(VB.POS_x1[pos], VB.POS_y1[pos], VB.POS_x2[pos], VB.POS_y2[pos]);
}
}
}
i tried drawing the first line then redrawing then drawing the second line but it didn't work and drew the second line

You should not be using the static keyword anywhere but the static main method.
Here's a GUI that draws two lines. You can add additional lines if you wish.
I created a Swing model using plain Java getter/setter classes.
I created a LineSegment class to hold all the parameters to draw a line. I created a DrawingLinesModel class to hold a List of LineSegment instances. You can use an array, but a List is more flexible.
I created a JFrame and a drawing JPanel.
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Performing Custom Painting section.
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
Here's the complete runnable code. I made all the additional classes inner classes so I could post the code as one block.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class DrawingLinesExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DrawingLinesExample());
}
private final DrawingLinesModel model;
private final DrawingPanel drawingPanel;
public DrawingLinesExample() {
this.model = new DrawingLinesModel();
this.drawingPanel = new DrawingPanel(model);
}
#Override
public void run() {
JFrame frame = new JFrame("Drawing Lines");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final DrawingLinesModel model;
public DrawingPanel(DrawingLinesModel model) {
this.model = model;
this.setPreferredSize(new Dimension(600, 640));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (LineSegment line : model.getLines()) {
g2d.setColor(line.getColor());
g2d.setStroke(new BasicStroke(line.getThickness()));
Point sp = line.getStartPoint();
Point ep = line.getEndPoint();
g2d.drawLine(sp.x, sp.y, ep.x, ep.y);
}
}
}
public class DrawingLinesModel {
private final List<LineSegment> lines;
public DrawingLinesModel() {
this.lines = new ArrayList<>();
this.lines.add(new LineSegment(new Point(10, 10),
new Point(400, 400), Color.BLUE, 9));
this.lines.add(new LineSegment(new Point(10, 400),
new Point(400, 10), Color.MAGENTA, 11));
}
public List<LineSegment> getLines() {
return lines;
}
}
public class LineSegment {
private final int thickness;
private final Color color;
private final Point startPoint, endPoint;
public LineSegment(Point startPoint, Point endPoint, Color color,
int thickness) {
this.startPoint = startPoint;
this.endPoint = endPoint;
this.color = color;
this.thickness = thickness;
}
public Point getStartPoint() {
return startPoint;
}
public Point getEndPoint() {
return endPoint;
}
public Color getColor() {
return color;
}
public int getThickness() {
return thickness;
}
}
}

Related

java gui paintComponent refresh

I am learning java gui interface and wrote a program that has a button. Each time the button is clicked, a random sized rectangle will be added to the screen. But instead of adding it to the screen, the program keeps erasing the old one, which I want to keep on the screen. Here is my code. I tried to do paint() and it did not work. Thanks in advance.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class SimpleGui implements ActionListener {
JFrame frame = new JFrame();
public static void main(String[] args){
SimpleGui gui = new SimpleGui();
gui.go();
}
public void go(){
JButton button = new JButton("Add a rectangle");
MyDrawPanel panel = new MyDrawPanel();
button.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event){
frame.repaint();
}
class MyDrawPanel extends JPanel{
public void paintComponent(Graphics g){
g.setColor(Color.blue);
int height = (int) (Math.random()*120 + 10);
int width = (int) (Math.random()*120 + 10);
int x = (int) (Math.random()*40 + 10);
int y = (int) (Math.random()*40 + 10);
g.fillRect(x, y, height, width);
}
}
}
Your paintComponent method is written to draw only one rectangle, so its behavior should come as no shock to you. If you want it to draw multiple, you have one of two options:
Create an ArrayList<Rectangle>, and in the actionPerformed method, add a new random Rectangle to this List and then call repaint(). In the paintComponent method, iterate through this List with a for-loop, painting each Rectangle.
Or you could draw the new random rectangle onto a BufferedImage that is displayed by the paintComponent method.
The first method is the easier of the two, the 2nd is better if you're worried about program responsiveness, say in an animation program.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class TwoDrawRectMethods extends JPanel {
// Array to hold our two drawing JPanels
private AddRandomRect[] addRandomRects = {
new DrawList("Using List"),
new DrawBufferedImage("Using BufferedImage")};
// constructor
public TwoDrawRectMethods() {
// add drawing rectangles onto GUI
for (AddRandomRect addRandomRect : addRandomRects) {
add(addRandomRect);
}
// button to tell rectangles to add a new Rectangle
add(new JButton(new DrawAction("Add New Rectangle")));
}
// The button's Action -- an ActionListener on "steroids"
private class DrawAction extends AbstractAction {
public DrawAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// tell both drawing JPanels to add a new rectangle
for (AddRandomRect addRandomRect : addRandomRects) {
addRandomRect.addRectangle();
}
}
}
private static void createAndShowGui() {
TwoDrawRectMethods mainPanel = new TwoDrawRectMethods();
JFrame frame = new JFrame("TwoDrawRectMethods");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class DrawList extends AddRandomRect {
private static final Color RECT_COLOR = Color.RED;
private List<Rectangle> rectList = new ArrayList<>();
public DrawList(String title) {
super(title);
}
#Override
public void addRectangle() {
rectList.add(createRandomRect());
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(RECT_COLOR);
for (Rectangle rectangle : rectList) {
g2.draw(rectangle);
}
}
}
#SuppressWarnings("serial")
class DrawBufferedImage extends AddRandomRect {
private static final Color RECT_COLOR = Color.BLUE;
private BufferedImage img = null;
public DrawBufferedImage(String title) {
super(title);
}
#Override
public void addRectangle() {
if (img == null) {
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Rectangle rect = createRandomRect();
Graphics2D g2 = img.createGraphics();
g2.setColor(RECT_COLOR);
g2.draw(rect);
g2.dispose();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, null);
}
}
}
#SuppressWarnings("serial")
abstract class AddRandomRect extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private Random random = new Random();
public AddRandomRect(String title) {
setBorder(BorderFactory.createTitledBorder(title));
}
abstract void addRectangle();
protected Rectangle createRandomRect() {
int x1 = random.nextInt(PREF_W);
int x2 = random.nextInt(PREF_W);
int y1 = random.nextInt(PREF_H);
int y2 = random.nextInt(PREF_H);
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1 - x2);
int height = Math.abs(y1 - y2);
return new Rectangle(x, y, width, height);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}

Two ScheduledExecutorService overriding eachother?

I'm trying to make two blinking circles that blink at different rates. I'm using ScheduledExecutorService in the Circle class to regulate the blinking, and its duration is set by the ms (milliseconds) variable in each Circle.
When I make one car individually, they blink at the correct rates (I have the black one set to 1000ms, the red set to 10ms). However, when I create them both and add them to my JLayeredPane, they both blink at the shorter period.
I'm not too familiar with the use of ScheduledExecutorService, so if someone could help me out with what's going wrong it'd be greatly appreciated!
import java.awt.Color;
import java.awt.Graphics;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.awt.*;
import javax.swing.*;
public class blinker extends JFrame
{
JLayeredPane lp = new JLayeredPane();
public carlight()
{
lp.setLayout(new BorderLayout());
lp.setPreferredSize(new Dimension(450, 450));
car c1 = new car(new Color(0, 0, 0), "1", 10, 0, 0);
c1.setOpaque(false);
car c2 = new car(new Color(255, 0, 0), "2", 1000, 100, 100);
c2.setOpaque(false);
c1.setBounds(0, 0, 450, 450);
c2.setBounds(0, 0, 450, 450);
lp.add(c2);
lp.add(c1);
add(lp);
setTitle("Carlights");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setVisible(true);
}
public static void main(String[] args)
{
carlight cl = new carlight();
}
}
class Circle extends JPanel
{
private Color color;
private String name;
private long ms;
private int x, y;
private boolean on = true;
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
#Override
public void paintComponent(Graphics g)
{
super.paintComponents(g);
if(on)
{
g.setColor(color);
int r = 50;
g.fillOval(x, y, r, r);
on = false;
}
else
{
on = true;
}
}
public car(Color c, String s, long l, int x, int y)
{
color = c;
name = s;
ms = l;
this.x = x;
this.y = y;
this.service.scheduleAtFixedRate(new Runnable()
{
public void run()
{
repaint();
}
}, 0, ms, TimeUnit.MILLISECONDS);
}
}
Your problem is that you have program logic in the paintComponent method, where you change the state of the boolean variable. You don't have full control over when or even if this method will be called, and in fact both paintComponents will be called when repaint is called which is why your blinkers aren't working. The solution: get the logic out of the paintComponent method by changing the state of the boolean field, on, elsewhere. Also you'll want to use a Swing Timer for better Swing threading.
You also will want to fix your use of layouts including avoiding use of setBounds. This is especially dangerous and unpredictable in your setup, using it with a BorderLayout. Myself, I'd not make the Circle class extend a JPanel but rather make it a logical class, not a component class, and then I'd have the drawing component, a class that does extend JPanel, hold instances of Circle classes and then draws them in its paintComponent. For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class BlinkerEg extends JPanel {
private static final int PREF_W = 450;
private static final int PREF_H = PREF_W;
private List<Circle> circles = new ArrayList<>();
public BlinkerEg() {
circles.add(new Circle(Color.red, 1000, 0, 0, 450, this));
circles.add(new Circle(Color.black, 60, 0, 0, 450, this));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Circle circle : circles) {
circle.paint(g2);
}
}
private static void createAndShowGui() {
BlinkerEg mainPanel = new BlinkerEg();
JFrame frame = new JFrame("BlinkerEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Circle {
private Color color;
private int x, y;
private int diam;
private JComponent component;
private boolean on = true;
public Circle(Color color, int ms, int x, int y, int diam, JComponent component) {
this.color = color;
this.x = x;
this.y = y;
this.diam = diam;
this.component = component;
new Timer(ms, new TimerListener()).start();
}
public void paint(Graphics g) {
if (on) {
g.setColor(color);
g.fillOval(x, y, diam, diam);
}
}
public boolean isOn() {
return on;
}
public void setOn(boolean on) {
this.on = on;
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
setOn(!isOn());
component.repaint();
}
}
}

Change the background color on a custom Button?

I want my button to change color on the mod == 0 of i % 3. The paintComponent(...) is called when the form is re-sized and index is passed in so I would think that this should change the color of my button ever time I start moving the form around the screen.
I have two components on the screen but both will not show up this might be a factor.
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testform {
public static void main (String[] p) {
testBall3 j1 = new testBall3();
myButton b1 = new myButton("test");
JPanel testPane = new JPanel();
testPane.setBackground(Color.green);
testPane.setLayout(new BorderLayout());
j1.setPreferredSize(new Dimension(10,10));
//testPane.add(b1);
testPane.add(j1);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(testPane);
frame.pack();
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//j1.setColorBall(Color.BLACK);
//j1.repaint();
}
}
class myButton extends JButton {
private static final long serialVersionUID = 1L;
public myButton(String s) {
super(s);
}
public void setPrefferedSize(Dimension d) {
//this.setBounds(x, y, width, height)
setPreferredSize(d);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
index += i;
System.out.println(i);
if (index % 3 == 0) {
setBackground(Color.RED);
}
else {
setBackground(Color.BLACK);
}
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
class testBall3 extends JComponent
{
private static final long serialVersionUID = 1L;
private Color colorBall = Color.red;
private int x1, y1;
int index = 0;
public void setColorBall(Color c)
{
this.colorBall = c;
}
public testBall3()
{
super();
System.out.println("MyBall (0)");
}
public testBall3(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
System.out.println("MyBall (1)");
x1 = x;
y1 = y;
}
public void paintBorder(Graphics g)
{
super.paintBorder(g);
g.setColor(Color.YELLOW);
g.fillOval(100, 100, 50, 50);
System.out.println("PaintBorder");
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(colorBall);
g.fillOval(x1, y1, 10, 10);
System.out.println("paintComponent");
}
public void paint(Graphics g)
{
super.paint(g);
paintComponent(g);
paintBorder(g);
paintChildren(g);
System.out.println("Paint");
}
}
But paintComponent doesn't take a second parameter, how are you passing it? I would think that instead of trying to pass i, you would want make i an attribute of class myButton instead and initialize it to 0 upon instantiation. That is, if you want each button to have its own counter. That sounds like the better plan.
You've got a lot of strange stuff going on...
You've got a component where you override all four major painting methods for no good reason.
In this component, your paint method override calls the super method, and calls the other 3 methods, which in essence will make those 3 methods be called twice.
You've got program logic (advancement of i) inside of your myButton's paintComponent method -- something that should never be done. You do not have full control over when or even if this method is called.
You are calling setBackground(...) from within paintComponent, something which shouldn't be done.
Your class names do not begin with an upper case letter, going against coding conventions, and potentially confusing anyone who tries to read your code.
If you want to change the state of a component on resize, use a ComponentListener.
e.g.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Foo2 extends JPanel {
protected static final Color MAGIC_BACKGROUND = Color.red;
protected static final int MAGIC_NUMBER = 3;
private static final int TIMER_DELAY = 20;
private int index = 0;
private JButton myButton = new JButton("My Button");
protected int DELTA_SIZE = 2;
public Foo2() {
add(myButton);
addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
index++;
if (index % MAGIC_NUMBER == 0) {
myButton.setBackground(MAGIC_BACKGROUND);
} else {
myButton.setBackground(null);
}
}
});
new Timer(TIMER_DELAY, new ActionListener() {
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private int screenWidth = toolkit.getScreenSize().width;
private int screenHeight = toolkit.getScreenSize().height;
#Override
public void actionPerformed(ActionEvent e) {
if (getWidth() >= screenWidth || getHeight() >= screenHeight) {
((Timer)e.getSource()).stop();
} else {
int width = getWidth() + DELTA_SIZE;
int height = getHeight() + DELTA_SIZE;
setPreferredSize(new Dimension(width, height));
Window win = SwingUtilities.getWindowAncestor(Foo2.this);
win.pack();
win.setLocationRelativeTo(null);
}
}
}).start();
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Foo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Foo2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Repaint method compiling improperly

I am trying to use repaint in a timer task, but eclipse is telling me the method is undefined, and I don't know why. I believe I have all the proper imports. Below is just a small segment of my code.
import java.awt.Color;
import java.awt.Graphics;
import java.util.TimerTask;
import java.util.Timer;
import javax.swing.JPanel;
class task extends TimerTask
{
public void run()
{
repaint();
}
}
You're calling a method that has not been declared in the class it is held in, and so Java, not "Eclipse" is complaining, and rightfully so.
If you are trying to redraw a Swing GUI component intermittently using a timer then,
Use a Swing Timer, not a java.util.Timer, since the latter does not handle Swing threading properly.
Call repaint() on a Swing component, not on nothing as you're doing.
Most important, go through the Java and Java Swing tutorials, as it will explain all of this and more.
For example, try running this straight, and then try running it stoned. It's almost psychedelic:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyRepaint extends JPanel {
private static final Color COLOR_1 = Color.RED;
private static final Color COLOR_2 = Color.BLUE;
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int DELAY = 25;
private int x1 = 0;
private int y1 = 0;
private int x2 = 20;
private int y2 = 20;
Paint myPaint = new GradientPaint(x1, y1, COLOR_1, x2, y2, COLOR_2, true);
public MyRepaint() {
new Timer(DELAY, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
x1++;
y1++;
x2++;
y2++;
x1 %= PREF_W;
y1 %= PREF_H;
x2 %= PREF_W;
y2 %= PREF_H;
myPaint = new GradientPaint(x1, y1, COLOR_1, x2, y2, COLOR_2, true);
// the repaint method call below works because it is calling it on
// the current object of this class, which extends JPanel
// and thus has a repaint() method.
repaint();
}
}).start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(myPaint);
g2.fillRect(0, 0, PREF_W, PREF_H);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
MyRepaint mainPanel = new MyRepaint();
JFrame frame = new JFrame("MyRepaint");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Implementing clolored free-hand lines with SWING

Hy!
I want to draw free lines in a JFrame. I implemented it in a class which extends JPanel. Its definition looks like this:
public class Draw extends JPanel implements MouseMotionListener, MouseListener
I added to the class Draw a void method where I also generated the JFrame and added than the Draw object. My problem now is: I want to be able to select the color of the line from a menu:
JMenu colorMenu = new JMenu();
JMenuItem greenChoice = new JMenuItem("GREEN");
greenChoice.addActionListener(this);
colorMenu.add(greenChoice);
JMenuItem redChoice = new JMenuItem("RED");
colorMenu.add(redChoice);
JMenuBar bar = new JMenuBar();
bar.add(colorMenu);
I don't know where to implement this code! Should I make 2 classes, one for the drawing and one for the JFrame together with its Menu? How should I tell the Drawing class to interact with my JMenu, e.g. with the color I choose from the Menu? It is here where i generate my line in the class Drwa, with the default color BLUE :(
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
if(point1!=null && point2!=null){
g2d.setPaint(Color.BLUE);
g2d.setStroke(new BasicStroke(1.5f));
g2d.draw(line2d);
}
}
thank you!
Here's a free hand drawing class that I did to illustrate Swing graphics. Modify it as you wish.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
public class DrawingTest implements Runnable {
private JFrame frame;
private MyDrawPanel drawPanel;
private List<Point> points;
public DrawingTest() {
points = new ArrayList<Point>();
}
#Override
public void run() {
frame = new JFrame("Bouncing Vertices");
drawPanel = new MyDrawPanel(this);
MyListener alpha = new MyListener(this);
drawPanel.addMouseMotionListener(alpha);
drawPanel.addMouseListener(alpha);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawPanel);
frame.setSize(800, 600);
frame.setVisible(true);
}
public JPanel getDrawingPanel() {
return drawPanel;
}
public List<Point> getPoints() {
return points;
}
public void setPoint(int x, int y) {
points.add(new Point(x, y));
}
public void resetPoints() {
points.clear();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new DrawingTest());
}
private class MyListener extends MouseInputAdapter {
private DrawingTest drawingTest;
public MyListener(DrawingTest drawingTest) {
this.drawingTest = drawingTest;
}
#Override
public void mouseDragged(MouseEvent event) {
drawingTest.setPoint(event.getX(), event.getY());
drawingTest.getDrawingPanel().repaint();
}
#Override
public void mouseReleased(MouseEvent event) {
drawingTest.resetPoints();
}
}
private class MyDrawPanel extends JPanel {
private static final long serialVersionUID = 1L;
private DrawingTest drawingTest;
public MyDrawPanel(DrawingTest drawingTest) {
this.drawingTest = drawingTest;
}
#Override
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLUE);
for (int i = 1; i < drawingTest.getPoints().size(); i++) {
Point p1 = drawingTest.getPoints().get(i - 1);
Point p2 = drawingTest.getPoints().get(i);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
}
}
}

Categories