At university we started Java programming and got the task to write a program that draws a vertical and a horizontal line at the location where the mouse currently is. Also we should add a Label that shows the coordinates of the mouse. I got the drawing thing working but when I try to add a label, it won't show up? I started with a test-label, but even that isn't shown inside the frame. Can someone help me?
public class Coordinates extends JPanel implements MouseListener, MouseMotionListener {
private Point currentPoint = new Point(-50, -50);
public Coordinates(){
addMouseListener(this);
addMouseMotionListener(this);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.blue);
g.drawLine(currentPoint.x, currentPoint.y+1000, currentPoint.x, currentPoint.y-1000);
g.drawLine(currentPoint.x+1000, currentPoint.y, currentPoint.x-1000, currentPoint.y);
}
public void mousePressed(MouseEvent e){
currentPoint = e.getPoint();
repaint();
};
static JLabel label = new JLabel();
public static void main(String[] args) {
JFrame frame = new JFrame("Koordinaten");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(label);
JComponent newContentPane = new Coordinaten();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
label.setText(currentPoint.toString());
currentPoint = e.getPoint();
repaint();
}
}
Do all your painting within the JPanel's paintComponent method not the paint method, and be sure to call the super's paintComponent method within your override, usually at the start of the override method.
You need to add a JLabel to your JPanel to have it display anything. Your code does not do this. And then in the MouseMotionListener, set the JLabel's text with the mouse coordinates.
For example:
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 DrawPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private JLabel locationLabel = new JLabel();
public DrawPanel() {
add(locationLabel);
addMouseMotionListener(new MyMouseAdapter());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // this allows JPanel to do housekeeping painting first
// do drawing here!
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
// get Point location and turn into a String
String location = String.format("[%d, %d]", e.getX(), e.getY());
// set the label's text with this String
locationLabel.setText(location);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
With the cross-hairs:
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 DrawPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private JLabel locationLabel = new JLabel();
private int mouseX = 0;
private int mouseY = 0;
public DrawPanel() {
add(locationLabel);
addMouseMotionListener(new MyMouseAdapter());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // this allows JPanel to do housekeeping
// painting first
// do drawing here!
g.drawLine(0, mouseY, getWidth(), mouseY);
g.drawLine(mouseX, 0, mouseX, getHeight());
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
// get Point location and turn into a String
String location = String.format("[%d, %d]", mouseX, mouseY);
// set the label's text with this String
locationLabel.setText(location);
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Basically, a JLabel is made like this, defined outside of the main method:
static JLabel label = new JLabel();
In your main method
frame.add(label);
And in your mouseMoved method you would put this:
label.setText(currentPoint.toString());
Related
Im using JPanel and JFrame to create a program that can draw lines and circles. The problem is that my program only redraws the last object added.
I have tried moving around the repaint. For some reason, when I directly draw shapes onto the graphic in paintComponent(), they show up and refresh each frame. However, I have methods inside of paintComponent that pass the graphic variable to elsewhere methods that draw to the graphic object, these are the shapes that do not show up.
Painter Class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Painter implements ActionListener, MouseListener, MouseMotionListener {
/**
*
*/
Color temp = Color.RED;
// 0 = line, 1 = circle
int object = 0;
PaintingPanel canvas;
Point startPoint = new Point();
Point endPoint = new Point();
Painter() {
//buttons
JButton circleBut = new JButton();
JButton lineBut = new JButton();
//frame
//close operation
//resizes
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
//holder holds the information
JPanel holder = new JPanel();
JPanel leftPanel = new JPanel();
holder.setLayout(new BorderLayout());
leftPanel.setLayout(new GridLayout(3, 1)); // 3 by 1 grid
JPanel northPanel = new JPanel();
northPanel.setLayout(new GridLayout(1, 2)); // 3 by 1 grid
frame.add(holder);
// circle and line buttons
circleBut.setText("Circle");
lineBut.setText("Line");
northPanel.add(circleBut);
northPanel.add(lineBut);
circleBut.setActionCommand("1");
lineBut.setActionCommand("0");
//
holder.add(northPanel, BorderLayout.NORTH);
// red
JButton redPaint = new JButton();
redPaint.setBackground(Color.RED);
redPaint.setOpaque(true);
redPaint.setBorderPainted(false);
leftPanel.add(redPaint);
redPaint.setActionCommand("red");
// green
JButton greenPaint = new JButton();
greenPaint.setBackground(Color.GREEN);
greenPaint.setOpaque(true);
greenPaint.setBorderPainted(false);
leftPanel.add(greenPaint);
greenPaint.setActionCommand("green");
// blue
JButton bluePaint = new JButton();
bluePaint.setBackground(Color.BLUE);
bluePaint.setOpaque(true);
bluePaint.setBorderPainted(false);
leftPanel.add(bluePaint);
bluePaint.setActionCommand("blue");
holder.add(leftPanel, BorderLayout.WEST);
// still need to add painting panel to the CENTER panel
canvas = new PaintingPanel();
holder.add(canvas, BorderLayout.CENTER);
circleBut.addActionListener(this);
lineBut.addActionListener(this);
redPaint.addActionListener(this);
greenPaint.addActionListener(this);
bluePaint.addActionListener(this);
canvas.addMouseListener(this);
//holder.addMouseMotionListener(this);
// still need to add chat panel to the SOUTH panel
frame.setContentPane(holder);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("red")) {
temp = Color.RED;
System.out.println("received r");
} else if (e.getActionCommand().equals("green")) {
temp = Color.GREEN;
System.out.println("received g");
} else if (e.getActionCommand().equals("blue")) {
temp = Color.BLUE;
System.out.println("received b");
} else if (e.getActionCommand().equals("0")) {
object = 0;
System.out.println("received 0");
} else if (e.getActionCommand().equals("1")) {
object = 1;
System.out.println("received 1");
}
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
startPoint.setLocation(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint.setLocation(e.getPoint());
if (object == 0) {
canvas.addPrimitive(new Line(startPoint, endPoint, temp));
}
if (object == 1){
canvas.addPrimitive(new Circle(startPoint, endPoint, temp));
}
canvas.repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
Painter game1 = new Painter();
}
}
PaintingPrimitives:
`
import java.awt.Graphics;
import java.awt.Color;
public abstract class PaintingPrimitive{
Color color;
PaintingPrimitive(Color color) {
this.color = color;
}
// This is an example of the Template Design Pattern
// this is all invariant code
public final void draw(Graphics g) {
g.setColor(color);
drawGeometry(g);
}
public void setColor(Color color) {
this.color = color;
}
protected abstract void drawGeometry(Graphics g);
}
Line Class:
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
public class Line extends PaintingPrimitive{
Point startPoint = new Point();
Point endPoint = new Point();
public Line(Point start, Point end, Color c) {
super(c);
this.startPoint = start;
this.endPoint = end;
}
public void drawGeometry(Graphics g) {
System.out.println("graw geo called");
g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}
#Override
public String toString() {
return "Line";
}
}
Painting Panel:
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
public class PaintingPanel extends JPanel {
ArrayList<PaintingPrimitive> primitives = new ArrayList<PaintingPrimitive>();
PaintingPanel() {
setBackground(Color.WHITE);
}
public void addPrimitive(PaintingPrimitive obj) {
primitives.add(obj);
this.repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// i'm confident that this is not painting to the right graphics
for (PaintingPrimitive shape : primitives) {
//g.dispose();
//this line works. this line is drawn each time its updated.
g.drawLine(0,0,100,100);
shape.draw(g);
}
}
}
`
Okay, that was weird, until it wasn't. Your problem basic centers around...
public void mousePressed(MouseEvent e) {
startPoint.setLocation(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint.setLocation(e.getPoint());
if (object == 0) {
canvas.addPrimitive(new Line(startPoint, endPoint, temp));
}
You create a single instance of startPoint and endPoint and simply update the location of each Point. You then pass these to each primitive you create. This means that each primitive is using the SAME instance of startPoint and endPoint. So, each time you call setLocation ALL the primitives are been updated.
Instead, do something more like...
#Override
public void mousePressed(MouseEvent e) {
startPoint = new Point(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint = new Point(e.getPoint());
And because I'm paranoid and don't trust any one, I'd probably also do...
public class Line extends PaintingPrimitive {
Point startPoint = new Point();
Point endPoint = new Point();
public Line(Point start, Point end, Color c) {
super(c);
this.startPoint = new Point(start);
this.endPoint = new Point(end);
}
Just to be sure
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() {
}
}
So I am new to event handlers, and I wanted to create a program where I made a Purple panel inside a frame and if the user clicks the mouse button in the area of the panel and then types % with their keyboard, I want the panel to draw a line segment in the area of the panel. This is just testing the event handlers. Right now, I am trying it but it does not work. All help will be appreciated. After I get the hand of this, I want to try out the repaint() method, where if someone does the same actions as before, I wanted to check the background of the Panel. If you can help me with both, that'd be awesome but it is not a priority. Thank you.
import java.awt.Graphics; // for classes Graphics, Color, Font, Image
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyEvent; // for classes KeyListener, MouseListener
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame; // for classes JFrame, JPanel, JLabel
import javax.swing.JPanel;
public class GardenGrows
{
public GardenGrows()
{
}
public static void main(String[] args)
{
GardenGrows gg = new GardenGrows();
gg.runIt();
}
// makes the frame and handles all properties of the frame
// also instantiates the Garden.java object
public void runIt()
{
JFrame frame = new JFrame ("Garden");
frame.setDefaultCloseOperation( frame.EXIT_ON_CLOSE );
frame.setLayout(null);
frame.setBackground(Color.GRAY);
frame.setSize( 1200,700);
frame.setLocation( 50, 10);
frame.setResizable(true);
frame.setVisible(true);
Garden gar = new Garden();
frame.getContentPane().add(gar);
}
}
class Garden extends JPanel implements KeyListener, MouseListener
{
private boolean mouseClicked;
private boolean keyClicked;
private int xpos;
private int ypos;
public Garden()
{
mouseClicked = false;
keyClicked = false;
addKeyListener(this);
addMouseListener(this);
setBackground(Color.PINK);
setLocation(50,50);
setSize(1000,500);
}
public void mousePressed(MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
if(x>=50 || x<=1050 && y<=50 || y>=550)
{
mouseClicked = true;
}
}
public void mouseClicked(MouseEvent evt){}
public void mouseReleased(MouseEvent evt){}
public void mouseEntered(MouseEvent evt){}
public void mouseExited(MouseEvent evt){}
public void keyReleased(KeyEvent evt){}
public void keyPressed(KeyEvent evt){}
public void keyTyped(KeyEvent evt)
{
int letter = evt.getKeyCode();
if (letter == 13)
{
keyClicked =true;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(keyClicked && mouseClicked)
g.drawLine(50,0,110,120);
}
}
Making a key listener work in a JPanel, will not be so simple, because it is not focusable. (Think about a JTextField, when you write text on it, it is focused). So, in order to make this work you will have to use KeyBindings. In practice, remove the KeyListener implementation from your JPanel, and use KeyBindings.
public class GardenGrows {
public GardenGrows() {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// All swing applications must run on EDT Thread
GardenGrows gg = new GardenGrows();
gg.runIt();
});
}
// makes the frame and handles all properties of the frame
// also instantiates the Garden.java object
public void runIt() {
JFrame frame = new JFrame("Garden");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setBackground(Color.GRAY);
frame.setSize(1200, 700);
frame.setLocation(50, 10);
frame.setResizable(true);
frame.setVisible(true);
Garden gar = new Garden();
frame.getContentPane().add(gar);
}
}
class Garden extends JPanel implements MouseListener {
private boolean mouseClicked;
private boolean keyClicked;
private int xpos;
private int ypos;
public Garden() {
mouseClicked = false;
keyClicked = false;
addMouseListener(this);
setBackground(Color.PINK);
setLocation(50, 50);
setSize(1000, 500);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_5, KeyEvent.SHIFT_MASK),
"percentageClicked");
getActionMap().put("percentageClicked", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
keyClicked = true;
repaint(); // Try to draw the line
}
});
}
public void mousePressed(MouseEvent evt) {
int x = evt.getX();
int y = evt.getY();
if (x >= 50 || x <= 1050 && y <= 50 || y >= 550) {
mouseClicked = true;
repaint(); // Try to draw the line
}
}
public void mouseClicked(MouseEvent evt) {
}
public void mouseReleased(MouseEvent evt) {
}
public void mouseEntered(MouseEvent evt) {
}
public void mouseExited(MouseEvent evt) {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (keyClicked && mouseClicked)
g.drawLine(50, 0, 110, 120);
}
}
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 am trying to create a panel with pictures that are changed with the mouse.
I have 10 images (0.png to 9.png). My problem is, I want to move image and I am currently viewing the second picture. I used the JScrollPane to scroll back to the first image, but only the first image is moving. How can I refresh my panel and be able to move all images?
This is my code:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
class MapFrame extends JPanel {
/**
*
*/
private static final long serialVersionUID = (long) 1.0;
private static Image image;
private static JLabel label = new JLabel();
private static int ind =0;
private static JFrame frame;
private static String str;
//-----------------------------------------------------------------
public MapFrame(){ }
//-----------------------------------------------------------------
public MapFrame(String pathe) {
super(new BorderLayout());
image = new ImageIcon(getClass().getResource(pathe)).getImage();
label = new JLabel(new ImageIcon(image));
JScrollPane scroll = new JScrollPane(label,JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
add(scroll);
HandLcalss hand = new HandLcalss(label);
JViewport v = scroll.getViewport();
v.addMouseListener(hand);
v.addMouseMotionListener(hand);
v.addMouseWheelListener(hand);
}
//-----------------------------------------------------------------
public static void ShowGUI(String pathe) {
frame = new JFrame("Bladi_map");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new MapFrame(pathe));
frame.setSize(500,400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
//-----------------------------------------------------------------
public static void ChangImage(String pathe){
frame.getContentPane().add(new MapFrame(pathe));
label.revalidate();
frame.setVisible(true);
}
//-----------------------------------------------------------------
class HandLcalss implements MouseListener,MouseMotionListener,MouseWheelListener{
private static final int DELAY = 10;
private Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
private Timer scroller;
private JComponent label;
private Point startPt = new Point();
private Point move = new Point();
//-----------------------------------------------------------------
public HandLcalss(JComponent comp) {
this.label = comp;
comp.getCursor();
this.scroller = new Timer(DELAY, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
}
//-----------------------------------------------------------------
#Override public void mouseDragged(MouseEvent e) {
JViewport vport = (JViewport)e.getSource();
Point pt = e.getPoint();
int dx = startPt.x - pt.x;
int dy = startPt.y - pt.y;
Point vp = vport.getViewPosition();
vp.translate(dx, dy);
label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
startPt.setLocation(pt);
}
#Override
public void mousePressed(MouseEvent e) {
((JComponent)e.getSource()).setCursor(hc);
startPt.setLocation(e.getPoint());
move.setLocation(0, 0);
scroller.stop();
}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
if (notches < 0) {
ind++;
if(ind <0){ind=0;}
if(ind<=9){
str="/resources/"+ind+".png";
ChangImage(str);
System.out.println("indink"+str);
}
} else {
ind--;
if(ind >9){ind=8;}
if(ind>=0){
str="/resources/"+ind+".png";
ChangImage(str);
System.out.println("ind"+ind);
}
}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
//-----------------------------------------------------------------
}
This is the main class:
public class main {
public static void main(String[] args) {
MapFrame.ShowGUI("/resources/0.png");
}
}
You have 2 problems in your code:
The first:
public static void ChangImage(String pathe){
frame.getContentPane().add(new MapFrame(pathe));
label.revalidate();
frame.setVisible(true);
}
When you change image (invoked on mouse wheel event) you simply add new panel (MapFrame) with image to existing container: (Container pane = frame.getContentPane()). The old ones are still there and are overlapping with the new panel. The above method should be:
public static void ChangImage(String pathe) {
frame.getContentPane().removeAll();
frame.getContentPane().add(new MapFrame(pathe));
label.revalidate();
frame.setVisible(true);
}
The second thing:
Why complicate? (also there is an error on 0 value of ind):
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation() * -1;
ind += notches;
if(ind < 0) {
ind = 0;
}
else if(ind > 9) {
ind = 9;
}
str = "/resources/" + ind + ".png";
ChangImage(str);
}
And the last thing:
If you are implementing all mouse interfaces - you can extend MouseAdapter. Now you needn't override methods you don't want.