I made a Frame which repaints itself when I click on it(also the new geometric figure is painted) but when I click rapidly It does not responds so fast, it needs like half a sec beetween clicks. What have I done wrong?
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import javax.swing.JOptionPane;
public class Okienko extends Frame implements MouseListener{
public static final int SIZE = 500;
public static int mX = 0,mY = 0;
public ArrayList<Wyrysowywalny> l; //COLLECTION OF OBJECT TO DRAW
Okienko(){
l = new ArrayList<Wyrysowywalny>();
createGUI();
}
public void createGUI(){
setSize(SIZE, SIZE);
setVisible(true);
setAlwaysOnTop(true);
setTitle("Zadanie 1");
addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent arg0) {}
public void windowIconified(WindowEvent arg0) {}
public void windowDeiconified(WindowEvent arg0) {}
public void windowDeactivated(WindowEvent arg0) {}
public void windowClosed(WindowEvent arg0) {}
#Override
public void windowClosing(WindowEvent arg0) {
JOptionPane.showConfirmDialog(null, "dziekujemy za skorzystanie z programu","",JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
#Override
public void windowActivated(WindowEvent arg0) {
repaint();
}
});
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {/// IMPORTANT!
System.out.println(e.getX() + " " + e.getY());
mX = e.getX();
mY = e.getY();
int r;
r = (int) (Math.random() * 6);
switch(r){
case 0: l.add(new Trojkat(mX,mY,lXY(),lXY(),lXY(),lXY()));break; // OBJECTS TO DRAW
case 1: l.add(new Prostokat(mX,mY,lR(),lR()));break;
case 2: l.add(new Kwadrat(mX,mY,lR()));break;
case 3: l.add(new Kolo(mX,mY,lR()));break;
case 4: l.add(new Elipsa(mX,mY,lR(),lR())); break;
case 5: l.add(new TrojkatRownoboczny(mX,mY,lR())); break;
}
repaint();
}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
public static int lXY(){
return (int) (Math.random()*SIZE * 4d/5 + 1d/40*SIZE);
}
public static int lR(){
return (int) (Math.random()*200 - 1d/40*SIZE);
}
public void paint(Graphics g){
super.paint(g);
for(Wyrysowywalny w : l)
w.draw(g);//DRAW OBJECT
}
public static void main(String[] args) {
new Okienko();
}
}
Absent a complete example, I can only make several observations:
Instead of mouseClicked(), which fires when the mouse is released in the same component, you may want to respond to mousePressed().
Also consider MouseAdapter over implements MouseListener.
As mentioned here, "Swing programs should override paintComponent() instead of overriding paint()."
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
A more elaborate example with no perceptible latency is cited here.
Related
I'm not sure why the fr.repaint(); method isn't working here. If I use the set visible false, then set it true after making changes it makes the screen go black which isn't what I'm trying to do.
Any help?
This code is for a school project, so if it's possible please provide somewhat detailed explanation to understand.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
class Main {
static int startingposx;
static int startingposy;
static int endingposx;
static int endingposy;
public static void main(String[] args) {
JFrame fr = new JFrame();
fr.setBounds(10,10,512,512);
fr.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
});
fr.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
startingposx = e.getX();
startingposy = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
endingposx = e.getX();
endingposy = e.getY();
//fr.setVisible(false);// i tried to use this to refresh it but it makes the frame black for a second
JPanel x = new JPanel(){
#Override
public void paint(Graphics g){
g.setColor(Color.RED);
g.fillRect(startingposx-(32-15),startingposy-32,30,30);
g.setColor(Color.BLUE);
g.fillRect(endingposx-(32-15),endingposy-32,30,30);
}
};
fr.add(x);
fr.repaint();// why does this not work??
//fr.setVisible(true);
System.out.print("\033[H\033[2J");
System.out.println("starting pos: " + startingposx+ ","+ startingposy+"\n" + "ending pos: " + endingposx+ "," + endingposy);
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Frame made shorter in height purely to save space in answer
See further comments in the code. Note that the blue rectangle completely covers the red rectangle.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestCustomPaint {
// Don't use static! Make them instances of the x class and give it a constructor
static int startingposx;
static int startingposy;
static int endingposx;
static int endingposy;
public static void main(String[] args) {
JFrame fr = new JFrame();
// this is the wrong size if the content should be square
fr.setBounds(10,10,512,512);
// unused MouseMotionListener removed
fr.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) { }
#Override
public void mousePressed(MouseEvent e) {
startingposx = e.getX();
startingposy = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
endingposx = e.getX();
endingposy = e.getY();
fr.repaint();
System.out.print("\033[H\033[2J");
System.out.println("starting pos: " + startingposx+ ","+ startingposy+"\n" +
"ending pos: " + endingposx+ "," + endingposy);
}
#Override
public void mouseEntered(MouseEvent e) { }
#Override
public void mouseExited(MouseEvent e) { }
});
// This is when the panel should be created and added.
JPanel x = new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(startingposx-(32-15),startingposy-32,30,30);
g.setColor(Color.BLUE);
g.fillRect(endingposx-(32-15),endingposy-32,30,30);
}
};
fr.add(x);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
i am writing a program that when the mouse is clicked, a circle will be drawn. The below code i've wrote so far.
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.event.*;
import java.awt.geom.*;
public class test extends JFrame implements ActionListener, MouseListener {
Shape circle = new Ellipse2D.Float(10, 10, 10, 10);
public test () {
setSize(250,150);
addMouseListener(this);
}
public static void main(String[] args) {
//TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
test frame = new test();
frame.setVisible(true);
}
});
}
public void actionPerformed(ActionEvent ae) {
}
public void drawCircle(int x, int y) {
Graphics g = this.getGraphics();
g.drawOval(x, y, x, y);
g.setColor(Color.BLACK);
g.fillOval(x, y, 2, 2);
}
public void mouseClicked(MouseEvent e) {
drawCircle(e.getX(), e.getY());
repaint();
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
}
The code is a 400X400 jframe, when clicked open display a circle at a half seconds, The problem is that, when i release the mouse, the circle disappear. why?
Change your mouseClick(...) to:
int x, y;
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
Override paint(...):
#Override
public void paint(Graphics g) {
drawCircle(x, y);
}
When you call repaint(), the component gets painted again from scratch. You're circle is wiped away. You will want to override paintComponent(Graphics) which is called every time the component is painted.
this program is suppose to shift the two rectangles by 10 points to the right each time I click on the screen at the x coordinate 300 or greater, but it doesn't, whats the problem?
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* To change this template use File | Settings | File Templates.
*/
public class MasterMind extends JComponent implements ActionListener,MouseListener {
//private MouseEvent me;
private int screenX=0;
private int screenY=0;
private ActionEvent e;
private int xX=10;
public MasterMind() throws IOException {
}
public static void main(String [] args) throws IOException {
JFrame window = new JFrame("Master Mind");
MasterMind game= new MasterMind();
window.add(game);
window.pack();
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setVisible(true);
Timer t = new Timer(30, game);
t.start();
window.addMouseListener(game);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800,600);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.red);
g.drawRect(xX,30,200,200);
g.setColor(Color.red);
g.drawString("x,y coordinates: "+screenX+" , "+screenY,400,100);
g.setColor(Color.blue);
g.drawRect(xX+3, 33, 194, 194);
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
repaint();
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
#Override
public void mouseClicked(MouseEvent e) {
MouseEvent mouseIvent = (MouseEvent) e;
int screenX = mouseIvent.getX();
int screenY = mouseIvent.getY();
System.out.println("screen(X,Y) = " + screenX + "\t" + screenY);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
//To change body of implemented methods use File | Settings | File Templates.
if (screenX>300) {
xX=xX+10; }
//timer animation
repaint();
}
}
I am very new to Java. so please answer in details if I may ask. thank you all.
These lines should be in the mouseClicked method rather than in actionPerformed.
if (screenX > 300) {
xX = xX + 10;
}
immediately before the existing repaint method there. They ensure that X coordinate variable xX is updated for use later in the paintComponent method.
Unrelated but make sure to invoke super.paintComponent(g) as the first statement of paintComponent
Put this ,In your MouseClicked or MousePressed or MouseReleased Method
if(me.getX()>300)
xX=xX+10;
repaint();
I am trying to implement a click and drag method, for which I need mousePressed and mouseReleased events. I will also be using mouseClicked events, so I implemented MouseMotionListener and MouseListener.
However, when I go to write mousePressed, mouseReleased, mouseEntered, mouseExited methods I get the following error:
method mousePressed(MouseEvent) is already defined in class BoingPanel
Here is the entire class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class BoingPanel extends JPanel implements MouseMotionListener, MouseListener {
private int width;
private int height;
private int updateRate=40;
ArrayList<Ball> balls;
ArrayList<Line> lines;
private Container box;
private boolean drag = false;
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public BoingPanel()
{
balls = new ArrayList<Ball>();
balls.add(new Ball(100,0)); // adds test ball
balls.get(0).setXVelocity(5);
balls.add(new Ball(100,0));
balls.add(new Ball(400,50));
lines = new ArrayList<Line>();
lines.add(new Line(0, height, width, height));
gameStart();
}
public BoingPanel(int x, int y)
{
width=x;
height=y;
balls = new ArrayList<Ball>();
balls.add(new Ball(100,0)); // adds test ball
balls.get(0).setXVelocity(5);
balls.add(new Ball(100,0));
balls.add(new Ball(400,50));
lines = new ArrayList<Line>();
box = new Container(width, height);
gameStart();
}
#Override
public void mouseDragged(MouseEvent me) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
public void gameStart() {
// Run the game logic in its own thread.
Thread gameThread = new Thread() {
public void run() {
while (true) {
// Execute one time-step for the game
update();
// Refresh the display
repaint();
// Delay and give other thread a chance
try {
Thread.sleep(1000 /updateRate);
} catch (InterruptedException ex) {}
}
}
};
gameThread.start(); // Invoke GaemThread.run()
}
private void update()
{
for(Ball a:balls) //calls balls updated position
{
a.update(box);
}
}
public void paintComponent(Graphics g)
{
box.paint(g);
for(Ball a:balls) //calls balls updated position
{
a.paint(g);
}
for(Line b:lines) //draws lines
{
b.paint(g);
}
}
public void actionPerformed(ActionEvent e)
{
update(); //changes ball position
repaint(); //refreshes image
}
}
What is causing this error? Thanks!
I would suggest this, just below your variable declarations and before you constructor, isn't helping...
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
You've basically implemented these methods twice. Just before and after the constructor.
Simply remove on of these groups of declarations...
please remove public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { } and then try
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);
}