import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
@SuppressWarnings("serial")
public class GUI extends JFrame implements ActionListener, MouseListener {
private boolean drawLine = false;
private boolean drawRec = false;
private boolean drawOval = false;
private final JButton line;
private final JButton oval;
private final JButton rectangle;
private final JPanel buttonPanel;
public DrawStuff drawPanel = new DrawStuff();
public int x1;
public int x2;
public int y1;
public int y2;
public int click;
public GUI() {
super("Graphics IO");
this.click = 1;
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 3));
line = new JButton("Line");
line.addActionListener(this);
buttonPanel.add(line);
oval = new JButton("Oval");
oval.addActionListener(this);
buttonPanel.add(oval);
rectangle = new JButton("Rectangle");
rectangle.addActionListener(this);
buttonPanel.add(rectangle);
Container contentPane = this.getContentPane();
contentPane.add(buttonPanel, BorderLayout.SOUTH);
//add(drawPanel);
addMouseListener((MouseListener) this);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == line) {
drawLine = true;
repaint();
} else if (source == oval) {
drawOval = true;
repaint();
} else if (source == rectangle) {
drawRec = true;
repaint();
}
}
public static void main(String[] args) {
GUI guiIO = new GUI();
}
class DrawStuff extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLUE);
ArrayList<Shape> shapes = new ArrayList<>();
if (drawLine) {
drawLine = false;
} else if (drawOval) {
//no clue how to add an oval
drawOval = false;
} else if (drawRec) {
Rectangle rec = new Rectangle(x1, y1,Math.abs(x2-x1) , Math.abs(y2-y1));
shapes.add(rec);
drawRec = false;
}
Graphics2D j = (Graphics2D)g;
shapes.stream().map((s) -> {
((Graphics2D) j).draw((Shape) s);
return s;
}).forEach((_item) -> {
repaint();
});
}
}
@Override
public void mousePressed(MouseEvent me) {
if (click == 1){
x1 = me.getX();
y1 = me.getY();
System.out.println(x1);
System.out.println(y1);
click = 2;
}else if (click == 2) {
x2 = me.getX();
y2 = me.getY();
System.out.println(x2);
System.out.println(y2);
click = 1;
}
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
}
Okay so i have to make a program to create shapes using two mouseclicks and then be able to export/import them. I am trying to use arraylist for this but im having a hard time trying to get it to work. The rectangle im creating will not show up on the panel. What am i doing wrong? Please help me.
Lets start with the fact that DrawStuff
hasn't actually been added to anything that is capable of painting it.
DrawStuff#paintComponent
should be making decisions about updating the state of the shapes
List
, instead, your ActionListener
and MouseListener
should be making these decisions (what to add, where and what do modify), the DrawStuff
panel should just be painting what's in the Shape
list
You also shouldn't be modifying the state of the component from within the paintComponent
calling things like setBackground
could set up a repeated repaint request which could cripple your application if not your PC
Modify DrawStuff
so it has it's own MouseListener
and methods that allow your GUI
to ask it to create new shapes. Make the shapes
List
a instance field so you can manage from within DrawStuff
more easily
Something like...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GUI extends JFrame implements ActionListener {
private boolean drawLine = false;
private boolean drawRec = false;
private boolean drawOval = false;
private final JButton line;
private final JButton oval;
private final JButton rectangle;
private final JPanel buttonPanel;
public DrawStuff drawPanel = new DrawStuff();
public int x1;
public int x2;
public int y1;
public int y2;
public int click;
public GUI() {
super("Graphics IO");
this.click = 1;
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 3));
line = new JButton("Line");
line.addActionListener(this);
buttonPanel.add(line);
oval = new JButton("Oval");
oval.addActionListener(this);
buttonPanel.add(oval);
rectangle = new JButton("Rectangle");
rectangle.addActionListener(this);
buttonPanel.add(rectangle);
Container contentPane = this.getContentPane();
contentPane.add(buttonPanel, BorderLayout.SOUTH);
add(drawPanel);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == line) {
drawPanel.setDrawShape(DrawStuff.DrawShape.LINE);
} else if (source == oval) {
drawPanel.setDrawShape(DrawStuff.DrawShape.OVAL);
} else if (source == rectangle) {
drawPanel.setDrawShape(DrawStuff.DrawShape.RECTANGLE);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
GUI guiIO = new GUI();
}
});
}
public static class DrawStuff extends JPanel {
public enum DrawShape {
LINE, OVAL, RECTANGLE;
}
private ArrayList<Shape> shapes = new ArrayList<>();
private DrawShape drawShape = DrawShape.LINE;
private Shape currentShape;
public DrawStuff() {
setBackground(Color.BLUE);
MouseAdapter ma = new MouseAdapter() {
private Point clickPoint;
@Override
public void mousePressed(MouseEvent e) {
clickPoint = e.getPoint();
currentShape = null;
}
@Override
public void mouseReleased(MouseEvent e) {
if (currentShape != null) {
shapes.add(currentShape);
currentShape = null;
repaint();
}
}
@Override
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
switch (getDrawShape()) {
case LINE:
currentShape = new Line2D.Double(clickPoint, e.getPoint());
break;
case OVAL:
case RECTANGLE:
int x = clickPoint.x;
int y = clickPoint.y;
int width = p.x - clickPoint.x;
int height = p.y - clickPoint.y;
if (width < 0) {
x = p.x;
width *= -1;
}
if (height < 0) {
y = p.y;
height *= -1;
}
switch (getDrawShape()) {
case OVAL:
currentShape = new Ellipse2D.Double(x, y, width, height);
break;
case RECTANGLE:
currentShape = new Rectangle2D.Double(x, y, width, height);
break;
}
break;
}
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
public DrawShape getDrawShape() {
return drawShape;
}
public void setDrawShape(DrawShape drawShape) {
this.drawShape = drawShape;
currentShape = null;
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
for (Shape shape : shapes) {
g2d.draw(shape);
}
if (currentShape != null) {
g2d.setColor(Color.RED);
g2d.draw(currentShape);
}
}
}
}
For example. You always need to be asking yourself "who is responsible for doing what". In this case the DrawStuff
panel is actually responsible for determine "where" something is drawn, but it needs more information about "what", then based on that information it can perform the actual operation