以下代码可以工作并创建可拖动图像(DI)。我已经创建了2个类型DI,test和test1的实例。这两个都有效,但我无法弄清楚如何同时将它们包含在JFrame中。当我尝试添加两者时,我只会添加最后一个。
我在这里做了很多阅读,我知道我需要创建一个Jpanel并将每个图像添加到Jpanel然后添加到JFrame,但在这种情况下,DI是一个JPanel。
我希望有人可以提供帮助,我经历了大量的试验和错误以及大量的互联网搜索,但我没有接近答案。
这是代码 - >
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class DI extends JPanel
{
private BufferedImage image;
Rectangle r;
public DI(BufferedImage image) {
super();
this.image = image;
r = new Rectangle(10, 10, image.getWidth(), image.getHeight());
this.setFocusable(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(image, r.x, r.y, this);
//Add a border, red if picture currently has focus
if (isFocusOwner()) {
g.setColor(Color.RED);
} else {
g.setColor(Color.BLACK);
}
g2.draw(r);
}
public void setRect(int x, int y) {
r.x = x;
r.y = y;
repaint();
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
r.setSize(image.getWidth(), image.getHeight());
}
public static void main(String[] args) throws IOException {
File file = new File("happy.png");
BufferedImage image = ImageIO.read(file);
DI test = new DI(image);
DragHandler handler = new DragHandler(test);
test.addMouseListener(handler);
test.addMouseMotionListener(handler);
File file2 = new File("sad.png");
BufferedImage image2 = ImageIO.read(file2);
DI test2 = new DI(image2);
DragHandler handler2 = new DragHandler(test2);
test2.addMouseListener(handler2);
test2.addMouseMotionListener(handler2);
JFrame f = new JFrame("This is a Draggable Icon");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(test);
f.setContentPane(test2);
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
class DragHandler extends MouseInputAdapter {
DI di;
Point offset;
boolean dragging;
public DragHandler(DI di) {
this.di = di;
offset = new Point();
dragging = false;
}
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
if(di.r.contains(p)) {
offset.x = p.x - di.r.x;
offset.y = p.y - di.r.y;
dragging = true;
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
}
public void mouseDragged(MouseEvent e) {
if(dragging) {
int x = e.getX() - offset.x;
int y = e.getY() - offset.y;
di.setRect(x, y);
}
}
}
答案 0 :(得分:0)
当您调用setContentPane
方法时,整个框架将填充您提供的容器。当您执行两次时,第一个面板(test
)将被第二个面板(test2
)替换。
f.setContentPane(test);
f.setContentPane(test2);
使用现有内容窗格并指定布局管理器时,可以同时显示两个面板。您可以为面板设置尺寸甚至背景颜色(这些背景颜色可用于查看面板所覆盖的区域):
f.getContentPane().setLayout(new FlowLayout());
f.getContentPane().add(test);
f.getContentPane().add(test2);
test.setPreferredSize(new Dimension(200, 160));
test2.setPreferredSize(new Dimension(200, 160));
test.setBackground(Color.BLUE);
test2.setBackground(Color.RED);
答案 1 :(得分:0)
你的基本概念是错误的。您正在尝试创建一个大型组件,然后在组件边界内的某处绘制图像。问题是你不能将多个组件堆叠在一起。
相反,您只想拥有一个简单的面板,并在此面板中添加组件。然后使用setLocation()方法移动组件。所以不需要定制绘画。所有拖动代码都会改变组件的位置。执行此操作时,面板需要使用“空布局”,因此还负责设置添加到面板的组件的大小。
要显示图像,您应该只使用带有ImageIcon的JLabel并将图像添加到面板。
代码的基本结构是:
JLabel image1 = new JLabel( new ImageIcon(...) );
image1.setSize( image1.getPreferredSize() );
image1.addMouseListener(...);
image1.addMouseMotionListener(...);
JPanel dragPanel = new JPanel();
dragPanel.setLayout(null);
dragPanel.add( image1 );
frame.add(dragPanel, BorderLayout.CENTER);