如何将一个JPanel的特定坐标绘制到另一个JPanel上 [英] How to paint specific coordinates of one JPanel onto another JPanel

查看:138
本文介绍了如何将一个JPanel的特定坐标绘制到另一个JPanel上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题:

我有一个JPanel,我在这个面板上绘制了一个矩形前例。在另一个JPanel中,我喜欢在第一个JPanel前面显示/绘制片段。 50x50,但是如果我改变了第一个JPanel,另一个JPanel也改变了(不要复制图形或面板)
我能做到这一点吗?




             First Panel                  第二个面板




 公共类Okienko扩展了JFrame {
Panel p = new Panel ();
public Okienko(){

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


$ b private class Panel 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(新的Rectangle2D.Float(100,100,100,100));
g2.setColor(Color.green);
g2.fill(new Rectangle2D.Float(50,50,50,50));


$ b private class Panel2 extends Panel {

$ b $ @Override
public void paint(Graphics g){

//我想只显示/绘制仅绘制的片段Panel,ex。 50x50(仅显示一个矩形)

}



}

公共静态void main(String [] args ){

Okienko o =新Okienko();



$ b


解决方案

所以这就是你需要做的。


  1. 您需要保存第一个 JPanel 图形上下文到 BufferedImage 。这是一个帮助程序方法,我在下面的示例程序中使用了

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

    这节省了整个 JPanel BufferedImage


  2. 使用 BufferedImage 绘制第二个 JPanel 。使用任何你想要的坐标。使用此方法从 Graphics class

      public abstract boolean drawImage(Image img ,
    int dx1,
    int dy1,
    int dx2,
    int dy2,
    int sx1,
    int sy1,
    int sx2, b

    img > - 要绘制的指定图像。如果img为null,则此方法不执行任何操作。

    dx1 - 目标矩形第一个角的x坐标。

    dy1 strong> - 目标矩形第一个角的y坐标。

    dx2 - 目标矩形第二个角的x坐标。
    dy2 - 目标矩形第二个角的y坐标。

    sx1 - 源矩形第一个角的x坐标。
    sy1 - 源矩形第一个角的y坐标。

    sx2 - 第二个角的x坐标的源矩形。

    sy2 - 源矩形第二个角的y坐标。

    观察者 - 对象以获得更多的图像缩放和转换通知。

      g.drawImage(bi,0,0, 200,200,0,0,50,50,t他的); 


以下是结果





下面是完整的代码

  import java.awt.Dimension; 
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
导入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;
导入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图片;
面板二面板二;

public PanelOne(PanelTwo panelTwo){
this.panelTwo = panelTwo;
尝试{
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();


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


$ b @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);
}
}
}


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?

            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. 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

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

这篇关于如何将一个JPanel的特定坐标绘制到另一个JPanel上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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