java - 无法使用 getGraphics() 方法一次性加载图像

标签 java image swing

嗨,我是 java GUI 编程新手。我创建了 Jframe(MainFrame) 并添加了 JPanel(OutPanel),其中还有另一个 Jpanel(InnerPanel)。我尝试在 InnerPanel 中绘制 Image,而不是绘制 OutPanel。我希望 OutPanel 曾经只是 Container。正如你所看到的 TestA。我从 OutPanelpaintComponent() 中的 InnerPanel 获取 Graphics,这是重写的方法。

最后我可以在 OutPanelpaintComponent() 方法中使用 InnerPanelGraphics 进行绘制。但它不能很好地工作。程序启动时无法一次性绘制图像。当我隐藏窗口并再次显示时,程序显示图像。尽管那是图像的一部分,但不是全部图像。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class TestA{

    private static Image image = GUI.loadImage("PlayerBoard.jpg");


    public static void main(String[] args) {
        TestA testA = new TestA();
    }


    public TestA() {

        JFrame mainFrame = new JFrame("Main Frame");
        mainFrame.setLayout(null);
        mainFrame.setSize(500, 500);
        mainFrame.setVisible(true);
        mainFrame.setBackground(Color.black);
        mainFrame.setLocation(800, 400);

        OutPanel outPanel = new OutPanel();

        mainFrame.getContentPane().add(outPanel);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        outPanel.repaint();
    }

    private class OutPanel extends JPanel {

        JPanel innerPanel;

        public OutPanel() {

            this.setLayout(null);
            this.setLocation(0, 0);
            this.setSize(500, 50);
            this.setBackground(Color.red);

            innerPanel = new JPanel();
            this.innerPanel.setSize(400, 50);
            this.innerPanel.setVisible(true);
            this.add(innerPanel);

        }

        @Override
        protected void paintComponent(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponent(g);

            int width = 500;
            int height = 50;

            BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
            Graphics gBuffer = resized.createGraphics();
            gBuffer.drawImage(TestA.image, 0, 0, width, height, this);

            Graphics gPanel = innerPanel.getGraphics();
            gPanel.drawImage(resized, 0, 0, width, height, this);
        }
    }
}

所以我尝试不同的方式(TestB)。唯一不同的是我刚刚将 drawImage() 方法和 getGraphics() 内容移动到 InnerPanelpaintComponent() 来自 OutPanelpaintComponent()。这是另一个代码 TestB。而且效果很好。

为什么会发生这种情况。它与上下文有关吗?什么是上下文。我可以在 OutPanel 中绘制 InnerPanel 的 图像吗?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestB {

    private static Image image = GUI.loadImage("PlayerBoard.jpg");

    public static void main(String[] args) {
        TestB testB = new TestB();
    }

    public TestB() {

        JFrame mainFrame = new JFrame("Main Frame");
        mainFrame.setLayout(null);
        mainFrame.setSize(500, 500);
        mainFrame.setVisible(true);
        mainFrame.setBackground(Color.black);
        mainFrame.setLocation(800, 400);

        OutPanel outPanel = new OutPanel();

        mainFrame.add(outPanel);

        outPanel.repaint();

    }

    private class OutPanel extends JPanel {

        JPanel innerPanel;

        public OutPanel() {

            this.setLayout(null);
            this.setLocation(0, 0);
            this.setSize(500, 50);
            this.setBackground(Color.red);

            innerPanel = new InnerPanel(this);
            this.innerPanel.setSize(500, 50);
            this.innerPanel.setVisible(true);
            this.add(innerPanel);

            this.repaint();
        }
    }

    private class InnerPanel extends JPanel {

        OutPanel outPanel;

        public InnerPanel(OutPanel outPanel) {
            this.outPanel = outPanel;
        }

        @Override
        protected void paintComponent(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponent(g);

            int width = 500;
            int height = 50;

            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.drawImage(TestB.image, 0, 0, width, height, this);
        }
    }
}

最佳答案

组件的paintComponent()方法只负责绘制自身。它永远不应该知道或关心任何其他组件。

I want OutPanel used to be just Container.

那就这么做吧。创建面板并设置外部面板的布局管理器,然后将外部面板添加到 JFrame。

然后创建内部面板并将其添加到外部面板。确保重写内部面板的 getPreferredSize() 方法,以便外部面板的布局管理器可以完成其工作。

阅读 Swing 教程中关于 Custom Painting 的部分了解更多信息和工作示例。

关于java - 无法使用 getGraphics() 方法一次性加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39606668/

相关文章:

java - 屏幕尺寸问题

java - 如何检查参数值是否在常量列表中

jQuery UI 对话框向图像添加不需要的内联样式

python - 图像在 Pygame 中旋转,同时保持平滑的边缘

java - 如何告诉用户从程序安装 Java 8?

java - 将 DefaultTableCellRenderer 中的 boolean 值的复选框替换为字符串

java - 使用 OpenCV SURF 对多个图像进行图像匹配

image - 使用 css 或 canvas 制作表格

java - JPanel 出现在 Netbeans Debug模式中,但不在运行模式中

java - JOptionPane 类型中的方法 showMessageDialog(Component, Object) 不适用于参数 (new ActionListener(){}, String)