gpt4 book ai didi

java - 如何防止绘制的形状在 Java 中消失?

转载 作者:行者123 更新时间:2023-11-29 06:36:52 25 4
gpt4 key购买 nike

我正在做一个项目来创建一个绘制随机形状的屏幕保护程序。我有几个问题,但我现在主要关心的是如何让形状留在屏幕上,而不是在创建后消失。这是我的代码。我不能使用任何循环,并且我不打算更改我已有的任何功能(除了可能的 shapesDrawn)。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ScreenSaver2 extends JPanel implements ActionListener {
private JFrame frame = new JFrame("FullSize");
private Rectangle rectangle;
boolean full;


protected void paintComponent(Graphics g) {
int r = (int)(Math.random() * 255);
int gr = (int)(Math.random() * 255);
int b = (int)(Math.random() * 255);
Color color = new Color(r, gr, b);
int width = 10 + (int)(Math.random() * 40);
int height = 10 + (int)(Math.random() * 40);
int x = (int)(Math.random() * (getWidth() - width));
int y = (int)(Math.random() * (getHeight() - height));
int whichShape = (int)(Math.random() * 3);
int shapesDrawn = 0;

super.paintComponent(g);
if (shapesDrawn >= 30) {
shapesDrawn = 0;
}

switch (whichShape) {
case 0:
g.setColor(color);
g.drawLine(x, y, x + width, y + height);
shapesDrawn++;
break;
case 1:
g.setColor(color);
g.drawRect(x, y, width, height);
shapesDrawn++;
break;
case 2:
g.setColor(color);
g.drawRoundRect(x, y, width, height, 25, 25);
shapesDrawn++;
break;
case 3:
g.setColor(color);
g.drawOval(x, y, width, height);
shapesDrawn++;
break;
}

}


ScreenSaver2() {
// Remove the title bar, min, max, close stuff
frame.setUndecorated(true);
// Add a Key Listener to the frame
frame.addKeyListener(new KeyHandler());
// Add this panel object to the frame
frame.add(this);
// Get the dimensions of the screen
rectangle = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().getBounds();
// Set the size of the frame to the size of the screen
frame.setSize(rectangle.width, rectangle.height);
frame.setVisible(true);
// Remember that we are currently at full size
full = true;
// set and initialize timer
Timer t = new Timer(500, this);
t.setDelay(500);
t.start();

}

// This method will run when any key is pressed in the window
class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
// Terminate the program.
if (e.getKeyChar() == 'x') {
System.out.println("Exiting");
System.exit(0);
}
// Change background color
else if (e.getKeyChar() == 'r') {
System.out.println("Change background color");
setBackground(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256)));
repaint();
}
// Resize to half-screen
else if (e.getKeyChar() == 'z') {
System.out.println("Resizing");
frame.setSize((int)rectangle.getWidth() / 2, (int)rectangle.getHeight());
}
}
}

public void actionPerformed(ActionEvent e) {
repaint();
}

public static void main(String[] args) {
ScreenSaver2 obj = new ScreenSaver2();
}
}

最佳答案

与其将 paintComponent 中的每个新形状直接绘制到 Graphics 上下文,不如使用后备缓冲区首先渲染形状并将其绘制到 图形上下文。

这样,您只需在每次呈现新形状时维护一个简单的计数器。

这也很麻烦,因为 paintComponent 可能会因为多种原因而被调用,而您无法控制很多,这意味着您的程序有可能在绘制更多形状之前绘制更多形状计时器滴答实际发生了...

更新了示例

您剩下的唯一选择是创建一个后备缓冲区,您可以根据需要在其上绘制每个更改。这将“存储”绘画周期之间的每个变化。然后您可以简单地将其绘制到屏幕上...

private BufferedImage img;

//...

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// Create the backing buffer
// This is a little cheat, creating a new image when the number of shapes
// exceeds the requirements, but it saves messing about with clearing
// a alpha image ;)
if (img == null || shapesDrawn >= 30) {
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
shapesDrawn = 0;
} else if (img.getWidth() != getWidth() || img.getHeight() != img.getHeight()) {
// Update the backing buffer to meet the requirements of the changed screen size...
BufferedImage buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D gbuffer = buffer.createGraphics();
gbuffer.drawImage(img, 0, 0, this);
gbuffer.dispose();
img = buffer;
}

// Get a reference to the backing buffers graphics context...
Graphics2D gbuffer = img.createGraphics();

// Paint the shapes to the backing buffer...
int r = (int) (Math.random() * 255);
int gr = (int) (Math.random() * 255);
int b = (int) (Math.random() * 255);
Color color = new Color(r, gr, b);
int width = 10 + (int) (Math.random() * 40);
int height = 10 + (int) (Math.random() * 40);
int x = (int) (Math.random() * (getWidth() - width));
int y = (int) (Math.random() * (getHeight() - height));
int whichShape = (int) (Math.random() * 3);
int shapesDrawn = 0;

switch (whichShape) {
case 0:
gbuffer.setColor(color);
gbuffer.drawLine(x, y, x + width, y + height);
shapesDrawn++;
break;
case 1:
gbuffer.setColor(color);
gbuffer.drawRect(x, y, width, height);
shapesDrawn++;
break;
case 2:
gbuffer.setColor(color);
gbuffer.drawRoundRect(x, y, width, height, 25, 25);
shapesDrawn++;
break;
case 3:
gbuffer.setColor(color);
gbuffer.drawOval(x, y, width, height);
shapesDrawn++;
break;
}
// Dispose of the buffers graphics context, this frees up memory for us
gbuffer.dispose();
// Paint the image to the screen...
g2d.drawImage(img, 0, 0, this);
g2d.dispose();
}

可能是我不得不给出的最糟糕的建议

改变...

super.paintComponent(g);
if (shapesDrawn >= 30) {
shapesDrawn = 0;
}

为了...

if (shapesDrawn >= 30) {
super.paintComponent(g);
shapesDrawn = 0;
}

关于java - 如何防止绘制的形状在 Java 中消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19284933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com