【发布时间】:2014-02-23 23:52:11
【问题描述】:
我的任务是在 Java 中制作一个简单的绘图程序,该程序利用 GUI 并具有基本的 I/O 功能。这就是我的教授告诉我要做的一切。但是,我之前只制作了一个 GUI 程序,所以直接跳到这个绘图程序中一直很头疼。现在我快完成了,但程序并没有像我预期的那样运行。当在面板上绘制新对象时,它们会在其下方的对象上绘制不可见的白色矩形,从而擦除这些对象。我认为这是重绘的结果(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1); DrawShapes 中的方法,但想不出修复它的方法。
另一方面,对象也没有正确保存。我可以让它按照我的意图导出 jpg,但是,它只会导出最后绘制的图像,而不是 paintComponent 画布上的所有内容。
最后,DrawShapes 中的 clear 方法的工作方式非常相似。当 clear 方法被激活时,它将清除除最后绘制的图像之外的所有内容。
有没有比我更熟悉这些工具的人可以找到解决这些问题的方法?这只是我使用的第一个程序,以及 I/O。
这是应该在其上绘制形状的面板的类:
/**
* @author me
*/
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class DrawShapes extends JPanel{
Point startPoint = null;
Point endPoint = null;
public int drawType = 1;
BufferedImage image;
Graphics2D g2d;
public DrawShapes(){
setBackground(Color.WHITE);
MyMouseListener m1 = new MyMouseListener();
addMouseListener(m1);
addMouseMotionListener(m1);
}//end constructor
//sets draw type, which is the decider of what is being drawn.
public void setType(int type){
if(type == 1)
{
drawType = 1;
}
else if(type == 2)
{
drawType = 2;
}
else if(type == 3)
{
drawType = 3;
}
}//end setType
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image == null)
{
createEmptyImage();
}
g.drawImage(image, 0, 0, null);
if (startPoint != null && endPoint != null)
{
int x = Math.min(startPoint.x, endPoint.x);
int y = Math.min(startPoint.y, endPoint.y);
int width = Math.abs(startPoint.x - endPoint.x);
int height = Math.abs(startPoint.y - endPoint.y);
switch (drawType)
{
case 1:
g.drawRect(x, y, width, height);
break;
case 2:
g.drawOval(x, y, width, height);
break;
case 3:
g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
break;
}
}
}//end paintComponent
public void save()
{
BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
this.paint(g);
g.dispose();
try{ImageIO.write(bi, "png",new File("test.png"));
}catch (Exception e){}
}
private void createEmptyImage()
{
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
g2d = (Graphics2D)image.getGraphics();
g2d.setColor(Color.BLACK);
g2d.drawString("Add a shape by clicking and dragging.", 40, 15);
}
public void addRect(int x, int y, int width, int height, Color color)
{
g2d.setColor( color );
g2d.drawRect(x, y, width, height);
repaint();
}
public void addOval(int x, int y, int width, int height, Color color)
{
g2d.setColor( color );
g2d.drawOval(x, y, width, height);
repaint();
}
public void addLine(int x1, int y1, int x2, int y2, Color color)
{
g2d.setColor(color);
g2d.drawLine(x1, y1, x2, y2);
repaint();
}
public void clear()
{
createEmptyImage();
repaint();
}
class MyMouseListener extends MouseInputAdapter
{
private int xMin;
private int xMax;
private int yMin;
private int yMax;
public void mousePressed(MouseEvent e)
{
startPoint = e.getPoint();
endPoint = startPoint;
xMin = startPoint.x;
xMax = startPoint.x;
yMin = startPoint.y;
yMax = startPoint.y;
}
public void mouseDragged(MouseEvent e)
{
//This is code I found that should make it so the only area affected by the dragging is repainted.
endPoint = e.getPoint();
xMin = Math.min(xMin, endPoint.x);
xMax = Math.max(xMax, endPoint.x);
yMin = Math.min(yMin, endPoint.y);
yMax = Math.max(yMax, endPoint.y);
repaint(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1);
}
public void mouseRelease(MouseEvent e)
{
//This code paints the shapes on the Buffered Image created as a canvas
int x = Math.min(startPoint.x, endPoint.x);
int y = Math.min(startPoint.y, endPoint.y);
int width = Math.abs(startPoint.x - endPoint.x);
int height = Math.abs(startPoint.y - endPoint.y);
if (width != 0 || height != 0)
{
g2d.setColor( e.getComponent().getForeground() );
// g2d.drawRect(x, y, width, height);
switch (drawType)
{
case 1:
addRect(x, y, width, height, e.getComponent().getForeground());
break;
case 2:
addOval(x, y, width, height, e.getComponent().getForeground());
break;
case 3:
addLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, e.getComponent().getForeground());
break;
}//end switch statement.
}
startPoint = null;
// repaint();
}
}
}//end class
这是 UI 的代码:
/*@author Me*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyDrawUI extends JFrame
{
private DrawShapes draw = new DrawShapes();
private JPanel ButtonPanel = new JPanel();
private JFrame window = new JFrame("Draw!");
//constructor
MyDrawUI(){
buildUI();
}
void buildUI()
{
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(new GridLayout(2,2));
window.add(draw);
window.add(ButtonPanel, BorderLayout.SOUTH);
ButtonPanel.setBackground(Color.LIGHT_GRAY);
draw.setBackground(Color.WHITE);
//define buttons
JButton rectangle = new JButton("Rectangle");
JButton oval = new JButton("Oval");
JButton line = new JButton("Line");
JButton exit = new JButton("Exit");
JButton save = new JButton("Save");
JButton clear = new JButton("Clear");
//add buttons
ButtonPanel.add(rectangle, BorderLayout.SOUTH);
ButtonPanel.add(oval, BorderLayout.SOUTH);
ButtonPanel.add(line, BorderLayout.SOUTH);
ButtonPanel.add(clear, BorderLayout.SOUTH);
ButtonPanel.add(save, BorderLayout.SOUTH);
ButtonPanel.add(exit, BorderLayout.SOUTH);
ButtonPanel.setSize(100, 100);
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
draw.save();
}
});
clear.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
draw.clear();
}
});
rectangle.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
draw.setType(1);
}
});
oval.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
draw.setType(2);
}
});
line.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
draw.setType(3);
}
});
exit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
window.setVisible(true);
window.setSize(1024, 800);
}
}
【问题讨论】:
-
“最后,..” 所以不是一站式“修复我的代码商店”。这是一个问答网站,理想情况下,每个线程一个问题和一个接受的答案。那么..你对这个线程的一个问题是什么?
-
最好将形状放入
List并重新绘制列表... -
我的问题是,当您尝试在其上绘制多个对象时,paintcomponent 是如何工作的。原来我找错地方了。不过感谢 MadProgrammer,它现在按预期工作。有时,一个答案可以解决多个问题,并纠正一个错字。
-
您可以通过点击左侧的empty check mark 来接受答案。
标签: java swing user-interface paintcomponent jcomponent