【问题标题】:How to paint specific coordinates of one JPanel onto another JPanel如何将一个 JPanel 的特定坐标绘制到另一个 JPanel 上
【发布时间】:2014-01-26 10:28:15
【问题描述】:

这是我的问题:

我有一个 JPanel,我在这个面板上画了一个矩形 ex。 100x100。

在另一个 JPanel 中,我想在第一个 JPanel ex 上显示/绘制片段。 50x50,但如果我更改第一个 JPanel,另一个 JPanel 也会更改(不要复制图形或面板) 我能做什么?

            第一组                       第二组


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


 }
}

【问题讨论】:

  • 请出示您的代码。也尝试创建一个a Minimal, Complete, Tested and Readable example
  • 我现在不能添加最小的示例代码(等到 8 小时)。
  • 您能否更清楚地解释一下您期望发生的事情,因为这对我来说仍然没有意义。
  • 我想在 panel2 的部分 panel1 上显示。 Panel1 包含(绘制的)AAABBBCCC。在 Panel2 中仅绘制或显示 CCC。我不知道我知道什么。对不起我的英语
  • 你可以展示一张图片吗?也许使用像Photoshop这样的绘画程序来展示你想要发生的事情。然后贴出我们可以看到的图片的链接

标签: java swing graphics jpanel paint


【解决方案1】:

所以这就是你需要做的。

  1. 您需要将第一个JPanelGraphics 上下文保存到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 类中使用此方法

    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 - 要绘制的指定图像。如果 img 为 null,则此方法不执行任何操作。
    dx1 - 目标矩形的第一个角的 x 坐标。
    dy1 - 的 y 坐标目标矩形的第一个角。
    dx2 - 目标矩形第二个角的 x 坐标。
    dy2 - 第二个角的 y 坐标
    sx1 - 源矩形第一个角的 x 坐标。
    sy1 - 源矩形第一个角的 y 坐标源矩形。
    sx2 - 源矩形第二个角的 x 坐标。
    sy2 - 源矩形第二个角的 y 坐标.
    observer - 当更多的图像被缩放和转换时要通知的对象。

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

这是结果

这是完整的代码

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

【讨论】:

  • 是的,这就是我需要的。您获取图形上下文 Panel1 并使用特定坐标放置到 Panel2,如果可以,我还有其他问题。
  • 问题是什么?
【解决方案2】:
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();

您创建空白 BufferedImage 并初始化到 Graphics2D?

panel.paint(g);

您在面板上绘制图形上下文并复制到 bi?

        g.dispose();

你释放 g。

    }

【讨论】:

  • 是的,你似乎明白了。
  • 非常感谢您的宝贵时间。这不仅仅是为了我,因为通常左侧是声明,左侧是参考。在此代码中,您更改语句 (Graphics2D g) 和语句更改参考旁边。我必须在这个线索上考虑更多时间。
  • 好的,这一切都澄清了。 bi.createGraphics() 返回图形,所以我们现在在 bi 上绘制。谢谢!
  • g 引用了bi 的图形。请记住,当您分配引用时,这两个对象指向同一个引用对象。所以gbi.createGraphics 是同一个对象,因为createGraphics() 返回一个Graphics 对象。因此,当您绘制g 时,您也在绘制bi 的图形。你明白了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
相关资源
最近更新 更多