上个贴子在回复中写的新问题没人理了,只好另开炉灶~
目前这个程序类似WINDOWS画图的功能,现在的问题出在画特定图形的功能实现上。
暂时的写法是在Panel上绘图,然后mouse事件里写入缓冲区,然后在paint方法里从缓冲区读取图象。这样写的问题是在画线,椭圆等特定图形时画面不断闪烁(因为用到了update。可是麻烦在于必须用到update,画特定图形例如线时,点击点与拖动鼠标的轨迹点之间的线必须不断清除,只留下松开鼠标之前的那条直线,否则就成了扇形~)。
一般解决这种闪烁有两个办法,第一重写update使其不清除画面,这条不行了。二是全部在缓冲区操作,个人感觉解决突破口应该在此,但不知具体该如何处理:把在Panel上绘图的方法照搬过去行不通,因为update会清除缓冲区,这样之前作品在操作中就无法保留了。想在update上作文章,但考虑了几天仍然无奈,所以期盼高手指点,请各位不吝赐教!感谢!!
目前这个程序类似WINDOWS画图的功能,现在的问题出在画特定图形的功能实现上。
暂时的写法是在Panel上绘图,然后mouse事件里写入缓冲区,然后在paint方法里从缓冲区读取图象。这样写的问题是在画线,椭圆等特定图形时画面不断闪烁(因为用到了update。可是麻烦在于必须用到update,画特定图形例如线时,点击点与拖动鼠标的轨迹点之间的线必须不断清除,只留下松开鼠标之前的那条直线,否则就成了扇形~)。
一般解决这种闪烁有两个办法,第一重写update使其不清除画面,这条不行了。二是全部在缓冲区操作,个人感觉解决突破口应该在此,但不知具体该如何处理:把在Panel上绘图的方法照搬过去行不通,因为update会清除缓冲区,这样之前作品在操作中就无法保留了。想在update上作文章,但考虑了几天仍然无奈,所以期盼高手指点,请各位不吝赐教!感谢!!
解决方案 »
- 读TXT文档
- Swing窗体只显示关闭按钮
- 求一个运算表达式的正则表达
- java后端学习路线.
- 500分求教:国外软件源码直接修改.java中字符串汉化编译出来是乱码,试了n种方法还是不行,500分求教各位达人
- 请教在eclipse3.1+myeclipse4.0中运行程序报的什么错啊?该怎样改才行啊?能不能说说具体的改的步骤啊?
- 为何这个程序输入的三个数据只能是n1<n1<n3才可以比较,否则就不可以比较大小;急
- 请问怎么通过Socket发送一个int数值?急,谢谢!!
- 问个低级的问题,我编译的时候没问题,可运行时候出现如下提示:Exception in thread "main" java.lang.NoClassDefFoundError: NativeDem
- 用法java是否可以实现底层协议,如链路层协议,ip,tcp协议
- 关于求处理图形问题
- Jtree大问题
package squall.swing;import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;import javax.swing.JFrame;
import javax.swing.JPanel;public class TestFrame extends JFrame {
public TestFrame() {
this.add(new TestPanel());
this.setTitle("TestFrame");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 400);
this.setVisible(true);
} public static void main(String[] args) {
new TestFrame();
}
}class TestPanel extends JPanel {
public TestPanel() {
TestMouse action = new TestMouse(this);
this.addMouseListener(action);
this.addMouseMotionListener(action);
} public ArrayList lines = new ArrayList(); public Point[] tmp = null; public void addPoint(Point[] pair) {
lines.add(pair);
} @Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0, length = lines.size(); i < length; ++i) {
Point[] points = (Point[]) lines.get(i);
g2.drawLine((int) points[0].getX(), (int) points[0].getY(),
(int) points[1].getX(), (int) points[1].getY());
}
if (tmp != null) {
g2.drawLine((int) tmp[0].getX(), (int) tmp[0].getY(), (int) tmp[1]
.getX(), (int) tmp[1].getY());
}
}}class TestMouse implements MouseListener, java.awt.event.MouseMotionListener {
public TestPanel owner; public TestMouse(TestPanel panel) {
this.owner = panel;
} private Point begin = null; public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub } public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub } public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub } public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
begin = e.getPoint();
} public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
if (begin != null) {
owner.addPoint(new Point[] { begin, e.getPoint() });
begin = null;
owner.tmp = null;
}
owner.repaint();
} public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub owner.tmp = new Point[] { begin, e.getPoint() };
owner.repaint(); } public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub }}
先感谢你的解答!
这个方法好象对于简单的例子比较适用,因为我的理解,你的方法是通过保存上之前绘图时鼠标的位置,在当前绘图时重新绘出前后的图形。如果要画的图形很多,那不是要在paint方法里写出全部的绘图方法,而且有一点很麻烦的是还有按鼠标轨迹绘图的功能(这个如果不用双缓冲,我感觉很难重新绘制出来)。
不知道我有没有理解错误的地方,还请你多指点
一个放保存了的shape
一个放改动中的shape感觉应该可以
是的,就是初始点也不断改变画线的情况
还有我说的图形很多是指种类,比如直线,圆,椭圆,长方形等等,如果绘图时作品包括所有这些,那paint方法里必须对每一种图形都要分别记录数据然后重新绘图吧
使用JPanel来绘制, 用的不是paint方法, 而是JPanel的protected void paintComponent(Graphics g)方法, 在方法的第一句, 要先调用父类的此方法, 如:
public class MyPanel extends JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g); // 开始进行绘制
g.drawString("Was", 0, 0);
}
}如果还想继续使用Panel来绘制的话, 那就要自己实现双缓冲机制了:
先建一个BufferedImage bufferedImage,
在paint方法中, Graphics gg = bufferedImage.getGraphics();
然后所有需要绘制的东西, 都使用这个gg来绘制,
绘制完成后, 把这个bufferedImage绘制到从paint方法得到的Graphics环境中:
void paint(Graphics g) {
Graphics gg = bufferedImage.getGraphics();
gg.drawString("buffer", 0, 0);
//......其他的绘制工作 g.drawImage(bufferedImage, 0, 0, this);
}
很感谢你的建议,这样写确实会让程序更简洁一些。
不过现在的主要问题是在repaint方法的内部,也就是说如何让update-paint的过程不影响之前的缓存图象而且不会使画面闪烁
(用背景色重画行不通的,这样会盖掉其他图形)
其实说白了就是想知道WINDOWS画图程序那种类似橡皮筋直线画法如何做到可覆盖,不闪烁的,这里应该不会没人知道如何做到的吧
其实除了线段,你需要的就是Shape保存图形了。
真的很感谢你给我这么多这方面的建议,我就从这个方法入手去写写看,有什么问题还请你多多指点
然后把前后相邻的两个点连接起来就可以了
1.package src;import java.awt.*;
public class Myline {
////////////////////////
private int orgX;
private int orgY;
private int endX;
private int endY;
public Myline(int orgX,int orgY,int endX,int endY){
this.orgX = orgX;
this.orgY = orgY;
this.endX = endX;
this.endY = endY;
}
public void dramline(Graphics g){
g.setColor(Color.RED);
g.drawString(orgX + "," + orgY,orgX,orgY);
g.drawString(endX+ "," + endY,endX,endY);
g.drawLine(orgX, orgY, endX, endY);
}
}package src;import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class Paint extends Frame {
/**
* @param args
*/
static final long serialVersionUID = 42L;
Vector allLine = new Vector();
public static void main(String[] args) {
// TODO 自动生成方法存根
Paint p = new Paint();
p.init(); }
public void init(){
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter(){
int orgX;
int orgY;
public void mousePressed(MouseEvent e){
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e){
allLine.add(new Myline(orgX, orgY, e.getX(), e.getY()));
repaint();
}
});
this.setSize(300,300);
this.setVisible(true);
}
public void paint(Graphics g){
Enumeration lines = allLine.elements();
while(lines.hasMoreElements()){
Myline l = (Myline)lines.nextElement();
l.dramline(g);
}
}}
2.
package src;import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class TestImage extends Frame {
/**
* @param args
*/
static final long serialVersionUID = 42L;
Vector allLine = new Vector();
Image img = null;
Graphics og = null;
public static void main(String[] args) {
// TODO 自动生成方法存根
TestImage p = new TestImage();
p.init(); }
public void init(){
setSize(300,300);
setVisible(true);
Dimension d = getSize();
img = createImage(d.width,d.height);
og = img.getGraphics();
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
addMouseListener(new MouseAdapter(){
int orgX;
int orgY;
public void mousePressed(MouseEvent e){
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e){
/*allLine.add(new Myline(orgX, orgY, e.getX(), e.getY()));
repaint();*/
Graphics g = getGraphics();
g.setColor(Color.RED);
g.drawString(orgX + "," + orgY,orgX,orgY);
g.drawString(e.getX()+ "," + e.getY(),e.getX(),e.getY());
g.drawLine(orgX, orgY, e.getX(), e.getY());
og.setColor(Color.RED);
og.drawString(orgX + "," + orgY,orgX,orgY);
og.drawString(e.getX()+ "," + e.getY(),e.getX(),e.getY());
og.drawLine(orgX, orgY, e.getX(), e.getY());
}
});
}
public void paint(Graphics g){
/*Enumeration lines = allLine.elements();
while(lines.hasMoreElements()){
Myline l = (Myline)lines.nextElement();
l.dramline(g);*/
if(img!=null){
g.drawImage(img,0,0,this);
}
}}