为什么矩形没有显示?

时间:2016-09-24 22:16:10

标签: java jframe

我检查了这段代码几个小时,但矩形没有显示,有人可以告诉我为什么它没有显示?:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        int resx = 700,resy = 500;
        frame.setSize(resx,resy);
        frame.setLocationRelativeTo(null);
        frame.setTitle("Game");
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        try {
            frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("C:\\Users\\ivans\\Pictures\\Cookies.png")))));
        } catch (IOException e) {
        }
        frame.repaint();
        frame.setLayout(new FlowLayout());
        frame.add(new JPanel(){
            @Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                g.setColor(Color.WHITE);
                g.fillRect(50,50,450,650);
            }
        }, BorderLayout.CENTER);
        frame.repaint();
        frame.setVisible(true);
    }

}

每次尝试激活背景时,都不显示矩形,每次激活矩形时,都不会显示背景。请帮忙!

2 个答案:

答案 0 :(得分:1)

您正在将JFrame的contentPane设置为JLabel,这是一个不使用布局的容器,因此向其添加组件将不允许显示该组件,除非您完全指定该组件的大小和位置,即其边界。这是我避免将jLabel用于contentPanes的一个原因(也就是说它不会根据它所拥有的组件设置其首选大小),而是通常更喜欢在后台JPanel的paintComponent方法中进行绘制。

侧面建议:

  • 你在主方法上有太多的事情 - 除非这个程序不是用于演示目的以外的任何其他目的
  • 您将JFrame的原始contentPane(JPanel)设置为FlowLayout,但了解一旦更改contentPane后这没有意义。
  • 尽管您假设contentPane使用FlowLayout,但您尝试将绘图JPanel添加到BorderLayout位置,这是没有意义的。
  • 你有一个空的挡块,几乎从来不应该这样做。
  • 将您的图像作为资源而不是文件。
  • 避免使用绝对文件路径,而是更喜欢使用资源的相对路径。
  • 如果可以避免,请不要设置尺寸。
  • 避免使用所谓的“幻数”,例如g.fillRect(50,50,450,650);,因为这会使您的代码难以调试和增强。

例如:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class ShowRectangle extends JPanel {
    private static final int RECT_X = 50;
    private static final int RECT_Y = RECT_X;
    private static final int RECT_W = 200;
    private static final int RECT_H = 200;
    private static final String URL_SPEC = "https://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png";
    private BufferedImage img;

    public ShowRectangle(BufferedImage img) {
        this.img = img;
    }

    // have same JPanel draw image and graphic element
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }

        // avoid magic numbers
        // g.fillRect(50,50,450,650);
        g.fillRect(RECT_X, RECT_Y, RECT_W, RECT_H);
    }

    // Size the JPanel to the image size
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || img == null) {
            return super.getPreferredSize();
        }
        return new Dimension(img.getWidth(), img.getHeight());
    }

    private static void createAndShowGui(BufferedImage image) {
        ShowRectangle mainPanel = new ShowRectangle(image);

        JFrame frame = new JFrame("ShowRectangle");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        try {
            URL imageUrl = new URL(URL_SPEC);
            BufferedImage img = ImageIO.read(imageUrl);
            SwingUtilities.invokeLater(() -> createAndShowGui(img));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

例如,如果你避免使用“魔术”数字,很容易使黑色矩形可拖动,因为它现在可以通过变量值绘制,你可以在MouseAdapter(MouseListener和MouseMotionListener组合)内部更改这些值。例如:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class ShowRectangle extends JPanel {
    private static final int RECT_X = 50;
    private static final int RECT_Y = RECT_X;
    private static final int RECT_W = 200;
    private static final int RECT_H = 200;
    private static final String URL_SPEC = "https://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png";
    private int rectX = RECT_X;
    private int rectY = RECT_Y;
    private BufferedImage img;

    public ShowRectangle(BufferedImage img) {
        this.img = img;
        MouseAdapter myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    // have same JPanel draw image and graphic element
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }

        // avoid magic numbers
        // g.fillRect(50,50,450,650);
        g.fillRect(rectX, rectY, RECT_W, RECT_H);
    }

    // Size the JPanel to the image size
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || img == null) {
            return super.getPreferredSize();
        }
        return new Dimension(img.getWidth(), img.getHeight());
    }

    private class MyMouse extends MouseAdapter {
        private Point p1;
        private Point rectP = null;

        @Override
        public void mousePressed(MouseEvent e) {
            p1 = e.getPoint();
            if (new Rectangle(rectX, rectY, RECT_W, RECT_H).contains(p1)) {
                rectP = new Point(rectX, rectY);
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            moveRect(e.getPoint());
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            moveRect(e.getPoint());
            rectP = null;
        }

        private void moveRect(Point p2) {
            if (rectP == null) {
                return;
            }
            rectX = rectP.x + p2.x - p1.x;
            rectY = rectP.y + p2.y - p1.y;
            repaint();
        }

    }

    private static void createAndShowGui(BufferedImage image) {
        ShowRectangle mainPanel = new ShowRectangle(image);

        JFrame frame = new JFrame("ShowRectangle");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        try {
            URL imageUrl = new URL(URL_SPEC);
            BufferedImage img = ImageIO.read(imageUrl);
            SwingUtilities.invokeLater(() -> createAndShowGui(img));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

答案 1 :(得分:0)

它刚刚离开边界,因此不可见。

替换这两行并检查

 g.setColor(Color.BLACK);
 g.fillRect(0,0,250,250);

试试这个,

@Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                Rectangle clipBounds = g.getClipBounds();
                                System.out.println(clipBounds.getX() +" "+ clipBounds.getY() + " "+ clipBounds.getHeight() + " " + clipBounds.getWidth());

                g.setColor(Color.BLACK);
                g.fillRect(0,0,450,450);
            }

你将获得0.0 0.0 10.0 10.0  作为输出意味着填充reactangle容器从0,0到10,10开始,因此没有显示

将布局更改为GridLayout()将解决您的问题,

frame.setLayout(new GridLayout());
        frame.add(new JPanel(new GridLayout()){
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                Rectangle clipBounds = g.getClipBounds();
                System.out.println(clipBounds.getX() +" "+ clipBounds.getY() + " "+ clipBounds.getHeight() + " " + clipBounds.getWidth());
                g.setColor(Color.BLACK);
                                     g.fillRect(frame.getWidth()/2,0,frame.getWidth(),frame.getWidth());

            }
        }, BorderLayout.CENTER);

根据文件,

void java.awt.Graphics.fillRect(int x,int y,int width,int height)

填充指定的矩形。矩形的左右边缘位于x和x +宽度-1处。顶部和底部边缘位于y和y +高度-1处。生成的矩形覆盖宽度为像素宽的区域宽度和高度像素高。使用图形上下文的当前颜色填充矩形。 参数: x要填充的矩形的x坐标。 y要填充的矩形的y坐标。 width要填充的矩形的宽度。 height要填充的矩形的高度。

这就是问题