继续,测试代码。程序运行时,您可以在面板上绘图,但无论何时调整大小,绘画都会消失。知道为什么或如何解决这个问题?我很乐意帮忙!
Window.java - GUI类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
public class Window extends JFrame implements ComponentListener {
public Window(){
this.setSize(700, 700);
this.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
this.setJMenuBar(menubar);
this.add(new PaintPanel());
this.setTitle("JPaint");
this.setBackground(Color.WHITE);
this.add(TOOL_BAR, BorderLayout.NORTH);
TOOL_BAR.add(BUTTON);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.add(PAINT_PANEL);
menubar.add(FILE);
FILE.setMnemonic(KeyEvent.VK_F);
FILE.add(NEW);
FILE.add(NEW_OPEN_SEPARATOR);
FILE.add(OPEN);
FILE.add(SAVE);
FILE.add(SAVE_AS);
FILE.add(SEPARATOR);
FILE.add(EXIT);
menubar.add(Box.createHorizontalGlue());
menubar.add(HELP);
HELP.add(ABOUT);
HELP.add(GNU_PUBLIC_LICENSE);
this.setVisible(true);
NEW.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PAINT_PANEL.repaint();
}
});
OPEN.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JFileChooser FILE_CHOOSER = new JFileChooser();
int CHOSEN_FILE = FILE_CHOOSER.showOpenDialog(FILE_CHOOSER);
}
});
SAVE.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JFileChooser SAVE_FILE_CHOOSER = new JFileChooser();
SAVE_FILE_CHOOSER.showSaveDialog(null);
Container c = frame.getContentPane();
BufferedImage SAVED_IMAGE = new BufferedImage(c.getWidth(), c
.getHeight(), BufferedImage.TYPE_INT_ARGB);
c.paint(SAVED_IMAGE.getGraphics());
try {
ImageIO.write(SAVED_IMAGE, "PNG", new File("test.png"));
} catch (IOException e1) {
// If unable to save image for 'Exception' reason.
e1.printStackTrace();
}
}
});
EXIT.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
ABOUT.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
JOptionPane
.showMessageDialog(frame,
"Created by Matthew Hanzelik for "
+ "open source use!");
}
});
GNU_PUBLIC_LICENSE.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "gpl.txt");
}
});
}
/**
* Serial Version
*/
private static final JFrame frame = new JFrame();
private static final long serialVersionUID = 5259700796854880162L;
private static final JMenuBar menubar = new JMenuBar();
private static final JMenu FILE = new JMenu("File");
private static final JMenu HELP = new JMenu("Help");
private static final JMenuItem SAVE = new JMenuItem("Save");
private static final JMenuItem EXIT = new JMenuItem("Exit");
private static final JSeparator SEPARATOR = new JSeparator();
private static final JSeparator NEW_OPEN_SEPARATOR = new JSeparator();
private static final JMenuItem NEW = new JMenuItem("New");
private static final JMenuItem OPEN = new JMenuItem("Open");
private static final JMenuItem SAVE_AS = new JMenuItem("Save as...");
private static final JMenuItem ABOUT = new JMenuItem("About");
private static final JMenuItem GNU_PUBLIC_LICENSE = new JMenuItem(
"GNU Public License");
private static final JToolBar TOOL_BAR = new JToolBar();
private static final JButton BUTTON = new JButton("Test");
private static final PaintPanel PAINT_PANEL = new PaintPanel();
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Window GUI = new Window();
}
});
}
@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
System.out.println("resized");
}
@Override
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
}
PaintPanel - 包含要在其上绘制的面板的类
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class PaintPanel extends JPanel {
MouseMotionListener theListener;
Graphics g;
MouseListener theListening;
int x, y, x1, y1;
boolean inside;
public PaintPanel() {
x = 0;
y = 0;
x1 = -99;
y1 = -99;
inside = false;
theListener = new MouseMotionListener() {
public void mouseDragged(MouseEvent arg0) {
if (inside) {
repaint();
}
}
public void mouseMoved(MouseEvent arg0) {
}
};
theListening = new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
x1 = -99;
y1 = -99;
}
public void mouseEntered(MouseEvent arg0) {
inside = true;
x1 = -99;
y1 = -99;
}
public void mouseExited(MouseEvent arg0) {
inside = false;
x1 = -99;
y1 = -99;
}
};
this.setBackground(Color.WHITE);
this.setVisible(true);
this.addMouseMotionListener(theListener);
this.addMouseListener(theListening);
}
@Override
public void paint(Graphics g) {
try {
if (x1 == -99) {
x = getMousePosition().x;
x1 = x;
y = getMousePosition().y;
y1 = y;
} else
{
x = getMousePosition().x;
y = getMousePosition().y;
g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
} catch (Exception ex) {
}
}
}
答案 0 :(得分:2)
两件事:首先,在扩展JComponent
时,您应该覆盖paintCompontent
,而不是paint
。
其次,在paintComponent
内,您需要渲染用户绘制的所有行。这意味着您需要在绘制时存储它们,然后每次都在paintComponent
内部渲染它们。这是因为只要窗口需要重新渲染(例如,窗口已经最小化然后恢复),就会调用paintComponent
。在这种情况下,Swing不会“记住”您将哪些像素设置为哪种颜色。相反,它会调用paintComponent
并希望您重新创建它们。
此外,当您覆盖paintComponent
时,您很可能希望在执行任何渲染工作之前调用super.paintComponent
。
答案 1 :(得分:1)
,但每当它调整大小时,油漆就会消失。知道为什么或如何解决这个问题?
如果你想做增量绘画,那么有两种常见的方法:
有关每种方法的更多信息和工作示例,请参阅Custom Painting Approaches。