i need your help badly because i cannot solve this problem on my own. I am trying to create a GUI and want to draw something in it after pressing a button, but i seem to ha
Java doesn't remember drawing commands for you; your graphic is rendered once when you click the button because that's the only time when draw()
is called.
If you want to refresh the rendering after a resize, override paint(Graphics)
and call draw()
in there.
If that is related to the button click, you must add fields to your class in which you remember everything that you need in draw()
including the fact whether it should draw anything:
private boolean drawAtAll = false;
private void jButton1ActionPerformed(ActionEvent evt) {
drawAtAll = true; // ok to draw now
draw();
}
@Override
public void paint(Graphics g) {
super.paint(g);
draw();
}
public void draw() {
if( !drawAtAll ) return;
Graphics g = jPanel1.getGraphics();
...
}
Further reading:
Try your hands on this code, and ask any questions that may arise, do painting inside the paintComponent(...) method of the JPanel. Instead of providing size everytime for the said JComponent
you can simply override getPreferredSize(), of the said component. In order to call your paintComponent(...)
you can simply write repaint()
instead of explicitly making a call to paintComponent(...)
from within your program, Swing will do that automatically.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintingExample
{
private CustomPanel paintingPanel;
private Timer timer;
private int x = 1;
private int y = 1;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
x++;
y++;
paintingPanel.setPosition(x, y);
}
};
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Painting Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
paintingPanel = new CustomPanel();
final JButton startStopButton = new JButton("STOP");
startStopButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (timer.isRunning())
{
startStopButton.setText("START");
timer.stop();
}
else if (!timer.isRunning())
{
startStopButton.setText("STOP");
timer.start();
}
}
});
frame.add(paintingPanel, BorderLayout.CENTER);
frame.add(startStopButton, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(100, timerAction);
timer.start();
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PaintingExample().createAndDisplayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
private int x = 0;
private int y = 0;
@Override
public Dimension getPreferredSize()
{
return (new Dimension(800, 600));
}
public void setPosition(int a, int b)
{
x = a;
y = b;
if (x <(getWidth() - 10) && y < (getHeight() - 10))
repaint();
else
System.out.println("Nothing is happening...");
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.MAGENTA);
g.fillOval(x, y, 10, 10);
}
}
I did not went through all of your code, but what is immediately visible is that you should not override the paintComponent
method without calling super.paintComponent
. And your commented out line calls super.paintComponents
(note the s), which is not the same.
I am also unsure what you mean 'when I resize the window', and how that is tied together with your Jpanel1.setSize( 1000, 1000 )
calls which appear all over your code. Your layout manager will take care of the size of the panel. You should not set that to a fixed size.
When you resize your panel or change it position or minimize it and maximize it, a paint(...)
method is called that repaints the content. You have to overwrite this function and let it paint your line or what ever. To do this, you must probably save your drawing in a data-structure to be able to repaint it when every necessary.
The paint method is described here.