用定时器绘图不工作
Drawing with timer is not working
我在 Java 中绘图时遇到问题。我认为我的代码是正确的,但是当我将它与计时器一起循环时,它不会打印任何内容。我想每秒重复 doDrawing(g) 方法。现在它只会打印文本舞会 system.out 但不会打印绘图。
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import javax.swing.JPanel;
import javax.swing.Timer;
public class surface extends JPanel{
private void doDrawing(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
//souradnice stredu ciferniku
final int sx = 250;
final int sy = 250;
// inicializace promennych
int uhel = 0;
int delka = 150;
int xHodina,xMinuta,xSekunda,
yHodina,yMinuta,ySekunda;
// získání aktuálního času
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1 ;
//výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení
xSekunda = (int) ((int) sx + Math.round( Math.sin(( 6 * SECOND * Math.PI / 180)) * delka));
ySekunda = (int) ((int) sy - Math.round( Math.cos(( 6 * SECOND * Math.PI / 180)) * delka));
//vyhreslení ručiček
g2d.drawLine(sx, sy, xSekunda, ySekunda);
//info
System.out.print(" "+(6 * SECOND)+ " "+ HOUR+" "+MINUTE+" "+SECOND+" "+xSekunda+" "+ySekunda+"\n");
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
int delay = 1000; //milliseconds
//Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing(g);
}
};
new Timer(delay, taskPerformer).start();
}
}
问题就在这里。
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
int delay = 1000; //milliseconds
//Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing(g);
}
};
new Timer(delay, taskPerformer).start();
}
}
切勿在 paintComponent 内部启动计时器。此方法只画画不画,我的意思绝对没有别的。
您应该在其他地方启动您的计时器,也许在 class 的构造函数中,并让它更改您的 class 的字段,然后调用 repaint()
。然后 paintComponent 方法应该使用这些字段来决定绘制什么和在哪里绘制。
例如,您的 doDrawing()
方法(没有 Graphics 参数)可以创建一个 Line2D,将其添加到 List<Line2D>
,然后调用 repaint()
。 paintComponent(...)
方法然后可以遍历此列表绘制每一行:
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.Timer;
public class surface extends JPanel {
private List<Line2D> lineList = new ArrayList<>();
public surface() {
int delay = 1000; // milliseconds
// Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing();
}
};
new Timer(delay, taskPerformer).start();
}
private void doDrawing() {
// souradnice stredu ciferniku
final int sx = 250;
final int sy = 250;
// inicializace promennych
int uhel = 0;
int delka = 150;
int xHodina, xMinuta, xSekunda, yHodina, yMinuta, ySekunda;
// získání aktuálního času
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1;
// výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení
xSekunda = (int) ((int) sx + Math.round(Math
.sin((6 * SECOND * Math.PI / 180)) * delka));
ySekunda = (int) ((int) sy - Math.round(Math
.cos((6 * SECOND * Math.PI / 180)) * delka));
Line2D line = new Line2D.Double(sx, sy, xSekunda, ySekunda);
lineList.add(line);
repaint();
// info
System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " "
+ SECOND + " " + xSekunda + " " + ySekunda + "\n");
}
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
for (Line2D line2d : lineList) {
g2d.draw(line2d);
}
}
}
Edit 不好意思,您只想使用此代码绘制 one 行,而不是行列表。如果是这样,摆脱列表,而是创建一个 Line2D 字段,该字段由您的计时器更改并由您的 paintComponent 绘制:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
// !! Class names should begin with upper-case letter
public class Surface extends JPanel {
private static final double DELKA = 150;
private static final int SX = 250;
private static final int SY = SX;
private static final int DELAY = 1000;
// private List<Line2D> lineList = new ArrayList<>();
private Timer timer = new Timer(DELAY, new TaskPerformer());
private Line2D line;
public Surface() {
timer.start();
}
private void doDrawing() {
int xSekunda, ySekunda;
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1;
xSekunda = (int) ((int) SX + Math.round(Math
.sin((6 * SECOND * Math.PI / 180)) * DELKA));
ySekunda = (int) ((int) SY - Math.round(Math
.cos((6 * SECOND * Math.PI / 180)) * DELKA));
// Line2D line = new Line2D.Double(SX, SY, xSekunda, ySekunda);
line = new Line2D.Double(SX, SY, xSekunda, ySekunda);
// lineList.add(line);
repaint();
// info
System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " "
+ SECOND + " " + xSekunda + " " + ySekunda + "\n");
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(2 * SX, 2 * SY);
}
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
// to give smoother lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through our list and draw lines it holds
if (line != null) {
g2d.draw(line);
}
}
private class TaskPerformer implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (!isShowing() && timer != null && timer.isRunning()) {
timer.stop();
} else {
doDrawing();
}
}
}
private static void createAndShowGui() {
Surface mainPanel = new Surface();
JFrame frame = new JFrame("surface");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
我在 Java 中绘图时遇到问题。我认为我的代码是正确的,但是当我将它与计时器一起循环时,它不会打印任何内容。我想每秒重复 doDrawing(g) 方法。现在它只会打印文本舞会 system.out 但不会打印绘图。
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import javax.swing.JPanel;
import javax.swing.Timer;
public class surface extends JPanel{
private void doDrawing(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
//souradnice stredu ciferniku
final int sx = 250;
final int sy = 250;
// inicializace promennych
int uhel = 0;
int delka = 150;
int xHodina,xMinuta,xSekunda,
yHodina,yMinuta,ySekunda;
// získání aktuálního času
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1 ;
//výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení
xSekunda = (int) ((int) sx + Math.round( Math.sin(( 6 * SECOND * Math.PI / 180)) * delka));
ySekunda = (int) ((int) sy - Math.round( Math.cos(( 6 * SECOND * Math.PI / 180)) * delka));
//vyhreslení ručiček
g2d.drawLine(sx, sy, xSekunda, ySekunda);
//info
System.out.print(" "+(6 * SECOND)+ " "+ HOUR+" "+MINUTE+" "+SECOND+" "+xSekunda+" "+ySekunda+"\n");
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
int delay = 1000; //milliseconds
//Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing(g);
}
};
new Timer(delay, taskPerformer).start();
}
}
问题就在这里。
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
int delay = 1000; //milliseconds
//Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing(g);
}
};
new Timer(delay, taskPerformer).start();
}
}
切勿在 paintComponent 内部启动计时器。此方法只画画不画,我的意思绝对没有别的。
您应该在其他地方启动您的计时器,也许在 class 的构造函数中,并让它更改您的 class 的字段,然后调用 repaint()
。然后 paintComponent 方法应该使用这些字段来决定绘制什么和在哪里绘制。
例如,您的 doDrawing()
方法(没有 Graphics 参数)可以创建一个 Line2D,将其添加到 List<Line2D>
,然后调用 repaint()
。 paintComponent(...)
方法然后可以遍历此列表绘制每一行:
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.Timer;
public class surface extends JPanel {
private List<Line2D> lineList = new ArrayList<>();
public surface() {
int delay = 1000; // milliseconds
// Somewhere there is that problem ..
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doDrawing();
}
};
new Timer(delay, taskPerformer).start();
}
private void doDrawing() {
// souradnice stredu ciferniku
final int sx = 250;
final int sy = 250;
// inicializace promennych
int uhel = 0;
int delka = 150;
int xHodina, xMinuta, xSekunda, yHodina, yMinuta, ySekunda;
// získání aktuálního času
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1;
// výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení
xSekunda = (int) ((int) sx + Math.round(Math
.sin((6 * SECOND * Math.PI / 180)) * delka));
ySekunda = (int) ((int) sy - Math.round(Math
.cos((6 * SECOND * Math.PI / 180)) * delka));
Line2D line = new Line2D.Double(sx, sy, xSekunda, ySekunda);
lineList.add(line);
repaint();
// info
System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " "
+ SECOND + " " + xSekunda + " " + ySekunda + "\n");
}
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
for (Line2D line2d : lineList) {
g2d.draw(line2d);
}
}
}
Edit 不好意思,您只想使用此代码绘制 one 行,而不是行列表。如果是这样,摆脱列表,而是创建一个 Line2D 字段,该字段由您的计时器更改并由您的 paintComponent 绘制:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
// !! Class names should begin with upper-case letter
public class Surface extends JPanel {
private static final double DELKA = 150;
private static final int SX = 250;
private static final int SY = SX;
private static final int DELAY = 1000;
// private List<Line2D> lineList = new ArrayList<>();
private Timer timer = new Timer(DELAY, new TaskPerformer());
private Line2D line;
public Surface() {
timer.start();
}
private void doDrawing() {
int xSekunda, ySekunda;
int HOUR = Calendar.getInstance().get(Calendar.HOUR);
int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1;
int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1;
xSekunda = (int) ((int) SX + Math.round(Math
.sin((6 * SECOND * Math.PI / 180)) * DELKA));
ySekunda = (int) ((int) SY - Math.round(Math
.cos((6 * SECOND * Math.PI / 180)) * DELKA));
// Line2D line = new Line2D.Double(SX, SY, xSekunda, ySekunda);
line = new Line2D.Double(SX, SY, xSekunda, ySekunda);
// lineList.add(line);
repaint();
// info
System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " "
+ SECOND + " " + xSekunda + " " + ySekunda + "\n");
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(2 * SX, 2 * SY);
}
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
// to give smoother lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through our list and draw lines it holds
if (line != null) {
g2d.draw(line);
}
}
private class TaskPerformer implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (!isShowing() && timer != null && timer.isRunning()) {
timer.stop();
} else {
doDrawing();
}
}
}
private static void createAndShowGui() {
Surface mainPanel = new Surface();
JFrame frame = new JFrame("surface");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}