Java 调整添加的绘制组件的大小和奇怪的摆动行为
这个问题困扰了我好几天。我正在制作一个特殊的绘画程序。我制作了一个JPanel,并添加了使用paint(..)方法绘制的定制jComponents。 问题是,每当我调整窗口大小时,所有添加的组件都会“消失”(或只是不绘制),因此我最终会得到一个空框架 在使用这种方法时,我还注意到一些奇怪的挥杆行为。我已经在描述这个问题的代码中添加了注释Java 调整添加的绘制组件的大小和奇怪的摆动行为,java,swing,Java,Swing,这个问题困扰了我好几天。我正在制作一个特殊的绘画程序。我制作了一个JPanel,并添加了使用paint(..)方法绘制的定制jComponents。 问题是,每当我调整窗口大小时,所有添加的组件都会“消失”(或只是不绘制),因此我最终会得到一个空框架 在使用这种方法时,我还注意到一些奇怪的挥杆行为。我已经在描述这个问题的代码中添加了注释 package simple; import java.awt.*; import java.awt.event.*; import java.util.Ar
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();
}
}
}
谢谢:)
顺便说一句:我只是想说这个网站太棒了。我在使用谷歌时经常来这里,现在我终于决定建立一个帐户。你的问题是布局问题。加:
System.out.println(getSize());
查看JComponent的绘制方法,以查看调整GUI大小时发生的情况
发生这种情况是因为“调整大小”正在调用布局管理器操作
要解决这个问题,不要使用setBounds(…)
来调整组件的大小,而是使用布局管理器。如果希望布局管理器尊重JComponent的特定大小,还可以重写它的getPreferredSize方法。最后,不要使用paint
方法进行绘制,而是使用paintComponent
方法。教程将解释原因
此外,如果您绝对需要使用绝对定位来定位某些内容,则容器必须使用空布局:
// The panel to which my SimpleCanvas objects are added
paintArea = new JPanel(null);
编辑如果我在做类似于上面的程序的事情,我不确定是否会向JPanel添加新组件,而是简单地让绘图JPanel保存一个形状列表,然后使用for循环在其paintComponent方法中绘制形状。例如:
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();
}
});
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.Stroke;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Ellipse2D;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.*;
公共类SimpleFrame2扩展了JPanel{
私有静态最终颜色椭圆\u颜色=Color.LIGHT\u灰色;
私有静态最终颜色椭圆\填充\颜色=Color.blue;
专用静态最终整型预调W=600;
专用静态最终int PREF_H=500;
公共静态最终整数椭圆_宽度=100;
公共静态最终整数椭圆高度=50;
专用静态最终行程椭圆_行程=新基本行程(2f);
私有列表形状=新的ArrayList();
公共SimpleFrame2(){
addMouseListener(新的MouseAdapter(){
@凌驾
公共无效鼠标按下(MouseEvent mEvt){
double x=mEvt.getX()-椭圆宽度/2;
双y=mEvt.getY()-椭圆高度/2;
双w=椭圆宽度;
双h=椭圆高度;
添加(新的椭圆2d.Double(x,y,w,h));
重新油漆();
}
});
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
//画光滑的边
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.设定行程(椭圆_行程);
用于(形状:形状){
g2.设置颜色(椭圆填充颜色);
g2.填充(形状);
g2.设置颜色(椭圆颜色);
g2.绘制(形状);
}
}
@凌驾
公共维度getPreferredSize(){
返回新维度(PREF_W,PREF_H);
}
私有静态void createAndShowGui(){
JFrame=新的JFrame(“SimpleFrame2”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(新的SimpleFrame2());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
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();
}
});
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.RenderingHints;
导入java.awt.Stroke;
导入java.awt.event.*;
导入java.awt.geom.*;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.*;
@抑制警告(“串行”)
公共类SimpleFrame3扩展了JPanel{
私有静态最终颜色椭圆\u颜色=Color.LIGHT\u灰色;
私有静态最终颜色椭圆\填充\颜色=Color.blue;
专用静态最终整型预调W=600;
专用静态最终int PREF_H=500;
公共静态最终整数椭圆_宽度=100;
公共静态最终整数椭圆高度=50;
专用静态最终行程椭圆_行程=新基本行程(2f);
private List rects=new ArrayList();
公共SimpleFrame3(){
MyMouseAdapter MyMouseAdapter=新的MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
//画光滑的边
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.设定行程(椭圆_行程);
for(矩形形状rect:rects){
g2.设置颜色(椭圆填充颜色);
g2.填充(rect);
g2.设置颜色(椭圆颜色);
g2.绘制(rect);
}
}
@凌驾
公共维度getPreferredSize(){
返回新维度(PREF_W,PREF_H);
}
类MyMouseAdapter扩展了MouseAdapter{
私有矩形形状selectedRect=null;
私有点deltaPt=null;
@凌驾
公共无效鼠标按下(MouseEvent mEvt){
if(mEvt.getButton()!=MouseEvent.BUTTON1){
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();
}
});
}
}