This question already has an answer here:
这个问题在这里已有答案:
- How to serialize Java 2D Shape objects as XML? 2 answers
如何将Java 2D Shape对象序列化为XML? 2个答案
I have a program that lets the user add rectangles and circles to JPanel using Graphics. What I want to be able to do is save the current state of the current JPanel (i.e. all of the shapes and their locations) into a file and be able to load that file back and restore that state. I have a Shapes class that extends JPanel and does all of the drawing and keeps track of the shapes with an ArrayList.
我有一个程序,允许用户使用Graphics向JPanel添加矩形和圆圈。我希望能够做的是将当前JPanel的当前状态(即所有形状及其位置)保存到文件中,并能够加载该文件并恢复该状态。我有一个Shapes类,它扩展了JPanel并完成所有绘图并使用ArrayList跟踪形状。
Will I be able to just simply save the state of the panel? Or will I have to just save the Shapes data into a file and redraw the shapes when a file is "opened"?
我能够简单地保存面板的状态吗?或者我必须将形状数据保存到文件中并在文件“打开”时重绘形状?
Can anyone guide me on how I can save the current state of my JPanel and re-open it? Thanks
任何人都可以指导我如何保存我的JPanel的当前状态并重新打开它?谢谢
public class UMLEditor {
public static void main(String[] args) {
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class UMLWindow extends JFrame {
Shapes shapeList = new Shapes();
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(shapeList);
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem openMenuItem = new JMenuItem("Open File");
openMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Open saved state
});
JMenuItem saveMenuItem = new JMenuItem("Save");
saveMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Save current state
}
});
file.add(openMenuItem);
file.add(saveMenuItem);
JMenu shapes = new JMenu("Shapes");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
rectangleMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
shapeList.addSquare(100, 100);
}
});
JMenuItem circleMenuItem = new JMenuItem("New Circle");
circleMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
shapeList.addCircle(100, 100);
}
});
shapes.add(rectangleMenuItem);
shapes.add(circleMenuItem);
menubar.add(file);
menubar.add(shapes);
setJMenuBar(menubar);
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
// Shapes class, used to draw the shapes on the panel
// as well as implements the MouseListener for dragging
class Shapes extends JPanel {
private static final long serialVersionUID = 1L;
private List<Path2D> shapes = new ArrayList<Path2D>();
int currentIndex;
public Shapes() {
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
public void addSquare(int width, int height) {
Path2D rect2 = new Path2D.Double();
rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
- height / 2, width, height), true);
shapes.add(rect2);
repaint();
}
public void addCircle(int width, int height) {
Path2D rect2 = new Path2D.Double();
rect2.append(new Ellipse2D.Double(getWidth() / 2 - width / 2,
getHeight() / 2 - height / 2, width, height), true);
shapes.add(rect2);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Path2D rect : shapes) {
g2.draw(rect);
}
}
class MyMouseAdapter extends MouseAdapter {
private boolean pressed = false;
private Point point;
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
for (int i = 0; i < shapes.size(); i++) {
if (shapes.get(i) != null
&& shapes.get(i).contains(e.getPoint())) {
currentIndex = i;
pressed = true;
this.point = e.getPoint();
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (pressed) {
int deltaX = e.getX() - point.x;
int deltaY = e.getY() - point.y;
shapes.get(currentIndex).transform(
AffineTransform.getTranslateInstance(deltaX, deltaY));
point = e.getPoint();
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
pressed = false;
}
}
}
1 个解决方案
#1
0
You could add a line of code in addCircle and addSquare that stores their H and W (or instances of the shapes themselves) in a serialized array (which could be saved to a .dat file). Then read the file and shapes.add(tehShape) for each shape entry in the dat file and repaint when needed. Used this method on an android app when i needed a persistent storage of customized ListView items. Not pretty, but it worked like a charm once properly set up. Upside of this is that you will be saving identical object instances in the dat file, downside is that they wont be human-readable.
您可以在addCircle和addSquare中添加一行代码,它们将H和W(或形状本身的实例)存储在序列化数组中(可以保存为.dat文件)。然后读取dat文件中每个形状条目的文件和shapes.add(tehShape),并在需要时重新绘制。当我需要持久存储自定义ListView项目时,在Android应用程序上使用此方法。不漂亮,但一旦正确设置,它就像一个魅力。这样做的好处是你将在dat文件中保存相同的对象实例,缺点是它们不会是人类可读的。
#1
0
You could add a line of code in addCircle and addSquare that stores their H and W (or instances of the shapes themselves) in a serialized array (which could be saved to a .dat file). Then read the file and shapes.add(tehShape) for each shape entry in the dat file and repaint when needed. Used this method on an android app when i needed a persistent storage of customized ListView items. Not pretty, but it worked like a charm once properly set up. Upside of this is that you will be saving identical object instances in the dat file, downside is that they wont be human-readable.
您可以在addCircle和addSquare中添加一行代码,它们将H和W(或形状本身的实例)存储在序列化数组中(可以保存为.dat文件)。然后读取dat文件中每个形状条目的文件和shapes.add(tehShape),并在需要时重新绘制。当我需要持久存储自定义ListView项目时,在Android应用程序上使用此方法。不漂亮,但一旦正确设置,它就像一个魅力。这样做的好处是你将在dat文件中保存相同的对象实例,缺点是它们不会是人类可读的。