java jpanel 缓冲画图_JPanel上活动绘图之上的JTextField,线程问题

我找到了解决办法。

我认为正在发生的事情是:每当需要更新JTextfield(即在每个光标上眨眼)时,JPanel的重写的ploytComponent()就会被调用,但它使用的图形参数与由reploy()调用时不同。因此,在每一个光标闪烁,我的矩形被清除和重新绘制在一个错误的图形实例,留下在屏幕上看到的图形无效。

这说得通吗?如果是的话,这难道不是挥杆带来的奇怪的不便吗?

无论如何,通过保持一个布尔值(activeRedraw)调用的来源,看起来我设法解决了这个问题。因此,我似乎终于找到了一种方法来进行主动绘图,而无需在每一帧上重新绘制整个屏幕区域,这意味着CPU使用率低,与窗口大小无关!

在这里完成代码:import java.awt.Color;import java.awt.Dimension;import java.awt.EventQueue;import java.awt.Graphics;import java.awt.GraphicsConfiguration;

import java.awt.GraphicsDevice;import java.awt.GraphicsEnvironment;import java.awt.Insets;

import java.awt.Rectangle;import java.awt.Transparency;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import java.awt.event.ComponentEvent;import java.awt.event.ComponentListener;import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;import java.awt.image.BufferedImage;import javax.swing.JFrame;import javax.swing.JPanel

;import javax.swing.JTextField;import javax.swing.Timer;public class NewTest extends JPanel implements

MouseListener,

ActionListener,

ComponentListener,

Runnable {

JFrame f;

Insets insets;

private Timer t = new Timer(20, this);

BufferedImage buffer1;

boolean repaintBuffer1 = true;

int initWidth = 640;

int initHeight = 480;

Rectangle rect;

boolean activeRedraw = true;

public static void main(String[] args) {

EventQueue.invokeLater(new NewTest());

}

@Override

public void run() {

f = new JFrame("NewTest");

f.addComponentListener(this);

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(this);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

createBuffers();

insets = f.getInsets();

t.start();

}

public NewTest() {

super(true);

this.setPreferredSize(new Dimension(initWidth, initHeight));

this.setLayout(null);

this.addMouseListener(this);

}

void createBuffers() {

int width = this.getWidth();

int height = this.getHeight();

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

GraphicsDevice gs = ge.getDefaultScreenDevice();

GraphicsConfiguration gc = gs.getDefaultConfiguration();

buffer1 = gc.createCompatibleImage(width, height, Transparency.OPAQUE);

repaintBuffer1 = true;

}

@Override

protected void paintComponent(Graphics g) {

//super.paintComponent(g);

int width = this.getWidth();

int height = this.getHeight();

if (activeRedraw) {

if (repaintBuffer1) {

Graphics g1 = buffer1.getGraphics();

g1.clearRect(0, 0, width, height);

g1.setColor(Color.green);

g1.drawRect(0, 0, width - 1, height - 1);

g.drawImage(buffer1, 0, 0, null);

repaintBuffer1 = false;

}

double time = 2* Math.PI * (System.currentTimeMillis() % 5000) / 5000.;

g.setColor(Color.RED);

if (rect != null) {

g.drawImage(buffer1, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, rect.x, rect.y, rect.x + rect.

width, rect.y + rect.height, this);

}

rect = new Rectangle((int)(Math.sin(time) * width/3 + width/2 - 20), (int)(Math.cos(time) * height/3 + height/2)

- 20, 40, 40);

g.fillRect(rect.x, rect.y, rect.width, rect.height);

activeRedraw = false;

}

}

@Override

public void actionPerformed(ActionEvent e) {

activeRedraw = true;

this.repaint();

}

@Override

public void componentHidden(ComponentEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void componentMoved(ComponentEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void componentResized(ComponentEvent e) {

int width = e.getComponent().getWidth() - (insets.left + insets.right);

int height = e.getComponent().getHeight() - (insets.top + insets.bottom);

this.setSize(width, height);

createBuffers();

}

@Override

public void componentShown(ComponentEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void mouseClicked(MouseEvent e) {

JTextField field = new JTextField("test");

field.setBounds(new Rectangle(e.getX(), e.getY(), 100, 20));

this.add(field);

repaintBuffer1 = true;

}

@Override

public void mouseEntered(MouseEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void mouseExited(MouseEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void mousePressed(MouseEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void mouseReleased(MouseEvent arg0) {

// TODO Auto-generated method stub

}}

要给JPanel添加背景图片,可以通过以下步骤实现: 1. 创建一个继承自JPanel的类,命名为BackgroundPanel。 2. 在BackgroundPanel中添加一个BufferedImage类型的属性,用于保存背景图片。 3. 在BackgroundPanel的构造方法中,将背景图片加载到BufferedImage中。 4. 重写BackgroundPanel的paintComponent方法,在该方法中将背景图片绘制在JPanel上。 下面是具体的代码实现: ``` import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JPanel; public class BackgroundPanel extends JPanel { private BufferedImage backgroundImage; public BackgroundPanel(String imagePath) { try { backgroundImage = ImageIO.read(new File(imagePath)); } catch (IOException e) { e.printStackTrace(); } } @Override public Dimension getPreferredSize() { return new Dimension(backgroundImage.getWidth(), backgroundImage.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(backgroundImage, 0, 0, null); } } ``` 使用匿名内部类的方式创建JPanel并添加背景图片的示例如下: ``` import javax.swing.JFrame; public class Main { public static void main(String[] args) { JFrame frame = new JFrame(); // 使用匿名内部类创建BackgroundPanel并设置背景图片 JPanel panel = new BackgroundPanel("background.jpg") { @Override public Dimension getPreferredSize() { return new Dimension(800, 600); } }; frame.add(panel); frame.pack(); frame.setVisible(true); } } ``` 在上面的示例中,我们使用了匿名内部类的方式来创建BackgroundPanel,并且重写了getPreferredSize方法,以指定JPanel的大小。同时,我们也在构造方法中加载了背景图片,并在paintComponent方法中将背景图片绘制在JPanel上。最后,我们将创建好的BackgroundPanel添加到JFrame中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值