在java中是否有任何可以用paint()
和repaint()
替换的函数。
我有一个场景。
有一个三角形(三角1)。当用户点击三角形时,将出现另一个三角形(三角形2),第一个(三角形1)将从屏幕上删除。 (使用JFrame
,paint()
和repaint()
)编码
到目前为止我已经实现了它。但问题是当我用鼠标输出窗口最小化或改变窗口大小时,它只是再次绘制三角形1 而不是三角形2 。 OR 如果我拨打g2d.clearRect(0, 0, 1000, 1000);
triangle.reset();
注意:这两个函数都是删除前一个三角形(三角形1)。
是否有任何函数在最小化或窗口大小改变时不应更改状态?
或者我们可以根据情景覆盖repaint()
或其他任何帮助。
这是工作代码。执行它,单击三角形然后最小化并再次查看。你会更清楚地解决问题。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Triangle_shape extends JFrame implements ActionListener {
public static JButton btnSubmit = new JButton("Submit");
public Triangle_shape() {
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setLayout(new BorderLayout());
frame.add(new TrianglePanel(), BorderLayout.CENTER);
frame.add(btnSubmit, BorderLayout.PAGE_END);
frame.pack();
frame.repaint();
frame.setTitle("A Test Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public static class TrianglePanel extends JPanel implements MouseListener {
private Polygon triangle, triangle2;
public TrianglePanel() {
//Create triangle
triangle = new Polygon();
triangle.addPoint(400, 550); //left
triangle.addPoint(600, 550); //right
triangle.addPoint(500, 350); //top
//Add mouse Listener
addMouseListener(this);
//Set size to make sure that the whole triangle is shown
setPreferredSize(new Dimension(300, 300));
}
/**
* Draws the triangle as this frame's painting
*/
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.draw(triangle);
}
//Required methods for MouseListener, though the only one you care about is click
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
/**
* Called whenever the mouse clicks. Could be replaced with setting the
* value of a JLabel, etc.
*/
public void mouseClicked(MouseEvent e) {
Graphics2D g2d = (Graphics2D) this.getGraphics();
Point p = e.getPoint();
if (triangle.contains(p)) {
System.out.println("1");
g2d.clearRect(0, 0, 1000, 1000);
triangle.reset();
g2d.setColor(Color.MAGENTA);
triangle2 = new Polygon();
triangle2.addPoint(600, 550); // left
triangle2.addPoint(700, 350); //top
triangle2.addPoint(800, 550); //right
g2d.draw(triangle2);
} else {
System.out.println("Triangle dont have point");
}
}
}
}
答案 0 :(得分:2)
paint()
和repaint()
工作正常,但您没有使用它们,因为它们的设计目的是使用它们。窗口系统不会保持组件外观的持久图像。它希望您的组件能够按需重新绘制其整个外观(例如,当窗口调整大小或未最小化时)。
如果你使用getGraphics()
抓取一个Graphics对象并在组件上绘制一些东西,那么当你需要重新绘制整个组件时,你绘制的东西确实会丢失。因此,您不应该这样做,而是确保您的paintComponent
方法具有完全重新绘制组件所需的所有信息。
如果您只想在屏幕上同时显示一个三角形,请不要创建单独的变量triangle2
。只需通过更改鼠标单击处理程序替换您拥有的三角形,如下所示:
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
if (triangle.contains(p)) {
triangle = new Polygon();
triangle.addPoint(600, 550); // left
triangle.addPoint(700, 350); //top
triangle.addPoint(800, 550); //right
repaint();
} else {
System.out.println("Point not in triangle");
}
}
您的paintComponent
方法应调用super.paintComponent
以确保背景已绘制,但您无需更改背景:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.draw(triangle);
}
或者,如果您尝试在屏幕上保留多个三角形,例如,要在每次点击时添加新的三角形,您应该将它们添加到list个形状中,只要组件需要,就会绘制这些形状重新粉刷:
private final List<Shape> shapes = new ArrayList<>();
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
for (Shape s : shapes)
g2d.draw(s);
}
然后控制屏幕上的形状集,操纵列表的内容,然后调用repaint();
。
例如,要在屏幕上添加新形状:
Polygon triangle = new Polygon();
triangle.addPoint(200, 300);
triangle.addPoint(200, 200);
triangle.addPoint(300, 200);
shapes.add(triangle);
repaint();
要从屏幕上删除所有形状:
shapes.clear();
repaint();
您还应该确保在程序开始时切换到Swing线程,因为从主线程与Swing组件交互是不安全的。在main
:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
.
.
.
frame.setVisible(true);
}
});
}
答案 1 :(得分:2)
您的mouseClicked
方法不应创建新的 Triangle 对象。重置triangle
后,只需为其添加新点。也不要在此方法中绘制,而是调用repaint
:
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
if (triangle.contains(p)) {
System.out.println("1");
triangle.reset(); // change the current triangle
triangle.addPoint(600, 550); // new left
triangle.addPoint(700, 350); // new top
triangle.addPoint(800, 550); // new right
repaint(); // force repainting
} else {
System.out.println("Triangle dont have point");
}
}
现在,如果你想要很多三角形,你应该有一个Polygon
的集合。像这样:
public static class TrianglePanel extends JPanel implements MouseListener {
private Vector<Polygon> triangles;
public TrianglePanel() {
n = 0;
// Create an empty collection
triangles = new Vector<Polygon>();
//Create first triangle
Polygon triangle = new Polygon();
triangle.addPoint(400, 550); //left
triangle.addPoint(600, 550); //right
triangle.addPoint(500, 350); //top
// Add the triangle to the collection
triangles.add(triangle);
//Add mouse Listener
addMouseListener(this);
//Set size to make sure that the whole triangle is shown
setPreferredSize(new Dimension(300, 300));
}
/**
* Draws the triangles as this frame's painting
*/
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (Polygon p : triangles) // Draw all triangles in the collection
g2d.draw(p);
}
//Required methods for MouseListener, though the only one you care about is click
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
/**
* Called whenever the mouse clicks. Could be replaced with setting the
* value of a JLabel, etc.
*/
public void mouseClicked(MouseEvent e) {
Graphics2D g2d = (Graphics2D) this.getGraphics();
Point p = e.getPoint();
// Do what you want with p and the collection
// For example : remove all triangles that contain the point p
ListIterator<Polygon> li = triangles.listIterator();
while (li.hasNext()) {
if (li.next().contains℗) li.remove();
}
// Do what you want to update the list
// For example: Add a new triangle...
Polygon triangle = new Polygon();
triangle.addPoint(600+n, 550); // left
triangle.addPoint(700+n, 350); //top
triangle.addPoint(800+n, 550); //right
triangles.add(triangle); // add the new triangle to the list
n += 10; // next new triangle will be "moved" right
repaint();
}
private int n;
}