Java 摆动计时器和画布上的绘画
嗨,我想问一下摇摆计时器和画布。我在做简单的动画来改变物体的颜色。我用Thread.sleep创建了它,但JFrame在重新绘制时没有响应,所以我将其更改为Swing Timer。但现在当我开始动画时,它的“不做任何事情”计时器正在工作,但画布上的对象不会改变颜色。 这里是我的功能,动画的颜色变化,我使用它在画布的画外画功能Java 摆动计时器和画布上的绘画,java,swing,canvas,timer,Java,Swing,Canvas,Timer,嗨,我想问一下摇摆计时器和画布。我在做简单的动画来改变物体的颜色。我用Thread.sleep创建了它,但JFrame在重新绘制时没有响应,所以我将其更改为Swing Timer。但现在当我开始动画时,它的“不做任何事情”计时器正在工作,但画布上的对象不会改变颜色。 这里是我的功能,动画的颜色变化,我使用它在画布的画外画功能 private void paintSearch(Vector<NodeGraph2D> vector,Graphics graphics2D) {
private void paintSearch(Vector<NodeGraph2D> vector,Graphics graphics2D) {
if (!vector.isEmpty()) {
final int[] k = {0};
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (repaint) {
if (k[0] == vector.size())
return;
if (vector == pruferTreeNodes) {
vector.elementAt(k[0]).draw((Graphics2D) graphics2D);
} else {
graphics2D.setColor(Color.GREEN);
((Graphics2D) graphics2D).fill(vector.elementAt(k[0]));
graphics2D.setColor(Color.BLACK);
((Graphics2D) graphics2D).drawString(vector.elementAt(k[0]).getNodeGraph().getName(), vector.elementAt(k[0]).getX1() + 15, vector.elementAt(k[0]).getY1() + 25);
}
k[0] += 1;
}
}
});
timer.start();
}
}
private void paintSearch(矢量、图形2d){
如果(!vector.isEmpty()){
最终int[]k={0};
计时器计时器=新计时器(1000,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
如果(重新喷漆){
如果(k[0]==vector.size())
返回;
if(向量==pruferTreeNodes){
向量元素at(k[0])draw((Graphics2D)Graphics2D);
}否则{
图形2D.setColor(颜色为绿色);
(Graphics2D)Graphics2D)fill(vector.elementAt(k[0]);
图形2D.setColor(颜色为黑色);
(Graphics2D)Graphics2D).drawString(vector.elementAt(k[0]).getNodeGraph().getName(),vector.elementAt(k[0]).getX1()+15,vector.elementAt(k[0]).getY1()+25);
}
k[0]+=1;
}
}
});
timer.start();
}
}
你认为我使用计时器不好吗?感谢您的回复。:) 在Swing中进行自定义绘制时,最好将JPanel子类化(它可以是一个匿名类),并将绘制相关数据存储在面板可访问的属性中 您的计时器不会进行任何绘制,而是操纵与绘制相关的数据。在Swing的EventDispatcherThread或JComponents的paintComponent方法之外,绝对不要尝试在图形对象上进行任何绘制。(有关更多信息,请参阅这些方法的文档) 下面是一个示例,演示了使用计时器操纵颜色的自定义绘制的外观:
public static void main(String[] args) {
EventQueue.invokeLater(Example::new);
}
// this is the painting-related data that is being manipulated by the timer
private int currentColorIndex;
public Example() {
JFrame frame = new JFrame("Custom Painting");
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
Color[] allColors = {Color.RED, Color.BLUE, Color.GREEN,
Color.YELLOW, Color.ORANGE, Color.MAGENTA};
JPanel myCustomPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
// here the painting related data is being used by the custom JPanel implementation
g.setColor(allColors[currentColorIndex]);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
frame.setContentPane(myCustomPanel);
Timer timer = new Timer(100, e -> {
// the timer does not use any graphics objects, etc, but rather manipulates our painting-related data
currentColorIndex = (currentColorIndex + 1) % allColors.length;
// whenever the painting-related data has changed we need to call repaint() on our custom JPanel implementation
myCustomPanel.repaint();
});
timer.setRepeats(true);
timer.start();
frame.setVisible(true);
}
在Swing中进行自定义绘制时,最好将JPanel子类化(它可以是一个匿名类),并将绘制相关数据存储在面板可访问的属性中 您的计时器不会进行任何绘制,而是操纵与绘制相关的数据。在Swing的EventDispatcherThread或JComponents的paintComponent方法之外,绝对不要尝试在图形对象上进行任何绘制。(有关更多信息,请参阅这些方法的文档) 下面是一个示例,演示了使用计时器操纵颜色的自定义绘制的外观:
public static void main(String[] args) {
EventQueue.invokeLater(Example::new);
}
// this is the painting-related data that is being manipulated by the timer
private int currentColorIndex;
public Example() {
JFrame frame = new JFrame("Custom Painting");
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
Color[] allColors = {Color.RED, Color.BLUE, Color.GREEN,
Color.YELLOW, Color.ORANGE, Color.MAGENTA};
JPanel myCustomPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
// here the painting related data is being used by the custom JPanel implementation
g.setColor(allColors[currentColorIndex]);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
frame.setContentPane(myCustomPanel);
Timer timer = new Timer(100, e -> {
// the timer does not use any graphics objects, etc, but rather manipulates our painting-related data
currentColorIndex = (currentColorIndex + 1) % allColors.length;
// whenever the painting-related data has changed we need to call repaint() on our custom JPanel implementation
myCustomPanel.repaint();
});
timer.setRepeats(true);
timer.start();
frame.setVisible(true);
}
您可能需要创建一个完整的代码来让我们测试您的代码,但是1)避免使用Canvas,因为AWT库已经死了20多年2)如果(vector==pruferTreeNodes){看起来不正确,那么这一行您确定吗?3)您从哪里获得Graphics2D对象?4)您在哪里调用
repaint()
?@HovercraftFullOfEels我应该使用swing Jpanel而不是Canvas吗?是的,你应该覆盖paintComponent并在那里进行绘制。同样,我不知道你从哪里获得Graphics2D对象,但如果它不是来自BuffereImage,那么我会怀疑它不是有效的可用对象。请搜索此站点以查找简单的wing动画示例来自我、MadProgrammer、Camickr和其他Swing专家,以了解如何正确操作。@HovercraftFullOfEels我从画布绘制的覆盖中获得了它,因为我在画布中使用此函数。您可能需要创建一个完整的示例,以允许我们测试您的代码,但1)避免使用画布,因为AWT库已经过时了20多年2)如果(vector==pruferTreeNodes){看起来不对劲,那么这是否确定这一行?3)从何处获取Graphics2D对象?4)在何处调用重新绘制()
?@HovercraftFullOfEels我应该使用swing Jpanel而不是Canvas吗?是的,你应该覆盖paintComponent并在那里进行绘制。同样,我不知道你从哪里获得Graphics2D对象,但如果它不是来自BuffereImage,那么我会怀疑它不是有效的可用对象。请搜索此站点以查找简单的来自我、MadProgrammer、Camickr和其他Swing专家的wing动画示例,以了解如何正确操作。@HovercraftFullOfEels我从画布绘制的覆盖中获得了它,因为我在画布中使用此函数。