I want to understand this code
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class pinpon extends JFrame {
private Image image;
private Graphics graph;
int x , y ;
public class klavye extends KeyAdapter{
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
if (key == e.VK_LEFT)
x=x-5;
if (key == e.VK_RIGHT)
x=x+5;
if (key == e.VK_UP)
y=y-5;
if (key == e.VK_DOWN)
y=y+5;
}
public void keyReleased(KeyEvent e){
}
}
public pinpon(){
addKeyListener(new klavye());
setSize(640, 480);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x=150;
y=150;
}
public void paint(Graphics g){
image = createImage(getWidth(), getHeight());
paintComponent(image.getGraphics());
g.drawImage(image,0,0,this);
}
public void paintComponent(Graphics g){
g.fillOval(x, y, 15, 15);
repaint();
}
public static void main(String[] args) {
new pinpon();
}
}
but in here i thing this code is for double buffering
public void paint(Graphics g){
image = createImage(getWidth(), getHeight());
paintComponent(image.getGraphics());
g.drawImage(image,0,0,this);
}
This code is used for moving ball without any trace of ball. But i did not understand how is it works. Can anybody help me. Or tell me where can i find any explanation. Thanks.
But i did not understand how is it works
Me either and you should not even worry about what it is doing because that code is completely wrong and should NOT be used for several reasons:
you would never invoke paintComponent() directly
you would never invoke repaint() in a painting method. This will cause an infinite loop
custom painting is done by overriding the paintComponent() method only. You don't need to override paint().
Read the section from the Swing tutorial on Custom Painting for explanations and examples of how painting SHOULD be done.
Once you understand the basics of painting properly then you can move on to getting rid of the KeyListener. Instead you should be using Key Bindings. All Swing components use Actions and Key Bindings to handle specific keyboard input from the user. Check out Motion Using the Keyboard for more information and working examples.
Related
We recently started using Applet and doing stuff with it, so the last class was on drawing lines. So after writing a successful code i changed a line of code for some reason unbeknownst to me and now it does not draw a line, rather draws a weird ray sort of.
Here is the code so any help would be appreciated.
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
public class SimplePaint extends Applet {
private int lastx;
private int lasty;
#Override
public void init() {
this.setForeground(Color.BLUE);
this.addMouseListener(new PositionRecorder());
this.addMouseMotionListener(new LineDrawer());
}
public int getLastx() {
return lastx;
}
public void setLastx(int lastx) {
this.lastx = lastx;
}
public int getLasty() {
return lasty;
}
public void setLasty(int lasty) {
this.lasty = lasty;
}
private class PositionRecorder extends MouseAdapter{
public void mousePressed(MouseEvent e) {
setLastx(e.getX());
setLasty(e.getY());
}
}
private class LineDrawer extends MouseMotionAdapter{
public void mouseDragged(MouseEvent e) {
int x=e.getX();
int y=e.getY();
Graphics g;
g=getGraphics();
g.drawLine(lastx, lasty, x, y);
}
}
}
I distinctively remember messing with this part of code if that helps
private class PositionRecorder extends MouseAdapter{
public void mousePressed(MouseEvent e) {
setLastx(e.getX());
setLasty(e.getY());
Painting in AWT is a well documented process. You should start by reading through:
Painting in AWT and Swing, in particular, I suggest you read the section on The Paint Method
A Closer Look at the Paint Mechanism
Quoted from "A Closer Look at the Paint Mechanism"
the paint method (defined by java.awt.Component.) This method will be executed by the painting subsystem whenever you component needs to be rendered.
In AWT, painting is destructive, it is expected that any time paint is called, that you will completely repaint the component state. This raises a number of issue which you will need to solve.
For anything you need to paint, you need a reliable way to store those states and reapply them when paint is called. In you case, something as simple as an ArrayList would be suitable, but you could also use a BufferedImage as a backing buffer and draw the committed drawing elements to it.
The benefit of the first approach is to provides the ability to undo changes, but in terms of painting, isn't as fast as simply painting an image.
A more clever approach would be to use both. Maintaining the draw states in a ArrayList, rendering each one as it's committed to the BufferedImage and when you want to perform an undo, start with a new BufferedImage and paint all the states up to the point you don't need...but that's all beyond the scope of the question
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
public class SimplePaint extends Applet {
private Point clickPoint;
private Point dragPoint;
#Override
public void init() {
this.setForeground(Color.BLUE);
this.addMouseListener(new PositionRecorder());
this.addMouseMotionListener(new LineDrawer());
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (clickPoint != null && dragPoint != null) {
g.drawLine(clickPoint.x, clickPoint.y, dragPoint.x, dragPoint.y);
}
}
private class PositionRecorder extends MouseAdapter {
public void mousePressed(MouseEvent e) {
clickPoint = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent e) {
// This is where I'd reset the clickPoint and dragPoint
// to null and apply the line to some structure which can
// redraw it in the `paint` method, maybe something like
// a ArrayList
// Alternativly, you could render the result to a BufferedImage
// and paint that inside the paint method
}
}
private class LineDrawer extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
dragPoint = e.getPoint();
repaint();
}
}
}
I'm trying to get my minigame, (paint) to detect keyboard clicks, I.e, Up arrow key to continue the line of an oval. The problem is that when I run the program and enter the up arrow key, or down or left or right, the program doesn't do anything. Please help.
Here's all the code:
package MiniGame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class GameTest extends JFrame{
int x;
int y;
//This class detects the keys pressed.
public class Actionlistener extends KeyAdapter{
public void KeyPressed(KeyEvent ke){
int Listen = ke.getKeyCode();
if(Listen == ke.VK_UP ) {y--;}
if(Listen == ke.VK_LEFT) {x--;}
if(Listen == ke.VK_DOWN) {y++;}
if(Listen == ke.VK_RIGHT){x++;}
}
public void KeyReleased() {
//There's no code here yet.
}
}
//The constructor that initialises some components.
public GameTest() {
addKeyListener(new Actionlistener());
setTitle("Game Test");
setSize(750, 750);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
x = 150;
y = 150;
} //Paint method.
public void paint(Graphics g) {
g.fillOval(x, y, 20, 20);
repaint();
}
//Creating an object
public static void main(String[] args){
new GameTest();
}
}
Don't use a KeyListener! Swing was designed to be used with Key Bindings.
See Motion Using the Keyboard for more information why you should NOT use a KeyListener and working examples of Key Bindings to get you started.
I am making a molecule designing application. I can draw the lines and circles, but it clears the old lines each time you click, so basically, you can only design molecules with 2 atoms.
Also, the mouseEvents don't deliver if you click very fast which is also a problem.
Here is the code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class MoleculeDesigner extends JComponent implements MouseListener {
private Point op, cp;
private boolean first = true;
public static final Color linecolor = new Color(0, 255, 0);
private static final long serialVersionUID = 1L;
private BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
public MoleculeDesigner() {
JFrame f = new JFrame("Molecule Designer");
f.setBackground(Color.WHITE);
f.addMouseListener(this);
f.add(this);
f.setSize(100, 100);
f.setDefaultCloseOperation(3);
f.setVisible(true);
}
public static void main(String[] args) {
new MoleculeDesigner();
}
#Override
protected void paintComponent(Graphics g) {
if(op != null && cp != null) {
Graphics2D g2 = img.createGraphics();
super.paintComponent(g2);
g2.setColor(linecolor);
g2.drawLine((int) op.getX(), (int) op.getY(), (int) cp.getX(), (int) cp.getY());
g2.setColor(Color.BLACK);
g2.fillOval((int) cp.getX(), (int) cp.getY(), 10, 10);
op = (Point) cp.clone();
g2.dispose();
}
}
#Override
public Dimension getPreferredSize() {
return getParent().getMaximumSize();
}
#Override
public void mouseClicked(MouseEvent e) {
if(!first) {
cp = e.getPoint();
cp.setLocation(cp.getX(), cp.getY() - 8);
}
else {
op = e.getPoint();
first = false;
}
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) {}
}
All help appreciated!
Either 1) draw in a BufferedImage which is then displayed inside of your paintComponent override, or 2) put your data into an ArrayList or other collection, and then iterate through the collection inside of paintComponent. I'd do the latter if I needed the data for other purposes. Also, never ever do this:
public void update(Graphics g) {
paintComponent(g);
}
This is not how Swing graphics are supposed to be done and is potentially dangerous code. Please read:
Basic Swing Graphics Tutorial
Advanced Swing Graphics Information
Edit
More detail regarding option 1:
Create a BufferedImage using one of its constructors.
Do your drawing on the image.
When you need to draw, get a Graphics object from the BufferedImage using getGraphics() or createGrahpics() (for a Graphics2D object)
Draw with this Graphics object
Then dispose() the Graphics object.
Then call repaint() to ask the JVM to repaint the component.
Draw the image in your paintComponent method by calling g.drawImage(...), passing in your buffered image.
Benefits: often the drawing is quicker, and I often use this to draw background images.
Drawbacks: the data points are not available, and so if you need to do manipulation or animation of your data points, this is not the way to go.
You don't, nor should you.
paint in Swing is a destructive process, this is the way it was designed. That is, there is an expectation that when you component is requested to paint itself, it will clean up the Graphics context before painting anything (this is slightly different for transparent components though).
Swing has no concept of what was painted on your component before and because the Graphics context is shared amongst all the components been painted, unless you clear the graphics first, you could end up with unwanted paint artifacts
Possible solutions might include...
Painting to some kind of backing buffer (such as a BufferedImage), which you use the paintComponent method to draw. This is limited in the fact that it just acts like a paint program, painting pixels to the image. You will also need to provide functionality when the size of the viewable area changes, as the BufferedImage won't know.
Place each object you wanted painted into some kind of List and iterate this list when paintComponent is called. This is a little more flexible in that you can control the order of the objects drawn, remove objects and insert new ones where you like
Thanks for checking out this Question. I think I've just about scratched through my skull in frustration.
So what I've got is a 'JFrame' containing a 'JPanel'. The 'JPanel' contains a little colored Square which is supposed to move X pixels whenever I click the window.
Well, essentially everything behaves as it should, with one exception. When the blue square moves to the right, it leaves a trail of other squares behind it. It is not supposed to leave the trail, however, when I re-size the window, the trail vanishes.
Catalyst.java
package Prototype;
import java.awt.*;
public class Catalyst {
public static void main(String[] args){
World theWorldInstance = new World("Prototype", 100,100, 600,100); /*title,xpos,ypos,width,height*/
}
}
World.java
package Prototype;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class World extends JFrame {
Level mainPanel;
public World(String title, int x, int y, int width, int height) {
setTitle(title);
setBounds(x,y,width,height);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBackground(new Color(0x00000000));
initLevel();
}
public void initLevel(){
mainPanel = new Level();
Container visibleArea = getContentPane();
visibleArea.add(mainPanel);
setVisible(true);
add(mainPanel);
}
}
Level.java
package Prototype;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Level extends JPanel implements MouseListener, ActionListener {
Square x;
public Level() {
System.out.println("This is working correctly[JPANEL Cons]");
addMouseListener(this);
x = new Square();
}
public void paintComponent(Graphics g){
x.draw(g);
}
public void actionPerformed(ActionEvent e){
}
public void mousePressed(MouseEvent e){
requestFocus();
x.move();
repaint();
System.out.println("Focus Acquired");
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
}
Square.java
package Prototype;
import java.awt.*;
public class Square {
private Point position;
private int size;
private final int displacement;
public Square(){
position = new Point(10,10);
size = 20;
displacement = 5;
}
public void draw(Graphics g){
g.setColor(Color.blue);
g.fillRect(position.x-(size/2), position.y-(size/2), size,size );
g.setColor(Color.black);
g.drawRect(position.x-(size/2), position.y-(size/2), size,size );
}
public void move() {
position.x += displacement;
}
}
Those are all my files. I hope I've phrased everything properly and provided all the content required. Whenever I've done something similar in the past this has never happened. I assume I'm missing something small, or I've done something stupid. If you can help me, thanks in advance!
There's another way of doing this. You can simply call the parent object's paintComponent method to clear the panel.
Add this to your constructor in Level :
this.setBackground(Color.BLACK);
And this as the first call in paintComponent:
super.paintComponent(g);
You can use g.clearRect(x, y, width, height), and provide the said coordinates, where you want the painting to be cleared from. Or you can give the dimensions of whole of the JPanel/JComponent where you are drawing, though doing this keep one thing in mind, that the said drawing is not a heavy work, else too much of cleaning will put extra burden on the painting calls.
I can't post any code right now, since the computer I'm programming on has no internet connection, and I absolutely refuse to write it out on this phone.
Basically, I have a JPanel (which implements mouseListener), which contains a Component in its contentPane. The JPanel is listening for mouse events on the Component.
When I draw to the panel, it works fine except that the area under the Component (which is visible but not painting anything) just shows the Panel's background (a standard colour fill) and not the image I drew on top of it.
I get the feeling that I'm missing something fundamental to do with mouseListeners...
OK, here's the whole class, now that my computer's working as intended again:
(Also, it seems I was using Labels, not Components. Sorry about that.)
import java.awt.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ComponentEvent;
import java.util.*;
public class PictureViewer extends Container implements MouseListener, ComponentListener
{
java.util.List<Image> images;
public Component leftSide, rightSide;
int currentImage;
boolean leftMoused, rightMoused;
boolean mouseDown;
Image leftTab, rightTab, noImage;
public PictureViewer()
{
setVisible(true);
setBackground(Color.BLUE);
addComponentListener(this);
images = new ArrayList<Image>();
leftSide = new Label();
leftSide.setLocation(0, 0);
leftSide.setSize(getWidth() / 2, getHeight());
leftSide.addMouseListener(this);
add(leftSide);
rightSide = new Label();
rightSide.setLocation(getWidth() / 2, 0);
rightSide.setSize(getWidth() / 2, getHeight());
rightSide.addMouseListener(this);
rightSide.setVisible(false);
add(rightSide);
noImage = Toolkit.getDefaultToolkit().getImage(getClass().getResource("Images/No Picture.png"));
leftTab = Toolkit.getDefaultToolkit().getImage(getClass().getResource("Images/Left Tab.png"));
rightTab = Toolkit.getDefaultToolkit().getImage(getClass().getResource("Images/Right Tab.png"));
}
public void addImage(Image image)
{
images.add(image);
}
public void clear()
{
images.clear();
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Image imageToDraw;
if (images.size() > 0)
{
imageToDraw = images.get(currentImage);
}
else
{
imageToDraw = noImage;
}
g2d.drawImage(imageToDraw, getX(), getY(), getWidth(), getHeight(), 0, 0, imageToDraw.getWidth(this), imageToDraw.getHeight(this), this);
g2d.draw(new Rectangle(0, 0, 20, 20));
if (leftMoused)
{
g2d.drawImage(leftTab, getX() + 8, getY() + (int)(getSize().getHeight() - leftTab.getHeight(this) / 2), this);
}
}
public void componentHidden(ComponentEvent e){}
public void componentShown(ComponentEvent e){}
public void componentMoved(ComponentEvent e)
{
componentResized(e);
}
public void componentResized(ComponentEvent e)
{
leftSide.setLocation(getLocation());
leftSide.setSize(getWidth() / 2, getHeight());
rightSide.setLocation((int)(getLocation().getX() + (getWidth() / 2)), (int)getLocation().getY());
rightSide.setSize(leftSide.getSize());
System.out.println(getSize());
repaint();
}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseEntered(MouseEvent e)
{
if (e.getComponent() == leftSide){
leftMoused = true;
System.out.println("Left");}
else {
rightMoused = true;
System.out.println("Right");}
repaint();
}
public void mouseExited(MouseEvent e)
{
if (e.getComponent() == leftSide)
leftMoused = false;
else
rightMoused = false;
repaint();
}
}
The component will also have a paintComponent method which by default will paint the container's background. You will need to override the method, setOpaque to false (depending on the component), or something else to keep painting from happening.
However, it sounds like what you really want is to add mouse listener to the panel and have it listen to a defined boundary instead the panel rather than adding a component to the panel.
I can't post any code right now
You wrote custom code that doesn't work and you expect us to guess what that code looks like? We don't have time to spend guessing what mistake you might have made. The point of the forums is to make it easy for us to answer the question which means you need to provide all the information we need to help solve the problem.
That is why you need to provide a SSCCE that demonstrates the problem.