Question

This is my problem :

I have one JPanel and i paint in this panel one rectangle ex. 100x100.

In another JPanel I wouldlike show/paint fragments on first JPanel ex. 50x50, but if I change first JPanel, another JPanel change too (dont copy graphics or Panel) What I can do this?

enter image description here enter image description here

            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();


 }
}
Was it helpful?

Solution

So this is what you need to do.

  1. You need to save the first JPanel's Graphics context to a 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.

  2. Use that BufferedImage to paint on the second JPanel. Use whatever coordinates you want. Use this method from Graphics class

    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. This method does nothing if img is null.
    dx1 - the x coordinate of the first corner of the destination rectangle.
    dy1 - the y coordinate of the first corner of the destination rectangle.
    dx2 - the x coordinate of the second corner of the destination rectangle.
    dy2 - the y coordinate of the second corner of the destination rectangle.
    sx1 - the x coordinate of the first corner of the source rectangle.
    sy1 - the y coordinate of the first corner of the source rectangle.
    sx2 - the x coordinate of the second corner of the source rectangle.
    sy2 - the y coordinate of the second corner of the source rectangle.
    observer - object to be notified as more of the image is scaled and converted.

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

Here's the result

enter image description here

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);
        }
    }
}

OTHER TIPS

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?

panel.paint(g);

You paint graphics context on panel and copy to bi?

        g.dispose();

You release g.

    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top