java - JComponent PaintComponent 未出现在面板上

标签 java swing

我正在制作一个简单的 GUI,其中小框应根据其 x,y 坐标出现在 Jpanel 上。所以我在我的结构中我有三个类:
1:MyFrame,其中包含主JFrame
2:MyPanel 扩展了 JPanel
3:图标扩展JComponent

在我的MyFrame中,我想要一个MenuBar,通过它我可以打开一个X,Y坐标文件,并且在菜单栏下方我想要有MyPanel 它将包含每个 X、Y 坐标的所有图标。我遇到的第一个问题是,当我添加图标时,Icon 没有出现在 MyPanel 上。

我的代码如下:

public class MyFrame {
    private JFrame frame;
    private MyPanel panel;

    public MyFrame(){
        panel = new MyPanel();
    }

    /*
    *HERE GOES THE `FILE OPEN` LISTENER
    * it creates `Coordinate` for each line 
    * passes the coordinate to panel.makeIcons()
    */

    public void createGui(){
      frame = new JFrame("Graph Editor");
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      frame.setResizable(true);

      //create, get and set the Jframe menu bar
      //createMenuBar() returns a JMenuBar
      frame.setJMenuBar(createMenuBar());

      Container frame_pane = frame.getContentPane();

      panel.setBounds(0, 0, frame.getWidth(), frame.getHeight());
      frame_pane.add(panel);

      frame.pack();
      frame.setVisible(true);
    }

    public static void main(String args[]){  
        MyFrame window = new MyFrame();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {     
            public void run() {
                window.createGui();
            }
        });
    }
} 

用于保存图标的面板的代码:

public class MyPanel extends JPanel{
    private Set<Icon> points;

    public MyPanel(){
      setLayout(null);
      setPreferredSize(new Dimension(600, 600));
      setBackground(Color.YELLOW);
    }

    //gets called by `FILE OPEN` listener for each coordinate

    public void makeIcons(Coordinate obj){
        Icon temp = new Icon(obj);
        points.add(temp);

        //add the temp JComponent to this JPanel
        this.add(temp);
    }
}

需要在上面面板上显示的图标代码:

public Icon extends JComponent{
    private Coordinate location;
    public Icon(Coordinate obj){
        location = obj;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED);
        g.fillRect(location.getX(), location.getY(), 20, 20);
        g.setColor(Color.BLACK);
        g.drawRect(location.getX(), location.getY(), 20, 20);
    }
}

第一个问题:使用上述代码,图标不会显示在面板中。

第二个问题:当我将MyPanel.class 中的makeIcon 方法更改为以下内容时。它通过 MenuBar 显示图标,当 MenuBar 出现在任何图标上时将其删除:

public void makeIcons(Coordinate obj){
    Icon temp = new Icon(obj);
    points.add(temp);

    //add the temp JComponent to this JPanel
    this.add(temp);
    temp.paintComponent(this.getGraphics());
    revalidate();
}

感谢任何帮助。谢谢

最佳答案

永远不要自己调用paintComponent(或任何paint)方法。绘画不是这样的。

组件不会被绘制的核心原因是:

  1. 它的大小是0x0
  2. 它是看不见的
  3. 它不会添加到(间接)添加到 native 对等点的容器中。

根据我的简短观察,我想说您遇到了第一点,部分原因是使用了空布局

此外,请记住,在绘制组件时,组件的Graphics上下文已经被转换,因此0x0是组件的左上角/左上角。这意味着,根据您的代码,您很可能会以任何方式超出组件的可见边界进行绘制。

所以,你基本上有两个选择。实现您自己的布局管理器,它使用坐标信息将Icon放置在容器中(然后需要重写getPreferredSize)为了提供尺寸提示)或者,自己绘制

可能看起来像这样......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Graph Editor");
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setResizable(true);
                frame.add(new MyPanel());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public class Coordinate {

        private int x;
        private int y;

        public Coordinate(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

    }

    public class Icon {

        private Coordinate coordinate;

        public Icon(Coordinate coordinate) {
            this.coordinate = coordinate;
        }

        public Coordinate getCoordinate() {
            return coordinate;
        }

        public void paint(Graphics2D g2d) {
            g2d.setColor(Color.RED);
            g2d.fillRect(0, 0, 20, 20);
            g2d.setColor(Color.BLACK);
            g2d.drawRect(0, 0, 20, 20);
        }
    }

    public class MyPanel extends JPanel {

        private Set<Icon> points;

        public MyPanel() {
            points = new HashSet<>();
            setLayout(null);
            setPreferredSize(new Dimension(600, 600));
            setBackground(Color.YELLOW);
        }

        //gets called by `FILE OPEN` listener for each coordinate
        public void makeIcons(Coordinate obj) {
            points.add(new Icon(obj));
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            for (Icon icon : points) {
                Graphics2D g2d = (Graphics2D) g.create();
                Coordinate coordinate = icon.getCoordinate();
                // I'd have a size component associated with the Icon
                // which I'd then use to offset the context by half its
                // value, so the icon is paint around the center of the point
                g2d.translate(coordinate.getX() - 10, coordinate.getY() - 10);
                icon.paint(g2d);
                g2d.dispose();
            }
        }

    }
}

我没有播种任何值(value)观,我很懒,但这是基本想法

关于java - JComponent PaintComponent 未出现在面板上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47047761/

相关文章:

java - Android 中通过 TCP 进行实时音频流传输

java - 线程在鼠标下的任何组件上写入状态更新文本

java - 按钮上的 getSource 方法出现问题

java - "Build Automatically"Swing 函数

java - 防止 GridBagLayout 调整列大小

java - 无法在 Android 中显示谷歌地图

java - 使用 Scala 或 Java 进行 Base 64 编码

Java/jetty : How to Add Filter to Embedded Jetty

java - 如何同时滚动多个对象?

java - 图表上的 setFont 问题 (JFreeChart)