简体   繁体   English

如何将一个JPanel的特定坐标绘制到另一个JPanel上

[英]How to paint specific coordinates of one JPanel onto another JPanel

This is my problem : 这是我的问题:

I have one JPanel and i paint in this panel one rectangle ex. 我有一个JPanel,我在这个面板上画了一个矩形ex。 100x100. 100×100。

In another JPanel I wouldlike show/paint fragments on first JPanel ex. 在另一个JPanel中,我想在第一个JPanel ex上显示/绘制片段。 50x50, but if I change first JPanel, another JPanel change too (dont copy graphics or Panel) What I can do this? 50x50,但如果我改变第一个JPanel,另一个JPanel也改变了(不要复制图形或面板)我能做什么呢?

在此输入图像描述在此输入图像描述

First Panel Second Panel 第一小组第二小组


Public class Okienko extends JFrame { 
Panel p = new Panel();
public Okienko(){

//setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(p);
pack();
setVisible(true);

}

private class Panel extends JPanel{

    public Panel(){
    setPreferredSize(new Dimension(300,400));
    setBackground(Color.red);
    setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
         Graphics2D g2 = (Graphics2D) g;
         super.paint(g2);
         g2.setColor(Color.blue);
         g2.fill(new Rectangle2D.Float(100,100,100,100));
         g2.setColor(Color.green);
         g2.fill(new Rectangle2D.Float(50,50,50,50));
    }

}
private class Panel2 extends Panel{


    @Override
    public void paint(Graphics g) {

      //I would like to show/paint only fragment painted Panel, ex. 50x50 (only show one rectangle)

    }



}

 public static void main(String[] args) {

   Okienko o =  new Okienko();


 }
}

So this is what you need to do. 所以这就是你需要做的。

  1. You need to save the first JPanel 's Graphics context to a BufferedImage . 您需要将第一个JPanelGraphics上下文保存到BufferedImage Here is a helper method, I used in the example program below 这是一个帮助方法,我在下面的示例程序中使用

     BufferedImage bi; .... private void setImage(JPanel panel) { Dimension d = panel.getPreferredSize(); int w = (int)d.getWidth(); int h =(int)d.getHeight(); bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); panel.paint(g); g.dispose(); } 

    This saves the entire JPanel to a BufferedImage . 这会将整个JPanel保存为BufferedImage

  2. Use that BufferedImage to paint on the second JPanel . 使用该BufferedImage在第二个JPanel上绘制。 Use whatever coordinates you want. 使用您想要的任何坐标。 Use this method from Graphics class 使用Graphics类中的此方法

     public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) 

    img - the specified image to be drawn. img - 要绘制的指定图像。 This method does nothing if img is null. 如果img为null,则此方法不执行任何操作。
    dx1 - the x coordinate of the first corner of the destination rectangle. dx1 - 目标矩形的第一个角的x坐标。
    dy1 - the y coordinate of the first corner of the destination rectangle. dy1 - 目标矩形的第一个角的y坐标。
    dx2 - the x coordinate of the second corner of the destination rectangle. dx2 - 目标矩形的第二个角的x坐标。
    dy2 - the y coordinate of the second corner of the destination rectangle. dy2 - 目标矩形的第二个角的y坐标。
    sx1 - the x coordinate of the first corner of the source rectangle. sx1 - 源矩形第一个角的x坐标。
    sy1 - the y coordinate of the first corner of the source rectangle. sy1 - 源矩形的第一个角的y坐标。
    sx2 - the x coordinate of the second corner of the source rectangle. sx2 - 源矩形第二个角的x坐标。
    sy2 - the y coordinate of the second corner of the source rectangle. sy2 - 源矩形第二个角的y坐标。
    observer - object to be notified as more of the image is scaled and converted. observer - 在缩放和转换更多图像时要通知的对象。

     g.drawImage(bi, 0, 0, 200, 200, 0, 0, 50, 50, this); 

Here's the result 这是结果

在此输入图像描述

Here's the full code 这是完整的代码

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;

public class TestTwoPanels {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {

                JPanel panel = new JPanel();
                PanelTwo panelTwo = new PanelTwo();
                PanelOne panelOne = new PanelOne(panelTwo);

                JSplitPane split = new JSplitPane(
                        JSplitPane.HORIZONTAL_SPLIT, panelOne, panelTwo);
                panel.add(split);


                JFrame frame = new JFrame("Test Graphics");
                frame.add(panel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class PanelOne extends JPanel {

        Dimension size;
        BufferedImage image;
        PanelTwo panelTwo;

        public PanelOne(PanelTwo panelTwo) {
            this.panelTwo = panelTwo;
            try {
                URL url = new URL("http://swoo.co.uk/content/images/icons/stackoverflow.png");
                image = ImageIO.read(url);
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            panelTwo.setImage(PanelOne.this);
            panelTwo.repaint();

        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.drawImage(image, 0, 0, this);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 250);
        }
    }

    private static class PanelTwo extends JPanel {

        BufferedImage bi;

        public PanelTwo() {
            setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        }

        public void setImage(BufferedImage image) {
            this.bi = image;
        }

        private void setImage(JPanel panel) {
            Dimension d = panel.getPreferredSize();
            int w = (int)d.getWidth();
            int h =(int)d.getHeight();
            System.out.println(d);
            bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bi.createGraphics();
            panel.paint(g);
            g.dispose();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(bi, 25, 25, 225, 225, 50, 50, 175, 175, this);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 250);
        }
    }
}
private void setImage(JPanel panel) {
            Dimension d = panel.getPreferredSize();
            int w = (int)d.getWidth();
            int h =(int)d.getHeight();
            System.out.println(d);
            bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

This code is clearify for me. 这段代码对我来说很清楚。

Graphics2D g = bi.createGraphics();

You create blank BufferedImage and init to Graphics2D? 你创建空白的BufferedImage和init到Graphics2D?

panel.paint(g);

You paint graphics context on panel and copy to bi? 你在面板上绘制图形上下文并复制到bi?

        g.dispose();

You release g. 你释放g。

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM