绝对定位图形JPanel内部JFrame由空白部分阻止 [英] Absolute Positioning Graphic JPanel Inside JFrame Blocked by Blank Sections

查看:139
本文介绍了绝对定位图形JPanel内部JFrame由空白部分阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过制作一个谜题程序来提高对Java的了解,尤其是Java GUI。目前,用户选择一张图像,该图像被分割成指定数量的图像。这些作品是随机抽取到屏幕上的,但它们似乎被其他作品的空白部分覆盖,并不是所有作品都显示出来,但我可以打印出所有的坐标。我正在使用绝对定位,因为LayoutManager似乎不工作。我简单地尝试了layeredPanes,但他们困惑了我,似乎没有解决问题。我非常感谢一些帮助。

以下是两个相关的类:

  import javax.swing。 *; 
import java.awt。*;
import java.awt.image。*;
import java.awt.event。*;

public class PuzzlePieceDriver extends JFrame
{
private static Dimension SCREENSIZE = Toolkit.getDefaultToolkit()。getScreenSize();
private static final int HEIGHT = SCREENSIZE.height;
private static final int WIDTH = SCREENSIZE.width;

public static int MY_WIDTH;
public static int MY_HEIGHT;

private static BufferedImage image;


private int xPieces = PuzzleMagicDriver.getXPieces();
private int yPieces = PuzzleMagicDriver.getYPieces();

private PuzzlePiece [] puzzle = new PuzzlePiece [xPieces * yPieces];

public Container pane = this.getContentPane();
private JLayeredPane layeredPane = new JLayeredPane();

$ b $ public PuzzlePieceDriver(ImageIcon myPuzzleImage)
{
MY_WIDTH = myPuzzleImage.getIconWidth()+(int)myPuzzleImage.getIconHeight()/ 2;
MY_HEIGHT = myPuzzleImage.getIconHeight()+(int)myPuzzleImage.getIconHeight()/ 2;
setTitle(Hot Puzz);
setSize(MY_WIDTH,MY_HEIGHT);
setLocationByPlatform(true);

pane.setLayout(null);


image = iconToImage(myPuzzleImage); //将图像传递到bufferedImage形式

puzzle = createClip(image);

//pane.add(layeredPane);


setVisible(true);
} //结束构造函数



public static BufferedImage iconToImage(ImageIcon icon)
{
Image img = icon.getImage() ;
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage image = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
//将图像绘制到缓冲图像上
g.drawImage(img,0,0,null);
g.dispose();

return image;
} // end BufferedImage

protected int randomNumber(int min,int max)
{
int temp =
min +(int)(Math .random()*((max - min)+ 1));

return temp;
} // end randomNumber


private PuzzlePiece [] createClip(BufferedImage passedImage)
{

int cw,ch;
int w,h;
w = image.getWidth(null);
h = image.getHeight(null);
cw = w / xPieces;
ch = h / yPieces;

int [] cells = new int [xPieces * yPieces];

int dx,dy;

BufferedImage clip = passedImage;

//layeredPane.setPreferredSize(new Dimension(w,h));

for(int x = 0; x {
int sx = x * cw;
for(int y = 0; y {
int sy = y * ch;
int cell = cells [x * xPieces + y];
dx =(cell / xPieces)* cw;
dy =(cell%yPieces)* ch;

clip = passedImage.getSubimage(sx,sy,cw,ch);
int myX = randomNumber(0,(int)w);
int myY = randomNumber(0,(int)h);

PuzzlePiece piece = new PuzzlePiece(clip,myX,myY);
puzzle [x * xPieces + y] = piece;
piece.setBounds(myX,myY,w,h);
//layeredPane.setBounds(myX,myY,w,h);
//layeredPane.add(piece,new Integer(x * xPieces + y));
pane.add(piece);
piece.repaint();

} //结束嵌套
} //结束
返回拼图;
} // end createClip

// end class

对不起,如果间距有点乱!

  import javax.swing。*; 
import java.awt。*;
import java.awt.event。*;
import java.awt.image。*;

public class PuzzlePiece extends JPanel
{
private point imageCorner; //图像的左上角位置
private Point prevPt; //前一个事件的鼠标位置
private Boolean insideImage = false;

私有BufferedImage图像;

public PuzzlePiece(BufferedImage clip,int x,int y)
{
image = clip;
imageCorner = new Point(x,y);
// repaint();
} //结束构造函数

public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image,(int)getImageCornerX(),(int)getImageCornerY(),this);
System.out.println(paint+ getImageCornerX()++ getImageCornerY());
// repaint();
//g.dispose();
} //结束paintComponent

public Point getImageCorner()
{
return imageCorner;
} //结束getImageCorner
public double getImageCornerY()
{
return imageCorner.getY();
} // end getImageCornerY
public double getImageCornerX()
{
return imageCorner.getX();
} // end getPoint


} // end class PuzzlePiece

任何帮助将不胜感激,我真的被卡住了!感谢!!

解决方案

我非常喜欢这个想法,所以我做了另一个例子,使用自定义布局管理器。 p>

  public class MyPuzzelBoard extends JPanel {

public static final int GRID_X = 4;
public static final int GRID_Y = 4;
私有BufferedImage图像;

public MyPuzzelBoard(BufferedImage image){
setLayout(new VirtualLayoutManager());
setImage(image);

addMouseListener(new MouseAdapter(){
@Override $ b $ public void mouseClicked(MouseEvent e){
if(e.getClickCount()== 2){
removeAll();
generatePuzzel();
} else {
Component comp = getComponentAt(e.getPoint());
if(comp!= null& & comp!= MyPuzzelBoard.this){
setComponentZOrder(comp,0);
invalidate();
revalidate();
repaint();
}
}
}
});
}

public void setImage(BufferedImage value){
if(value!= image){
image = value;
removeAll();
generatePuzzel();



public BufferedImage getImage(){
return image;


protected float generateRandomNumber(){
return(float)Math.random();
}

protected void generatePuzzel(){
BufferedImage image = getImage();

if(image!= null){
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();

int clipWidth = imageWidth / GRID_X;
int clipHeight = imageHeight / GRID_Y;
for(int x = 0; x for(int y = 0; y
float xPos = generateRandomNumber ();
float yPos = generateRandomNumber();
Rectangle bounds = new Rectangle((x * clipWidth),(y * clipHeight),clipWidth,clipHeight);
MyPiece piece = new MyPiece(image,bounds);
add(piece,new VirtualPoint(xPos,yPos));





invalidate();
revalidate();
repaint();
}

public class VirtualPoint {

private float x;
私人浮动y;

public VirtualPoint(float x,float y){
this.x = x;
this.y = y;
}

public float getX(){
return x;
}

public float getY(){
return y;
}

public void setX(float x){
this.x = x;
}

public void setY(float y){
this.y = y;



public class VirtualLayoutManager实现LayoutManager2 {

private Map< Component,VirtualPoint> mapConstraints;

public VirtualLayoutManager(){
mapConstraints = new WeakHashMap<>(25);

$ b @Override
public void addLayoutComponent(Component comp,Object constraints){
if(约束instance instanceof VirtualPoint){
mapConstraints.put(comp ,(VirtualPoint)限制);


$ b @Override
public Dimension maximumLayoutSize(Container target){
return new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE);
}

@Override
public float getLayoutAlignmentX(Container target){
return 0.5f;
}

@Override
public float getLayoutAlignmentY(Container target){
return 0.5f;
}

@Override
public void invalidateLayout(Container target){
}
$ b $ @覆盖
public void addLayoutComponent(字符串名称,Component comp){
}

@Override
public void removeLayoutComponent(Component comp){
mapConstraints.remove(comp);

$ b @Override
public Dimension preferredLayoutSize(Container parent){
return new Dimension(400,400);
}

@Override
public Dimension minimumLayoutSize(Container parent){
return preferredLayoutSize(parent);
}

@Override
public void layoutContainer(Container parent){
int width = parent.getWidth();
int height = parent.getHeight();

for(Component comp:parent.getComponents()){

VirtualPoint p = mapConstraints.get(comp);
if(p!= null){

int x = Math.round(width * p.getX());
int y = Math.round(height * p.getY());

Dimension size = comp.getPreferredSize();

x = Math.min(x,width - size.width);
y = Math.min(y,height - size.height);

comp.setBounds(x,y,size.width,size.height);






code $ pre

基本上,这使用了一个虚拟坐标系统,而不是以像素为单位提供绝对x / y位置,而是将它们提供为父容器的百分比。现在,说实话,转换回绝对定位并不需要太多,就这样,你也可以得到布局缩放。



这个例子还演示了Z- (为了以防万一)和双击简单重新随机化puzzel



哦,我也让这件作品透明( opaque = false





哦,我应该提到的一点是,在通过这个例子的时候,我发现可以将部分片段放在屏幕外(完全或部分)。



您可能需要检查您的定位代码,以确保图像在布置时不会移出屏幕;)

I'm trying to improve my understanding of Java, particularly Java GUI, by making a puzzle program. Currently the user selects an image, which is cut up into a specified number of pieces. The pieces are drawn randomly to the screen but they seem to be covered by blank portions of other pieces, and not all of them show up, but I can print out all the coordinates. I am using absolute positioning because a LayoutManager didn't seem to work. I briefly tried layeredPanes but they confused me and didn't seem to solve the problem. I would really appreciate some help.
Here are the 2 relevant classes:

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;

public class PuzzlePieceDriver extends JFrame
{
  private static Dimension SCREENSIZE = Toolkit.getDefaultToolkit().getScreenSize();
  private static final int HEIGHT = SCREENSIZE.height;
  private static final int WIDTH = SCREENSIZE.width;

  public static int MY_WIDTH;
  public static int MY_HEIGHT;

  private static BufferedImage image;


  private int xPieces = PuzzleMagicDriver.getXPieces();
  private int yPieces = PuzzleMagicDriver.getYPieces();

  private PuzzlePiece[] puzzle = new PuzzlePiece[xPieces*yPieces];

  public Container pane = this.getContentPane();
  private JLayeredPane layeredPane = new JLayeredPane();


  public PuzzlePieceDriver(ImageIcon myPuzzleImage)
  {
    MY_WIDTH = myPuzzleImage.getIconWidth()+(int)myPuzzleImage.getIconHeight()/2;
    MY_HEIGHT = myPuzzleImage.getIconHeight()+(int)myPuzzleImage.getIconHeight()/2;
    setTitle("Hot Puzz");
setSize(MY_WIDTH,MY_HEIGHT);
setLocationByPlatform(true);

pane.setLayout(null);


image = iconToImage(myPuzzleImage); //pass image into bufferedImage form

puzzle = createClip(image);

//pane.add(layeredPane);


setVisible(true);
  }//end constructor



  public static BufferedImage iconToImage(ImageIcon icon)
  {
    Image img = icon.getImage();
 int w = img.getWidth(null);
 int h = img.getHeight(null);
 BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
 Graphics g = image.createGraphics();
     // Paint the image onto the buffered image
    g.drawImage(img, 0, 0, null);
    g.dispose();

    return image;
  }//end BufferedImage

  protected int randomNumber(int min, int max)
  {
    int temp = 
    min + (int)(Math.random() * ((max - min) + 1));

 return temp;
  }//end randomNumber


  private PuzzlePiece[] createClip(BufferedImage passedImage)
  {

 int cw, ch;
 int w,h;
 w = image.getWidth(null);
 h = image.getHeight(null);
 cw = w/xPieces;
     ch = h/yPieces;

 int[] cells=new int[xPieces*yPieces];

 int dx, dy;

 BufferedImage clip = passedImage;

 //layeredPane.setPreferredSize(new Dimension(w,h));

    for (int x=0; x<xPieces; x++) 
      {
        int sx = x*cw;
        for (int y=0; y<yPieces; y++) 
            {
            int sy = y*ch;
            int cell = cells[x*xPieces+y];
            dx = (cell / xPieces) * cw;
            dy = (cell % yPieces) * ch;

            clip= passedImage.getSubimage(sx, sy, cw, ch);
    int myX = randomNumber(0,(int)w);
    int myY = randomNumber(0,(int)h);

    PuzzlePiece piece=new PuzzlePiece(clip,myX,myY);
    puzzle[x*xPieces+y]=piece;
    piece.setBounds(myX,myY,w,h);
    //layeredPane.setBounds(myX,myY,w,h);
    //layeredPane.add(piece,new Integer(x*xPieces+y));
    pane.add(piece);
    piece.repaint();

        }//end nested for
}//end for
return puzzle;
  }//end createClip

}//end class

Sorry if the spacing is a little messed up!

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class PuzzlePiece extends JPanel
{
private Point imageCorner;      //the image's top-left corner location
private Point prevPt;               //mouse location for previous event
private Boolean insideImage =false;

private BufferedImage image;

public PuzzlePiece(BufferedImage clip, int x, int y)
{
 image = clip;
 imageCorner = new Point(x,y);
 //repaint();
}//end constructor

public void paintComponent(Graphics g)
{
     super.paintComponent(g);
 g.drawImage(image, (int)getImageCornerX(),(int)getImageCornerY(), this);
     System.out.println("paint "+getImageCornerX()+"   "+getImageCornerY());
    //repaint(); 
//g.dispose();
}//end paintComponent

public Point getImageCorner()
{
  return imageCorner;
}//end getImageCorner
public double getImageCornerY()
{
  return imageCorner.getY();
}//end getImageCornerY
public double getImageCornerX()
{
  return imageCorner.getX();
}//end getPoint


}//end class PuzzlePiece

Any help would be appreciated, I've gotten really stuck! Thanks!!

解决方案

I was really intrigued by this idea, so I made another example, using a custom layout manager.

public class MyPuzzelBoard extends JPanel {

    public static final int GRID_X = 4;
    public static final int GRID_Y = 4;
    private BufferedImage image;

    public MyPuzzelBoard(BufferedImage image) {
        setLayout(new VirtualLayoutManager());
        setImage(image);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    removeAll();
                    generatePuzzel();
                } else {
                    Component comp = getComponentAt(e.getPoint());
                    if (comp != null && comp != MyPuzzelBoard.this) {
                        setComponentZOrder(comp, 0);
                        invalidate();
                        revalidate();
                        repaint();
                    }
                }
            }
        });
    }

    public void setImage(BufferedImage value) {
        if (value != image) {
            image = value;
            removeAll();
            generatePuzzel();
        }
    }

    public BufferedImage getImage() {
        return image;
    }

    protected float generateRandomNumber() {
        return (float) Math.random();
    }

    protected void generatePuzzel() {
        BufferedImage image = getImage();

        if (image != null) {
            int imageWidth = image.getWidth();
            int imageHeight = image.getHeight();

            int clipWidth = imageWidth / GRID_X;
            int clipHeight = imageHeight / GRID_Y;
            for (int x = 0; x < GRID_X; x++) {
                for (int y = 0; y < GRID_Y; y++) {

                    float xPos = generateRandomNumber();
                    float yPos = generateRandomNumber();
                    Rectangle bounds = new Rectangle((x * clipWidth), (y * clipHeight), clipWidth, clipHeight);
                    MyPiece piece = new MyPiece(image, bounds);
                    add(piece, new VirtualPoint(xPos, yPos));

                }
            }
        }

        invalidate();
        revalidate();
        repaint();
    }

    public class VirtualPoint {

        private float x;
        private float y;

        public VirtualPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }

        public void setX(float x) {
            this.x = x;
        }

        public void setY(float y) {
            this.y = y;
        }
    }

    public class VirtualLayoutManager implements LayoutManager2 {

        private Map<Component, VirtualPoint> mapConstraints;

        public VirtualLayoutManager() {
            mapConstraints = new WeakHashMap<>(25);
        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            if (constraints instanceof VirtualPoint) {
                mapConstraints.put(comp, (VirtualPoint) constraints);
            }
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
        }

        @Override
        public float getLayoutAlignmentX(Container target) {
            return 0.5f;
        }

        @Override
        public float getLayoutAlignmentY(Container target) {
            return 0.5f;
        }

        @Override
        public void invalidateLayout(Container target) {
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            mapConstraints.remove(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return new Dimension(400, 400);
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return preferredLayoutSize(parent);
        }

        @Override
        public void layoutContainer(Container parent) {
            int width = parent.getWidth();
            int height = parent.getHeight();

            for (Component comp : parent.getComponents()) {

                VirtualPoint p = mapConstraints.get(comp);
                if (p != null) {

                    int x = Math.round(width * p.getX());
                    int y = Math.round(height * p.getY());

                    Dimension size = comp.getPreferredSize();

                    x = Math.min(x, width - size.width);
                    y = Math.min(y, height - size.height);

                    comp.setBounds(x, y, size.width, size.height);

                }
            }
        }
    }
}

Basically, this uses a "virtual" coordinate system, where by rather then supply absolute x/y positions in pixels, you provide them as percentage of the parent container. Now, to be honest, it wouldn't take much to convert back to absolute positioning, just this way, you also get layout scaling.

The example also demonstrates Z-reording (just in case) and the double click simple re-randomizes the puzzel

Oh, I also made the piece transparent (opaque = false)

Oh, one thing I should mention, while going through this example, I found that it was possible to have pieces placed off screen (completely and partially).

You may want to check your positioning code to make sure that the images when they are laid out aren't been moved off screen ;)

这篇关于绝对定位图形JPanel内部JFrame由空白部分阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆