Reputation: 5
I am writing a GUI that is supposed to write lines and circles to a panel and I am supposed to use sliders to change how fast they add to the panel. I am supposed to add a clear button that will clear the entire panel and then when I move the sliders they should make the circles and lines begin to write on the panel again. There should be a specific stop point at the beginning of the sliders. We have been told to do this without actionlisteners on the sliders. I am having some trouble understanding how to make that work.
Below are the requirements for the assignment: Write a Swing program that provides the following functionality:
Draw random length lines of random color at random coordinates with pauses between the drawing of each line.
Allow the user to set the length of the pause between lines with a slider. Have the slowest value actually stop drawing lines (i.e., it slows to a stop once it is at that value on the slider).
Have a clear button that clears all the lines & circles. Be sure that the clear button is operational at all times.
Draw random size circles of random color at random coordinates with pauses between the drawing of each circle. (Use draw, not fill.)
Allow the user to set the length of the pause between circles with a slider. Have the slowest value actually stop drawing circles (i.e., it slows to a stop once it is at that value on the slider). This is independent of the lines' speed.
The circles and lines are both drawn independently, each in their own Thread. Do not use Timer for this, extend Thread and/or Runnable.
public class OhMy extends JFrame
{
private static final int MAX_COLOR = 225;
private static final long STOP_SLEEP = 0;
public OhMy()
{
this.setTitle("Oh My Window");
Container canvas = this.getContentPane();
canvas.setLayout(new GridLayout(2,1));
JPanel panControl = new JPanel(new GridLayout(1,1));
JPanel panDraw = new JPanel(new GridLayout(1,1));
canvas.add(panControl);
canvas.add(panDraw);
panControl.add(createPanControl());
panDraw.add(createPanDraw());
this.setSize(800, 600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JPanel createPanControl()
{
JPanel panControl = new JPanel();
JLabel lines = new JLabel("Lines");
panControl.add(lines);
lines.setForeground(Color.RED);
JSlider sldSpeedLines = new JSlider(1, 30, 5);
panControl.add(sldSpeedLines);
JButton btnClear = new JButton("Clear");
panControl.add(btnClear);
btnClear.setForeground(Color.RED);
JSlider sldSpeedCircles = new JSlider(0, 30, 5);
panControl.add(sldSpeedCircles);
JLabel circles = new JLabel("Circles");
panControl.add(circles);
circles.setForeground(Color.RED);
btnClear.addActionListener((e)->
{
repaint();
});
return panControl;
}
private JPanel createPanDraw()
{
JPanel panDraw = new JPanel();
class LinesThread extends Thread
{
@Override
public void run()
{
try
{
Graphics g = panDraw.getGraphics();
while(g == null)
{
Thread.sleep(STOP_SLEEP);
g = panDraw.getGraphics();
}
Random rand = new Random();
int red = rand.nextInt(MAX_COLOR);
int green = rand.nextInt(MAX_COLOR);
int blue = rand.nextInt(MAX_COLOR);
Color color = new Color(red, green, blue);
int x1 = rand.nextInt(panDraw.getWidth());
int y1 = rand.nextInt(panDraw.getHeight());
int x2 = rand.nextInt(panDraw.getWidth());
int y2 = rand.nextInt(panDraw.getHeight());
g.setColor(color);
g.drawLine(x1, y1, x2, y2);
}
catch(InterruptedException e1)
{
//awake now
}
}
}
return panDraw;
}
/**
* @param args
*/
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new OhMy();
}
});
}
}
Upvotes: 0
Views: 82
Reputation: 285403
You state:
"We have been told to do this without actionlisteners on the sliders..."
getValue()
on it. getGraphics()
on the JPanel since the Graphics object thus obtained will not be stable risking a broken image, or worse, a NullPointerException (to see what I mean, minimize and restore your current application while its drawing).Edit
Thanks to Abishek Manoharan for pointing out problems in my answer...
SwingUtilities.invokeLater(...)
and pass in a Runnable that has your Swing call.Upvotes: 2