Java代码中的计时器问题
对于家庭作业,我必须制作一个程序,在这个程序中,一个窗口用三个按钮打开:Drop、Retrieve和Quit。按下drop(下降)按钮时,一个圆圈从显示面板的顶部下降到底部并停留在那里。当按下Retrieve(检索)按钮时,一条线应沿屏幕向下落至圆圈,并目视将圆圈拉回到屏幕顶部 我写了几乎所有我无法让线回到屏幕上的东西,在我的代码中,只有球做了,线保持在那里Java代码中的计时器问题,java,graphics,timer,actionlistener,paintcomponent,Java,Graphics,Timer,Actionlistener,Paintcomponent,对于家庭作业,我必须制作一个程序,在这个程序中,一个窗口用三个按钮打开:Drop、Retrieve和Quit。按下drop(下降)按钮时,一个圆圈从显示面板的顶部下降到底部并停留在那里。当按下Retrieve(检索)按钮时,一条线应沿屏幕向下落至圆圈,并目视将圆圈拉回到屏幕顶部 我写了几乎所有我无法让线回到屏幕上的东西,在我的代码中,只有球做了,线保持在那里 import java.awt.*; import javax.swing.*; public class DisplayWindow
import java.awt.*;
import javax.swing.*;
public class DisplayWindow extends JFrame {
private Container c;
public DisplayWindow() {
super("Display");
c = this.getContentPane();
}
public void addPanel(JPanel p) {
c.add(p);
}
public void showFrame() {
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
我的代码:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class DropPanel extends JPanel implements ActionListener{
Timer ticker1= new Timer(20,this);
int x=150;
int y=0;
Timer ticker2= new Timer(20,this);
int x2=175;
int y2=0;
JButton drop=new JButton("Drop");
JButton retrieve=new JButton("Retrieve");
JButton quit=new JButton("Quit");
public DropPanel(){
setPreferredSize(new Dimension(300,600));
this.add(drop); drop.addActionListener(this);
this.add(retrieve); retrieve.addActionListener(this);
this.add(quit); quit.addActionListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawOval(x,y,50,50);
g.drawLine(x2,0,x2,y2);
}
public void actionPerformed (ActionEvent e){
if(e.getSource() == ticker1){
if (y<550)
y=y+2;
}
if(e.getSource() == drop){
ticker1.start();
}
if(e.getSource()== ticker2){
if (y2<550){
y2=y2+2;
}
if (y2==550) {
ticker1.stop();
y=y-2;
y2=y2-2;
}
}
if(e.getSource() == retrieve){
ticker2.start();
if(y2==550){
y2=y2-2;
}
}
if(e.getSource()==quit){
System.exit(0);
}
repaint();
}
}
代码的格式使其难以阅读,但我认为我发现了错误:
if(e.getSource()== ticker2) {
if (y2<550) {
y2=y2+2;
}
if (y2==550) {
ticker1.stop();
y=y-2;
y2=y2-2;
}
}
if(例如getSource()==ticker2){
如果(y2从分离责任区域开始。试图将所有“行动”逻辑混合到一个方法中不仅是糟糕的设计,还会给你带来很多混乱
每个计时器都应该有自己的ActionListener
。这意味着您可以单独隔离逻辑并专注于自己的工作单元,而不必不必要地混合其他对象的状态
例如
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DropBall {
public static void main(String[] args) {
new DropBall();
}
public DropBall() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton dropButton;
private JButton retrieveButton;
private AnimationPane animationPane;
public TestPane() {
setLayout(new BorderLayout());
animationPane = new AnimationPane();
add(animationPane);
dropButton = new JButton("Drop");
dropButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (animationPane.canDrop()) {
animationPane.drop();
}
}
});
retrieveButton = new JButton("Retrieve");
retrieveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (animationPane.canRetrieve()) {
animationPane.retrieve();
}
}
});
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonPane.add(dropButton);
buttonPane.add(retrieveButton);
add(buttonPane, BorderLayout.SOUTH);
}
}
public static class AnimationPane extends JPanel {
protected static final int RUN_TIME = 1000;
private Timer dropTimer;
private Timer retrieveTimer;
private Ellipse2D ball;
private long startTime = -1;
private Point ballPoint;
private Point linePoint;
public AnimationPane() {
ball = new Ellipse2D.Float(0, 0, 10, 10);
dropTimer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long duration = System.currentTimeMillis() - startTime;
float progress = (float) duration / (float) RUN_TIME;
if (progress > 1f) {
progress = 1f;
((Timer) e.getSource()).stop();
}
ballPoint = new Point();
ballPoint.x = getWidth() / 2;
ballPoint.y = Math.round(getHeight() * progress);
repaint();
}
});
dropTimer.setRepeats(true);
dropTimer.setCoalesce(true);
dropTimer.setInitialDelay(0);
retrieveTimer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long duration = System.currentTimeMillis() - startTime;
float progress = (float) duration / (float) RUN_TIME;
linePoint = new Point();
linePoint.x = getWidth() / 2;
if (progress < 0.5f) {
linePoint.y = Math.round(getHeight() * (progress * 2));
} else {
if (progress > 1f) {
progress = 1f;
((Timer) e.getSource()).stop();
linePoint = null;
ballPoint = null;
} else {
linePoint.y = Math.round(getHeight() * (progress * 2));
linePoint.y = getHeight() - (linePoint.y - getHeight());
ballPoint.y = linePoint.y;
}
}
repaint();
}
});
retrieveTimer.setRepeats(true);
retrieveTimer.setCoalesce(true);
retrieveTimer.setInitialDelay(0);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (ballPoint != null) {
int x = (int) (ballPoint.x - (ball.getWidth() / 2));
int y = (int) (ballPoint.y - ball.getHeight());
g2d.translate(x, y);
g2d.draw(ball);
g2d.translate(-x, -y);
}
if (linePoint != null) {
int x = getWidth() / 2;
int y = 0;
g2d.drawLine(x, y, linePoint.x, linePoint.y);
}
g2d.dispose();
}
public boolean canDrop() {
return !dropTimer.isRunning() && !retrieveTimer.isRunning() && ballPoint == null;
}
public boolean canRetrieve() {
return !dropTimer.isRunning() && !retrieveTimer.isRunning() && ballPoint != null;
}
public void drop() {
startTime = System.currentTimeMillis();
dropTimer.start();
}
public void retrieve() {
startTime = System.currentTimeMillis();
retrieveTimer.start();
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.FlowLayout;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.geom.Ellipse2D;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共级吊球{
公共静态void main(字符串[]args){
新落球();
}
公共投球{
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私有JButton下拉按钮;
私有JButton检索按钮;
私有动画窗格动画窗格;
公共测试窗格(){
setLayout(新的BorderLayout());
animationPane=新建animationPane();
添加(动画窗格);
dropButton=新按钮(“Drop”);
addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
if(animationPane.canDrop()){
animationPane.drop();
}
}
});
retrieveButton=新的JButton(“Retrieve”);
retrieveButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
if(animationPane.canRetrieve()){
animationPane.retrieve();
}
}
});
JPanel buttonPane=newjpanel(newflowlayout(FlowLayout.CENTER));
按钮平面。添加(dropButton);
按钮平面。添加(检索按钮);
添加(按钮平面,边界布局。南部);
}
}
公共静态类AnimationPane扩展了JPanel{
受保护静态最终整数运行时间=1000;
私人定时器;
私人定时器检索定时器;
私人椭圆球;
私有长startTime=-1;
私人圆珠笔;
专用点线点;
公共动画窗格(){
ball=新的椭圆2d.浮动(0,0,10,10);
dropTimer=新计时器(30,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
长持续时间=System.currentTimeMillis()-startTime;
浮动进度=(浮动)持续时间/(浮动)运行时间;
如果(进度>1f){
进度=1f;
((计时器)e.getSource()).stop();
}
圆珠笔=新点();
ballPoint.x=getWidth()/2;
ballPoint.y=Math.round(getHeight()*进度);
重新油漆();
}
});
dropTimer.setRepeats(真);
dropTimer.setCoalesce(真);
dropTimer.setInitialDelay(0);
retrieveTimer=新计时器(30,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
长持续时间=System.currentTimeMillis()-startTime;
浮动进度=(浮动)持续时间/(浮动)运行时间;
linePoint=新点();
linePoint.x=getWidth()/2;
如果(进度<0.5f){
linePoint.y=Math.round(getHeight()*(progress*2));
}否则{
如果(进度>1f){
进度=1f;
((计时器)e.getSource()).stop();
linePoint=null;
圆珠笔=零;
}否则{
linePoint.y=Math.round(getHeight()*(progress*2));
linePoint.y=getHeight()-(linePoint.y-getHeight());
B
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DropBall {
public static void main(String[] args) {
new DropBall();
}
public DropBall() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton dropButton;
private JButton retrieveButton;
private AnimationPane animationPane;
public TestPane() {
setLayout(new BorderLayout());
animationPane = new AnimationPane();
add(animationPane);
dropButton = new JButton("Drop");
dropButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (animationPane.canDrop()) {
animationPane.drop();
}
}
});
retrieveButton = new JButton("Retrieve");
retrieveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (animationPane.canRetrieve()) {
animationPane.retrieve();
}
}
});
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonPane.add(dropButton);
buttonPane.add(retrieveButton);
add(buttonPane, BorderLayout.SOUTH);
}
}
public static class AnimationPane extends JPanel {
protected static final int RUN_TIME = 1000;
private Timer dropTimer;
private Timer retrieveTimer;
private Ellipse2D ball;
private long startTime = -1;
private Point ballPoint;
private Point linePoint;
public AnimationPane() {
ball = new Ellipse2D.Float(0, 0, 10, 10);
dropTimer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long duration = System.currentTimeMillis() - startTime;
float progress = (float) duration / (float) RUN_TIME;
if (progress > 1f) {
progress = 1f;
((Timer) e.getSource()).stop();
}
ballPoint = new Point();
ballPoint.x = getWidth() / 2;
ballPoint.y = Math.round(getHeight() * progress);
repaint();
}
});
dropTimer.setRepeats(true);
dropTimer.setCoalesce(true);
dropTimer.setInitialDelay(0);
retrieveTimer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long duration = System.currentTimeMillis() - startTime;
float progress = (float) duration / (float) RUN_TIME;
linePoint = new Point();
linePoint.x = getWidth() / 2;
if (progress < 0.5f) {
linePoint.y = Math.round(getHeight() * (progress * 2));
} else {
if (progress > 1f) {
progress = 1f;
((Timer) e.getSource()).stop();
linePoint = null;
ballPoint = null;
} else {
linePoint.y = Math.round(getHeight() * (progress * 2));
linePoint.y = getHeight() - (linePoint.y - getHeight());
ballPoint.y = linePoint.y;
}
}
repaint();
}
});
retrieveTimer.setRepeats(true);
retrieveTimer.setCoalesce(true);
retrieveTimer.setInitialDelay(0);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (ballPoint != null) {
int x = (int) (ballPoint.x - (ball.getWidth() / 2));
int y = (int) (ballPoint.y - ball.getHeight());
g2d.translate(x, y);
g2d.draw(ball);
g2d.translate(-x, -y);
}
if (linePoint != null) {
int x = getWidth() / 2;
int y = 0;
g2d.drawLine(x, y, linePoint.x, linePoint.y);
}
g2d.dispose();
}
public boolean canDrop() {
return !dropTimer.isRunning() && !retrieveTimer.isRunning() && ballPoint == null;
}
public boolean canRetrieve() {
return !dropTimer.isRunning() && !retrieveTimer.isRunning() && ballPoint != null;
}
public void drop() {
startTime = System.currentTimeMillis();
dropTimer.start();
}
public void retrieve() {
startTime = System.currentTimeMillis();
retrieveTimer.start();
}
}
}