我在使用Java绘图时遇到问题。我认为我的代码是正确的,但是当我用计时器循环它时,它不会打印任何东西。我想每秒重复一次doDrawing(g)方法。现在它只打印文本prom 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();
}
}
答案 0 :(得分:5)
永远不要在paintComponent中启动Timer。这种方法仅用于绘图和绘图,没有任何意义,我的意思是没有别的。
您应该在其他位置启动计时器,可能在类的构造函数中,并让它更改类的字段,然后调用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);
}
}
}
编辑我的不好,您只想使用此代码绘制一个行,而不是行列表。如果是这样,请删除列表,然后创建一个由Timer更改并由paintComponent绘制的Line2D字段:
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();
}
});
}
}