My problem that I am having is that in this code, the line will not draw at all if I get rid of the JLabel from it. I tested it out and without the JLabel stuff with in it, the paintComponent(Graphics g) won't run at all. I want to know why this is and why JLabel effects the JPanel like this.
I have read online that sometime the paintComponent(Graphics g) might not run if it is in a infinite loop but i still don't understand how the JLabel would effect this trait.
I would guess that it might have to do something with the layout but i don't really understand how layout effects things like this
MouseAction Class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseAction extends JFrame{
private JPanel mousePanel;
private JLabel statusBar;
private GraphicsPanel g;
private int xS;
private int yS;
public MouseAction (){
super("Mouse example");
mousePanel = new JPanel();
statusBar = new JLabel("Deafault");
g = new GraphicsPanel(0,0,0,0);
add(mousePanel, BorderLayout.CENTER);
add(statusBar, BorderLayout.SOUTH);
MouseExploits handler = new MouseExploits();
mousePanel.addMouseListener(handler);
mousePanel.addMouseMotionListener(handler);
}
private class MouseExploits extends MouseAdapter{
public void mousePressed(MouseEvent mouse){
if(mouse.isMetaDown()){
xS= mouse.getX();
yS= mouse.getY();
}
}
public void mouseDragged(MouseEvent mouse){
if(!(mouse.isMetaDown() || mouse.isAltDown())){
g.updateCoordinates(mouse.getX(),mouse.getY(), xS,yS);
add(g);
System.out.printf("%d,%d\n",mouse.getX(),mouse.getY());
statusBar.setText(String.format("%d,%d",mouse.getX(),mouse.getY()));
}
}
}
}
GraphicsPanel class
import java.awt.*;
import javax.swing.*;
public class GraphicsPanel extends JPanel{
private int x;
private int y;
private int xS;
private int yS;
private Graphics dB;
private Image dBImage;
public graphics(int mouseX, int mouseY, int xSm, int ySm){
x = mouseX;
y = mouseY;
xS=xSm;
yS=ySm;
//System.out.println("Breaks2");
}
public void updateCoordinates(int mouseX, int mouseY, int xSm, int ySm){
x = mouseX;
y = mouseY;
xS=xSm;
yS=ySm;
//repaint();
}
public void paint(Graphics g){
dBImage = createImage(getWidth(),getHeight());
dB = dBImage.getGraphics();
paintComponent(dB);
g.drawImage(dBImage,0,0,this);
}
public void paintComponent(Graphics g){
//super.paintComponent(g);
System.out.println("Breaks3");
g.drawLine(xS,yS,x,y);
repaint();
}
}
MainProg class
import javax.swing.JFrame;
public class MainProg {
public static void main(String args[]){
MouseAction frameObj= new MouseAction ();
frameObj.setSize(300,230);
frameObj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameObj.setVisible(true);
}
}
EDIT: Code now contains double buffering and been revamped so the GraphicsPanel doesn't instantiate multiple of time how ever the issue of not be able to remove JLabel without breaking the program continues.
EDIT 2: after some messing around with the window after removing the JLabel, It seems to only work when i dragged on the screen,resized the window and then drag on the screen again. So it would seem there is some jpanel layout error which some how gets fixed by the jlabel being there.
First problem with your code is that you instanciate
graphics
at eachmouseDragged
event. This is weird and bad. You must only handle eachmouseDragged
, store the coordinates and callrepaint
on the singlegraphics
instance created and added to the interface at the beginning. This will cause a refresh.Second, the
paintComponent
should just make the drawings so you must use some kind of (1) double buffering (create a off-lineBufferedImage
and its associatedGraphics
, draw into it and use it in the refresh), (2) collection ofPoint
caught inmouseDragged
and use them todrawPolyline
in thepaintComponent
method.Third don't call
repaint()
insidepaintComponent
. This will unnecessarily triggers calls topaintComponent
in a kind of never ending loop.Fourthly don't create a double buffer each time
paint
is called. At each refresh you will create a newImage
. Create it once, draw in it in yourmouseDragged
method and trigger from it arepaint()
, then make adrawImage
inpaintComponent
.