我有这个问题困扰了我好几天。我正在制作一个特殊的油漆程序。我制作了一个JPanel,并添加了使用paint(..)方法绘制的自定义jComponents。 问题是,每当我调整窗口大小时,所有添加的组件都会消失。 (或者只是不要画画)所以我最终得到一个空框架。
我也注意到使用这种方法时有一些奇怪的挥杆动作。我在描述此问题的代码中添加了注释。
package simple;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class SimpleFrame extends JFrame {
JPanel paintArea;
SimpleCanvas c1;
SimpleCanvas c2;
ArrayList<SimpleCanvas> list;
public static void main(String[] args) {
SimpleFrame frame = new SimpleFrame();
}
public SimpleFrame() {
super("Test");
setSize(600,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//The panel to which my SimpleCanvas objects are added
paintArea = new JPanel();
paintArea.setPreferredSize(new Dimension(600, 500));
paintArea.addMouseListener(new paintAreaMouseEvents());
getContentPane().add(paintArea, BorderLayout.CENTER);
setVisible(true);
paintArea.setVisible(true);
//A list to hold all the objects together
list = new ArrayList<SimpleCanvas>(10);
//The same as in class paintAreaMouseEvent, but doesnt work
SimpleCanvas c = new SimpleCanvas();
c.setBounds(60, 100, 100, 50);
list.add(c);
paintArea.add(list.get(list.size() - 1));
paintArea.repaint();
}
//When you click the mouse, it makes an oval
class paintAreaMouseEvents extends MouseAdapter {
@Override
//This does work.
public void mouseClicked (MouseEvent me) {
SimpleCanvas c = new SimpleCanvas();
c.setBounds(me.getX() - 50, me.getY() - 25, 100, 50);
list.add(c);
paintArea.add(list.get(list.size() - 1));
paintArea.repaint();
}
}
}
这是SimpleCanvas类
package simple;
import java.awt.*;
import javax.swing.JComponent;
public class SimpleCanvas extends JComponent {
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLUE);
g.fillOval(0, 0, 100, 50);
}
}
谢谢:)
BTW:只是想说这个网站很棒。我在使用谷歌的时候来到这里很多,现在我终于决定开个账户了。答案 0 :(得分:6)
您的问题是布局问题。添加:
System.out.println(getSize());
到您的JComponent的paint方法,看看在调整GUI大小时会发生什么。
这种情况正在发生,因为调整大小正在调用布局管理器操作。
要解决此问题,请不要使用setBounds(...)
来调整组件大小,而是使用布局管理器。如果希望布局管理器遵守特定的大小,也可以覆盖JComponent的getPreferredSize方法。最后,不要使用paint
方法绘制,而是使用paintComponent
方法绘制。教程将解释原因。
此外,如果您绝对需要使用绝对定位来定位某些内容,那么容器必须使用空布局:
// The panel to which my SimpleCanvas objects are added
paintArea = new JPanel(null);
修改强>
如果我正在执行类似上面的程序,我不确定我是否会向JPanel添加新组件,而只是让绘图JPanel保存一个Shapes列表,然后使用一个paintComponent方法绘制形状。 for循环。例如:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class SimpleFrame2 extends JPanel {
private static final Color ELLIPSE_COLOR = Color.LIGHT_GRAY;
private static final Color ELLIPSE_FILL_COLOR = Color.blue;
private static final int PREF_W = 600;
private static final int PREF_H = 500;
public static final int ELLIPSE_WIDTH = 100;
public static final int ELLIPSE_HEIGHT = 50;
private static final Stroke ELLIPSE_STROKE = new BasicStroke(2f);
private List<Shape> shapes = new ArrayList<Shape>();
public SimpleFrame2() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mEvt) {
double x = mEvt.getX() - ELLIPSE_WIDTH / 2;
double y = mEvt.getY() - ELLIPSE_HEIGHT / 2;
double w = ELLIPSE_WIDTH;
double h = ELLIPSE_HEIGHT;
shapes.add(new Ellipse2D.Double(x, y, w, h));
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// to draw smooth edges
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(ELLIPSE_STROKE);
for (Shape shape : shapes) {
g2.setColor(ELLIPSE_FILL_COLOR);
g2.fill(shape);
g2.setColor(ELLIPSE_COLOR);
g2.draw(shape);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleFrame2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleFrame2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
编辑2
拖动形状
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleFrame3 extends JPanel {
private static final Color ELLIPSE_COLOR = Color.LIGHT_GRAY;
private static final Color ELLIPSE_FILL_COLOR = Color.blue;
private static final int PREF_W = 600;
private static final int PREF_H = 500;
public static final int ELLIPSE_WIDTH = 100;
public static final int ELLIPSE_HEIGHT = 50;
private static final Stroke ELLIPSE_STROKE = new BasicStroke(2f);
private List<RectangularShape> rects = new ArrayList<RectangularShape>();
public SimpleFrame3() {
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// to draw smooth edges
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(ELLIPSE_STROKE);
for (RectangularShape rect : rects) {
g2.setColor(ELLIPSE_FILL_COLOR);
g2.fill(rect);
g2.setColor(ELLIPSE_COLOR);
g2.draw(rect);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
class MyMouseAdapter extends MouseAdapter {
private RectangularShape selectedRect = null;
private Point deltaPt = null;
@Override
public void mousePressed(MouseEvent mEvt) {
if (mEvt.getButton() != MouseEvent.BUTTON1) {
return;
}
if (rects.size() > 0) {
for (int i = rects.size() - 1; i >= 0; i--) {
if (rects.get(i).contains(mEvt.getPoint())) {
selectedRect = rects.get(i);
rects.remove(selectedRect);
rects.add(rects.size(), selectedRect);
deltaPt = new Point(mEvt.getX() - selectedRect.getBounds().x,
mEvt.getY() - selectedRect.getBounds().y);
repaint();
return;
}
}
}
double x = mEvt.getX() - ELLIPSE_WIDTH / 2;
double y = mEvt.getY() - ELLIPSE_HEIGHT / 2;
double w = ELLIPSE_WIDTH;
double h = ELLIPSE_HEIGHT;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
rects.add(ellipse);
selectedRect = ellipse;
deltaPt = new Point((int)(mEvt.getX() - x), (int)(mEvt.getY() - y));
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (selectedRect != null) {
Rectangle bounds = selectedRect.getBounds();
bounds.setLocation(e.getX() - deltaPt.x, e.getY() - deltaPt.y);
selectedRect.setFrame(bounds.x, bounds.y, bounds.width, bounds.height);
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (selectedRect != null) {
repaint();
selectedRect = null;
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleFrame3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleFrame3());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}