【发布时间】:2014-10-23 03:21:01
【问题描述】:
请多多包涵,英语既不是我的第一语言,也不是我的第二语言。
基本思想是加载图像并使用鼠标绘制一些形状。 我创建了这三个 java 类(见底部的代码):
1 Main,目前仅用于启动第二类“Action”
2 Action,这个类应该包含用户在ui上执行的每一个动作(绘图,加载图像......)
3 UI,该类创建 UI 并保存与 UI 相关的每个对象(Jlabels、JButtons、JFrame ....)
在这个阶段它(有点)按预期工作,但我还有几个问题。我试图将每个问题可视化,但我只能在这篇文章中使用 2 张图片,所以请使用 image。
1) 绘制形状按预期工作,但一旦用户创建(释放鼠标按钮)形状,它应该以蓝色显示。除非绘制新形状,否则这不起作用。用户释放按钮后如何更新形状?如链接图像的第一帧和第二帧所示。 -- 已解决
添加了对paint()的调用;在 mouseReleased 事件中。
2) 第一个形状比其他形状更暗/颜色更饱满,请参见链接图像中的第二帧和第五帧。我不知道如何纠正这个,有什么想法吗? --已解决
交换了这两行
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.fill(shape);
3) 调整 UI 大小后,所有形状均不可见,如链接图像的第三帧和第四帧所示。我如何强制程序绘制它们? -- 已解决
将 ComponentListener 添加到 JFrame,现在在 componentResized() 事件中调用 paint()
3.1) 调整大小后如何使形状保持在原始图像(黑色方块)内?链接图像的第四帧。 -- 已解决
如果调整了框架的大小,我忘记添加偏移量....
4) 仅当用户不使用滚动窗格时,检查鼠标是否仍在图像边界内才有效。有没有人更好地检查鼠标是否在图像边界内?
5) 如果有多个形状,则在绘图期间形状会闪烁,我猜是因为每次用户在绘图时拖动鼠标时都会绘制它们。如何解决这个问题?
不要犹豫,指出任何其他错误或真正的最佳编码实践。 提前谢谢你。
更新
-添加标题
-改变格式
-添加了描述的更改
主类
public class Main {
public static void main(String[] args) {
new Action();
}
}
UI类
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
public class UI {
public JLabel jlabel_image;
public JFrame jframe_ui;
public JLabel jlabel_info;
private Action action;
private JScrollPane jscrollpane_image;
public UI(Action action) {
this.action = action;
jlabel_image = new JLabel();
jlabel_image.setHorizontalAlignment(jlabel_image.CENTER);
jlabel_image.setVerticalAlignment(jlabel_image.CENTER);
jlabel_image.addMouseListener(action);
jlabel_image.addMouseMotionListener(action);
jscrollpane_image = new JScrollPane(jlabel_image);
jlabel_info = new JLabel("mouse: ");
jframe_ui = new JFrame("test frame");
jframe_ui.addComponentListener(action);
jframe_ui.setPreferredSize(new Dimension(500,500));
jframe_ui.getContentPane().setLayout(new BorderLayout());
jframe_ui.setMinimumSize(new Dimension(500,500));
jframe_ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe_ui.add(jscrollpane_image, BorderLayout.CENTER);
jframe_ui.add(jlabel_info, BorderLayout.SOUTH);
jframe_ui.pack();
jframe_ui.setVisible(true);
}
}
动作类
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
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.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Action implements ActionListener, ComponentListener, MouseListener, MouseMotionListener {
private UI ui;
private Point startpoint;
private Point endpoint;
private ArrayList<Shape> shapes;
private boolean mouseonimage;
public Action() {
ui = new UI(this);
shapes = new ArrayList<Shape>();
mouseonimage = false;
BufferedImage bufferedimage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bufferedimage.createGraphics();
g2.setPaint(Color.BLACK);
g2.fillRect(0, 0, 800, 800);
g2.dispose();
ui.jlabel_image.setIcon(new ImageIcon(bufferedimage));
}
@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 arg0) {
// TODO Auto-generated method stub
paint();
}
@Override
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent me) {
// TODO Auto-generated method stub
if(mouseonimage) {
if(checkMouseCoordinates(me.getPoint())) {
endpoint = me.getPoint();
paint();
}
}
}
@Override
public void mouseMoved(MouseEvent me) {
// TODO Auto-generated method stub
checkMouseCoordinates(me.getPoint());
}
@Override
public void mouseClicked(MouseEvent me) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent me) {
// TODO Auto-generated method stub
mouseonimage = true;
checkMouseCoordinates(me.getPoint());
}
@Override
public void mouseExited(MouseEvent me) {
// TODO Auto-generated method stub
mouseonimage = false;
checkMouseCoordinates(me.getPoint());
}
@Override
public void mousePressed(MouseEvent me) {
// TODO Auto-generated method stub
if(mouseonimage) {
if(me.getButton() == MouseEvent.BUTTON1) {
if(checkMouseCoordinates(me.getPoint())) {
startpoint = me.getPoint();
endpoint = me.getPoint();
}
}
}
}
@Override
public void mouseReleased(MouseEvent me) {
// TODO Auto-generated method stub
if(checkMouseCoordinates(me.getPoint())) {
endpoint = me.getPoint();
}
if(startpoint != null) {
if(Math.abs(startpoint.x - endpoint.x) > 9) {
if(Math.abs(startpoint.y - endpoint.y) > 9) {
shapes.add(createrectangle(startpoint, endpoint));
}
}
}
startpoint = null;
endpoint = null;
paint();
}
@Override
public void actionPerformed(ActionEvent me) {
// TODO Auto-generated method stub
}
public boolean checkMouseCoordinates(Point point) {
boolean withinBoarders = false;
if(mouseonimage) {
int imageFrameWidth = ui.jlabel_info.getBounds().width;
int imageFrameHeight = ui.jlabel_info.getBounds().y;
int imageWidth = ui.jlabel_image.getIcon().getIconWidth();
int imageHeight = ui.jlabel_image.getIcon().getIconHeight();
int x = 0;
int y = 0;
int w = imageFrameWidth;
int h = imageFrameHeight;
System.out.println(ui.jlabel_info.getBounds());
if(imageFrameWidth > imageWidth) {
x = (imageFrameWidth - imageWidth)/2 - 9;
w = imageWidth;
}
if(imageFrameHeight > imageHeight) {
y = (imageFrameHeight - imageHeight)/2;
h = imageHeight;
if(imageFrameWidth > imageWidth) {
x = x + 7;
}
if(imageFrameHeight > imageHeight) {
y = y - 1;
}
}
Rectangle imageFrame = new Rectangle(x, y, w, h);
if(imageFrame.contains(point)) {
withinBoarders = true;
ui.jlabel_info.setText(String.format("mouse: on image :: %d/%d :: %d/%d :: %d/%d||%d/%d",point.x, point.y, imageFrameHeight, imageFrameWidth, imageFrame.x, imageFrame.width, imageFrame.y, imageFrame.height));
} else {
ui.jlabel_info.setText(String.format("mouse: not on image %d/%d",point.x, point.y));
}
} else {
ui.jlabel_info.setText("mouse: not on image");
}
return withinBoarders;
}
private Shape createrectangle(Point start, Point end) {
int image_x = (ui.jlabel_image.getWidth() - ui.jlabel_image.getIcon().getIconWidth()) / 2;
int image_y = (ui.jlabel_image.getHeight() - ui.jlabel_image.getIcon().getIconHeight()) / 2;
int image_w = ui.jlabel_image.getIcon().getIconWidth();
int image_h = ui.jlabel_image.getIcon().getIconHeight();
int x = start.x;
int y = start.y;
int h = end.y;
int w = end.x;
x = x < image_x ? image_x : x;
x = x > (image_x + image_w - 1) ? (image_x + image_w - 1) : x;
w = w < image_x ? image_x : w;
w = w > (image_x + image_w - 1) ? (image_x + image_w - 1) : w;
y = y < image_y ? image_y : y;
y = y > (image_y + image_h - 1) ? (image_y + image_h - 1) : y;
h = h < image_y ? image_y: h;
h = h > (image_y + image_h - 1) ? (image_y + image_h - 1) : h;
return new Rectangle2D.Float(Math.min(x, w), Math.min(y, h), Math.abs(x - w), Math.abs(y - h));
}
private void paint() {
Graphics g;
g = ui.jlabel_image.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(new BufferedImage(ui.jlabel_image.getIcon().getIconWidth(), ui.jlabel_image.getIcon().getIconHeight(), BufferedImage.TYPE_INT_RGB), (ui.jlabel_image.getWidth() - ui.jlabel_image.getIcon().getIconWidth()) / 2, (ui.jlabel_image.getHeight() - ui.jlabel_image.getIcon().getIconHeight()) / 2, null);
for(Shape shape: shapes) {
g2d.setPaint(Color.BLUE);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.fill(shape);
g2d.setPaint(Color.BLUE);
g2d.draw(shape);
}
if(startpoint != null) {
if(endpoint != null) {
g2d.setPaint(Color.RED);
g2d.draw(createrectangle(startpoint, endpoint));
}
}
}
}
【问题讨论】:
-
如果它是你的第三语言,你的英语非常好:)
标签: java image optimization draw