I am writing this program that creates an H-Tree design wherever you click, and I am supposed to implement a JMenuBar so I can change the color of the recursive drawing. For some reason it is not showing up no matter what I do.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
#SuppressWarnings("serial") class Echo extends JFrame implements ActionListener, MouseListener, ChangeListener{
private static final int SLIDER_MIN = 1;
private static final int SLIDER_MAX = 11;
private static final int SLIDER_INIT = 1;
private int x;
private int y;
private int rec = SLIDER_INIT;
private Echo() {
super("H-Tree Drawing Pad");
Container canvas = this.getContentPane();
addMenus();
canvas.add(createSlider(), BorderLayout.SOUTH);
this.setSize(800,800);
this.setVisible(true);
this.setLocation(200, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addMouseListener(this);
}
private void addMenus() {
JMenuBar menuBar = new JMenuBar();
this.setJMenuBar(menuBar);
JMenu menuColor = new JMenu("Color");
menuBar.add(menuColor);
JMenuItem mitToBlack = new JMenuItem("Black");
mitToBlack.addActionListener(new ColorListener());
menuColor.add(mitToBlack);
JMenuItem mitToBlue = new JMenuItem("Blue");
mitToBlue.addActionListener(new ColorListener());
menuColor.add(mitToBlue);
JMenuItem mitToRed = new JMenuItem("Red");
mitToRed.addActionListener(new ColorListener());
menuColor.add(mitToRed);
JMenuItem mitToGreen = new JMenuItem("Green");
mitToGreen.addActionListener(new ColorListener());
menuColor.add(mitToGreen);
}
private JPanel createSlider() {
JPanel slider = new JPanel(new BorderLayout());
JSlider electricSlide = new JSlider(JSlider.HORIZONTAL,SLIDER_MIN, SLIDER_MAX, SLIDER_INIT);
electricSlide.addChangeListener(this);
electricSlide.setMajorTickSpacing(2);
electricSlide.setMinorTickSpacing(1);
electricSlide.setPaintTicks(true);
electricSlide.setPaintLabels(true);
electricSlide.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));
slider.add(electricSlide);
return slider;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Echo();
}
});
}
#Override
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
drawOrder(this.getRec(),x,y,95,g);
}
private void drawHTree(int x, int y, int size, Graphics g) {
g.drawLine(x, y, x, y + size);
g.drawLine(x + size, y, x + size, y + size);
g.drawLine(x, y + size / 2, x + size, y + size / 2);
}
private void drawOrder(int initiative, int x, int y, int size, Graphics g) {
this.drawHTree(x, y, size, g);
if(initiative > 1) {
this.drawOrder(initiative - 1, x - size/4, y - size/4, size/2, g);
this.drawOrder(initiative - 1, x+size - size/4, y-size/4, size/2, g);
this.drawOrder(initiative -1, x-size/4, y+size-size/4, size/2, g);
this.drawOrder(initiative - 1, x+size-size/4, y+size-size/4, size/2, g);
}
}
#Override
public void stateChanged(ChangeEvent e) {
JSlider origin = (JSlider)e.getSource();
if(!origin.getValueIsAdjusting()) {
setRec((int)origin.getValue());
}
}
public int getRec() {
return rec ;
}
public void setRec(int rec) {
this.rec = rec;
}
private class ColorListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
You've overridden the paint method of your JFrame and did not call the super's method within it, breaking the painting chain.
e.g., you're missing this:
#Override
public void paint(Graphics g) {
super.paint(g); // ****** you're missing this ***
g.setColor(Color.BLACK);
drawOrder(this.getRec(), x, y, 95, g);
}
By not calling the super's painting method your code is now preventing the JFrame's child components, including its menu bar, from painting correctly .
Having said this, in fact you should never paint directly within a JFrame but rather in a JPanel's paintComponent and even there you should call the super's painting method, here super.paintComponent(g);.
Related
I have a project where I need to create a GUI in Java that creates a circle on mouse-click and and continues to make trailing circles as the mouse is dragged through the frame. I've been given reference to multiple threads on here but none have seemed to help me do what I need to do. So far I've got a static circle added to my JFrame, but I want to make the multiple circles show on a JPanel in that frame. I'm stuck after trying many different angles. As of now I just need to be able to click once and create a circle.
public class Theremin extends JFrame implements ActionListener, MouseListener{
private JPanel windowArea;
private int x, y;
private static final long serialVersionUID = 1L;
public Theremin() {
}
public static void main(String[] args) {
Theremin Frame = new Theremin();
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.setLayout(null);
Frame.add(panel);
Frame.pack();
Frame.setLocationRelativeTo(null);
Frame.setVisible(true);
}
private static class MyPanel extends JPanel {
public void paint(Graphics g) {
Graphics2D gObj = (Graphics2D)g;
Shape disk = new Ellipse2D.Double(10, 10, 100, 100);
gObj.setColor(new Color(255, 0, 0, 120));
gObj.fill(disk);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Here's a GUI that I put together.
Each mouse click creates a circle.
When I create a Swing GUI, or any Java application, I use the model / view / controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one part of the application at a time.
For a Swing GUI, the MVC pattern means:
The view reads from the model.
The view does not update the model.
The controller updates the model and repaints / revalidates the view.
The model consists of two classes, Circles and Circle. The Circle class defines a circle with a Point center, int radius, and a Color color. Because Circle is a class, I can define as many instances (circles) as I want.
The Circles class holds a List of Circle instances.
The view consists of a JFrame and a drawing JPanel. The paintComponent method of the drawing JPanel paints circles. Period. We create the circles in the controller class.
The controller class CirclesListener creates the circles and repaints the drawing JPanel. All of the circles are redrawn each and every time the drawing JPanel is repainted.
An instance of the JFrame class and the application model class is passed to the controller CirclesListener class. This allows the class to create a new circle and repaint the drawing JPanel.
Here's the complete runnable code.
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.awt.RenderingHints;
import java.awt.event.MouseAdapter;
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;
public class MouseClickCircleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MouseClickCircleGUI());
}
private Circles circles;
private DrawingPanel drawingPanel;
public MouseClickCircleGUI() {
this.circles = new Circles();
}
#Override
public void run() {
JFrame frame = new JFrame("Circles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel(this, circles);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public void repaint() {
drawingPanel.repaint();
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Circles circles;
public DrawingPanel(MouseClickCircleGUI frame, Circles circles) {
this.circles = circles;
setBackground(Color.WHITE);
setPreferredSize(new Dimension(500, 500));
addMouseListener(new CirclesListener(frame, circles));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(3f));
for (Circle circle : circles.getCircles()) {
Point p = circle.getCenter();
int radius = circle.getRadius();
g2.setColor(circle.getColor());
g2.drawOval(p.x - radius, p.y - radius,
2 * radius, 2 * radius);
}
}
}
public class CirclesListener extends MouseAdapter {
private final Circles circles;
private final MouseClickCircleGUI frame;
public CirclesListener(MouseClickCircleGUI frame, Circles circles) {
this.frame = frame;
this.circles = circles;
}
#Override
public void mouseReleased(MouseEvent event) {
circles.addCircle(new Circle(event.getPoint(), 30, Color.BLACK));
frame.repaint();
}
}
public class Circles {
private final List<Circle> circles;
public Circles() {
this.circles = new ArrayList<>();
}
public void addCircle(Circle circle) {
this.circles.add(circle);
}
public List<Circle> getCircles() {
return circles;
}
}
public class Circle {
private final int radius;
private final Color color;
private final Point center;
public Circle(Point center, int radius, Color color) {
this.center = center;
this.radius = radius;
this.color = color;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
return center;
}
public Color getColor() {
return color;
}
}
}
The idea here is to:
capture point
add it to list
repaint component
Here is how I have done it, this is a sample code.
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Theremin frame = new Theremin();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.initListeners();
panel.setLayout(null);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
#Override
public void windowOpened(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
panel.releaseListener();
}
#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) {
}
});
}
}
class MyPanel extends JPanel implements MouseListener, MouseMotionListener {
private Graphics graphics;
private List<CircleData> shapeList = new ArrayList<>();
private Graphics2D gObj;
public MyPanel() {
}
#Override
public void paint(Graphics g) {
this.graphics = g;
gObj = (Graphics2D) g;
System.out.println("called paint with times: " + times++);
for (CircleData circleData : shapeList) {
Rectangle rectangle = circleData.rectangle;
Color color = circleData.color;
Shape disk = new Ellipse2D.Double(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
gObj.setColor(color);
gObj.fill(disk);
}
}
Color randomColor() {
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
return new Color(red, green, blue);
}
static int times = 0;
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
public void initListeners() {
System.out.println("added default listeners");
addMouseListener(this);
addMouseMotionListener(this);
}
public void releaseListener() {
System.out.println("removed default listeners");
removeMouseListener(this);
removeMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Clicked # " + cordinates);
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseDragged(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Dragged # " + cordinates);
System.out.println("Mouse Dragged # " + shapeList.size());
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
class CircleData {
Rectangle rectangle;
Color color;
public CircleData(Rectangle rectangle, Color color) {
this.rectangle = rectangle;
this.color = color;
}
}
class Theremin extends JFrame {
private static final long serialVersionUID = 1L;
public Theremin() {
}
}
Well my English is not so good but i will try to explain.
I was make two class,First Class and Second Class(Second was named "Grafika").
I want that my rectangle move to position where i was clicked , but obviously he dont move and i cant understand why, please help .
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub``
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
i will show you a full code, it was small .This was second class.And my(i think) only problem is repaint() method . Why i dont know :D .
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
Now i will show you first class from where i was calling second class.
import java.awt.*;
import javax.swing.*;
public class Glavna extends Grafika {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Grafika g=new Grafika();
JFrame wi=new JFrame("Grafika");
wi.setBounds(50, 50, 500, 600);
wi.add(g);
wi.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wi.setVisible(true);
}
}
You've several problems in that code:
You're sort of creating a MouseListener (you're still missing several of the interface's methods), but I don't see anywhere that you've added it to your GUI. You must somewhere have addMouseListener(this); in your code for the listener to work.
Repaint by itself doesn't move the rectangle. Changing the X and Y does, but again, not without adding the MouseListener first.
You probably want to call repaint(); without parameters to paint the whole component. Otherwise the old rectangle might not get erased.
Your paintComponent method should call the super.paintComponent(g); as the first method call of your override method. Without this you won't erase the old rectangle, and you break the painting chain which could have painting side effects in child components.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class Grafika extends JPanel {
private static final int RECT_W = 20;
private static final int RECT_H = 30;
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final Color MY_COLOR = Color.RED;
private int myX = 0;
private int myY = 0;
public Grafika() {
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse); // add MouseListener
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // **MUST** call this
g.setColor(MY_COLOR);
g.fillRect(myX, myY, RECT_W, RECT_H);
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
myX = e.getX();
myY = e.getY();
repaint(); // repaint the whole JPanel
}
}
#Override // to make the GUI larger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Grafika mainPanel = new Grafika();
JFrame frame = new JFrame("Grafika");
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(() -> {
createAndShowGui();
});
}
}
If you want to get fancier and start dragging the square around:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Grafika extends JPanel {
private static final int RECT_W = 20;
private static final int RECT_H = RECT_W;
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final Color MY_COLOR = Color.RED;
private int myX = 0;
private int myY = 0;
public Grafika() {
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(MY_COLOR);
g.fillRect(myX, myY, RECT_W, RECT_H);
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
moveRect(e);
}
#Override
public void mouseDragged(MouseEvent e) {
moveRect(e);
}
#Override
public void mouseReleased(MouseEvent e) {
moveRect(e);
}
private void moveRect(MouseEvent e) {
myX = e.getX() - RECT_W / 2;
myY = e.getY() - RECT_H / 2;
repaint();
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Grafika mainPanel = new Grafika();
JFrame frame = new JFrame("Grafika");
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(() -> {
createAndShowGui();
});
}
}
you have to add mouse listener to component porobably
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
public Grafika(){
super();
addMouseListener(this); // add to constructor
}
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub``
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
I have a program which is simple in function. On start, it creates a random circle which it places in the window/frame. When that circle is clicked, it should dissappear, and spawn a new circle elsewhere. the issue is, my program does this, but you see all the past circles unless you minimize/reopen the window. I cannot get it to repaint without my help... and I do NOT know why. Here is my code.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
public class Core extends JFrame implements MouseListener{
public static ArrayList<Ellipse2D> list = new ArrayList<Ellipse2D>();
Random r = new Random();
public Ellipse2D spawn(){
int x = r.nextInt(this.getWidth());
int y = r.nextInt(this.getHeight());
while(x<75||x>this.getWidth()-150){
x = r.nextInt(this.getWidth());
}
while(y<75||y>this.getHeight()-150){
y = r.nextInt(this.getHeight());
}
System.out.println("MAKING SHAPE at :" + x + " AND " + y);
return new Ellipse2D.Double(x, y, 75, 75);
}
public void mouseClicked(MouseEvent me) {
// Save the coordinates of the click lke this.
if(list.get(0).contains(me.getPoint())){
System.out.println("CLICKED SHAPE!");
list.clear();
list.add(spawn());
}
revalidate();
repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
#Override
public void paint(Graphics g) {
if(list.size()==0){
System.out.println("oops");
}
if(!list.isEmpty()){
System.out.println("DRAW");
int x =(int) list.get(0).getX();
int y =(int) list.get(0).getY();
int width = (int) list.get(0).getWidth();
int height = (int) list.get(0).getHeight();
g.setColor(Color.red);
g.drawOval(x,y, width, height);
}
}
public Core(){
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addMouseListener(this);
list.add(spawn());
setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Core();
}
});
}
}
Your code works perfectly fine for me, however...
Don't override paint of top level containers like JFrame, JFrame contains a JRootPane, which contains a contentPane and may also have a visible glassPane, all of which can overpaint what is painted within the paint method. As a general rule, you shouldn't extend from JFrame (or other top level containers), you are locking yourself into a single use case, reducing the re-usability of your component and you're not actually any new functionality to the class. Instead, use a JPanel and override it's paintComponent method
Call super.paint before doing any custom painting. If, however, you use a JPanel, call super.paintComponent. Painting is performed by a series of methods which are chained together to generate the final output. See Painting in AWT and Swing and Performing Custom Painting for more details
Consider using something like x = r.nextInt(this.getWidth() - 150) + 75; and y = r.nextInt(this.getWidth() - 150) + 75; instead of your while loops, I think you might find them safer to use
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Core {
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Core();
}
});
}
public Core() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CorePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CorePane extends JPanel {
private ArrayList<Ellipse2D> list = new ArrayList<Ellipse2D>();
private Random r = new Random();
public Ellipse2D spawn() {
int x = r.nextInt(this.getWidth());
int y = r.nextInt(this.getHeight());
x = r.nextInt(this.getWidth() - 150) + 75;
y = r.nextInt(this.getWidth() - 150) + 75;
System.out.println("MAKING SHAPE at :" + x + " AND " + y);
return new Ellipse2D.Double(x, y, 75, 75);
}
public CorePane() {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
// Save the coordinates of the click lke this.
if (list.get(0).contains(me.getPoint())) {
list.clear();
list.add(spawn());
}
revalidate();
repaint();
}
});
}
#Override
public void invalidate() {
super.invalidate();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
if (list.isEmpty()) {
list.add(spawn());
}
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (!list.isEmpty()) {
for (Ellipse2D ellipse : list) {
g2d.setColor(Color.red);
g2d.draw(ellipse);
}
}
g2d.dispose();
}
}
}
Or, based on what I believe you're trying to do, you could simply do something like...
public class CorePane extends JPanel {
private Random r = new Random();
private Ellipse2D ellipse;
public Ellipse2D spawn() {
int x = r.nextInt(this.getWidth());
int y = r.nextInt(this.getHeight());
x = r.nextInt(this.getWidth() - 150) + 75;
y = r.nextInt(this.getWidth() - 150) + 75;
System.out.println("MAKING SHAPE at :" + x + " AND " + y);
return new Ellipse2D.Double(x, y, 75, 75);
}
public CorePane() {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
if (ellipse != null && ellipse.contains(me.getPoint())) {
ellipse = spawn();
}
revalidate();
repaint();
}
});
}
#Override
public void invalidate() {
super.invalidate();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
spawn();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (ellipse != null) {
g2d.setColor(Color.red);
g2d.draw(ellipse);
}
g2d.dispose();
}
}
I've been trying to do this assignment and for it to work I need the event mousePressed to work but for some reason it's not responding to the mouse. Its purpose is to paint another yellow circle when the mouse is pressed.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class CatchMonster extends JPanel
{
private int height = 300;
private int width = 600;
private final int delay = 4001;
private ImageIcon image;
private Timer timer;
private int x, y, moveX, moveY, xPoint, yPoint;
public CatchMonster() {
DotListener dot = new DotListener();
addMouseListener(dot);
timer = new Timer(delay, new timerListener());
x = 40;
y = 40;
moveX = moveY = 3;
setPreferredSize(new Dimension(width, height));
setBackground(Color.black);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(Color.yellow);
g.fillOval(x, y, 60, 60);
}
private class timerListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
Random gn = new Random();
x = gn.nextInt(width);
y = gn.nextInt(height);
repaint();
}
}
private class DotListener implements MouseListener
{
public void mousePressed(MouseEvent event)
{
repaint();
}
#Override
public void mouseClicked(MouseEvent event) {
}
#Override
public void mouseEntered(MouseEvent event) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent event) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent event) {
// TODO Auto-generated method stub
}
}
}
I need the event mousePressed to work but for some reason it's not responding to the mouse. Its purpose is to paint another yellow circle when the mouse is pressed.
But it won't paint another circle as all it does is call repaint(), and how is that going to paint anything new? If you want it to create another circle, you'll have to give it logic to do so. For instance, if you want to paint more than one yellow oval, you'll want to create an ArrayList of Point objects and add a Point into that array list in the mousePressed method. Then in the paintComponent method, you can iterate through the array list, painting ovals for each Point it contains.
In addition, you want to change this:
public void paintComponent(Graphics g) {
super.paintComponents(g); // this is not the "super" method of paintComponent
g.setColor(Color.yellow);
g.fillOval(x, y, 60, 60);
}
to this:
public void paintComponent(Graphics g) {
super.paintComponent(g); // See the difference?
g.setColor(Color.yellow);
g.fillOval(x, y, 60, 60);
}
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class CatchMonster extends JPanel {
private int height = 300;
private int width = 600;
private final int delay = 4001;
private ImageIcon image;
private Timer timer;
private int x, y, moveX, moveY, xPoint, yPoint;
private List<Point> points = new ArrayList<Point>();
public CatchMonster() {
DotListener dot = new DotListener();
addMouseListener(dot);
timer = new Timer(delay, new timerListener());
x = 40;
y = 40;
moveX = moveY = 3;
setPreferredSize(new Dimension(width, height));
setBackground(Color.black);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.yellow);
g.fillOval(x, y, 60, 60);
int radius = 30;
g.setColor(Color.green);
for (Point p : points) {
int x = p.x - radius;
int y = p.y - radius;
g.fillOval(x, y, 2 * radius, 2 * radius);
}
}
private class timerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random gn = new Random();
x = gn.nextInt(width);
y = gn.nextInt(height);
repaint();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CatchMonster());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private class DotListener extends MouseAdapter {
public void mousePressed(MouseEvent event) {
points.add(event.getPoint());
repaint();
}
}
}
Can't seem to figure out how to only show one circle. Was trying to //g.clearRect(0, 0, 400, 400); but that clears the background too. Was also trying to just fill the background with yellow again but couldn't get that working either. Any suggestions?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JMouseFrame extends JFrame
implements MouseListener {
Container con = null;
int x, y;
int size;
public JMouseFrame() {
setTitle("JMouseFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
con = this.getContentPane();
addMouseListener(this);
}
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
size = 4;
}
repaint();
}
public void mouseEntered(MouseEvent e) {
con.setBackground(Color.yellow);
}
public void mouseExited(MouseEvent e) {
con.setBackground(Color.black);
}
public void paint(Graphics g) {
//g.clearRect(0, 0, 400, 400);
g.drawOval(x - size, y - size, size * 3, size * 3);
}
public static void main(String[] args) {
JMouseFrame mFrame = new JMouseFrame();
mFrame.setSize(400, 400);
mFrame.setVisible(true);
}
public void mouseReleased(MouseEvent e) {
}
}
It looks like you're mixing AWT and Swing painting. Instead, override paintComponent(), as suggested in the example below. See Painting in AWT and Swing for details.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see http://stackoverflow.com/questions/3898775 */
public class MousePanel extends JPanel {
private static final int SIZE = 20;
Point p = new Point(Short.MAX_VALUE, Short.MAX_VALUE);
public MousePanel() {
this.setPreferredSize(new Dimension(400, 400));
this.setBackground(Color.yellow);
this.addMouseListener(new MouseHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawOval(p.x - SIZE, p.y - SIZE, SIZE * 2, SIZE * 2);
}
private final class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
p = e.getPoint();
repaint();
}
}
private void display() {
JFrame f = new JFrame("MousePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MousePanel().display();
}
});
}
}
Addendum:
I can't figure out how to make the code you posted work with what I have...
You can restore your mouse methods to the MouseHandler almost verbatim. The only difference is the need to qualify this, e.g.
#Override
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
MousePanel.this.size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
MousePanel.this.size = 4;
}
repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
MousePanel.this.setBackground(Color.yellow);
}
#Override
public void mouseExited(MouseEvent e) {
MousePanel.this.setBackground(Color.black);
}