我正在编写一个应该在面板上写行和圆圈的GUI,我应该使用滑块来改变它们添加到面板的速度。我应该添加一个清除整个面板的清除按钮,然后当我移动滑块时,它们应该使圆圈和线条再次开始在面板上写入。滑块开头应该有一个特定的停止点。我们被告知要在滑块上没有动作滑块的情况下执行此操作。我在理解如何完成这项工作时遇到了一些麻烦。
以下是作业的要求: 编写一个提供以下功能的Swing程序:
在随机坐标处绘制随机颜色的随机长度线,每条线的绘图之间有暂停。
允许用户使用滑块设置线条之间的暂停长度。让最慢的值实际上停止绘制线条(即,一旦它在滑块上的值处于减速状态,它就会减速。)
有一个清除按钮,清除所有线条&界。确保清除按钮始终可用。
在随机坐标处绘制随机颜色的随机大小圆圈,每个圆圈的绘图之间有暂停。 (使用绘制,而不是填充。)
允许用户使用滑块设置圆圈之间的暂停长度。让最慢的值实际上停止绘制圆圈(即,一旦它在滑块上的那个值,它就会减慢到停止)。这与线的速度无关。
圆圈和线条都是独立绘制的,每个都在自己的线程中。 不要使用Timer,扩展Thread和/或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();
}
});
}
}
答案 0 :(得分:2)
你说:
“我们被告知要在滑块上没有动作滑块的情况下这样做......”
getValue()
,即可重置图形并从JSliders获取值。 getGraphics()
来获取您的Graphics对象,因为这样获得的Graphics对象不会很稳定,有图像损坏,或者更糟糕的是,NullPointerException(看看我的意思,最小化和恢复)当前申请时的绘图)。 修改强>
感谢Abishek Manoharan在我的回答中指出问题......
SwingUtilities.invokeLater(...)
在Swing事件线程上对其进行排队,并传入一个具有Swing调用的Runnable。