自定义组件在Java中的未定义构造函数

huangapple go评论79阅读模式
英文:

Custom Component undefined constructor in Java

问题

我试图用一个名为PhotoComponent的自定义JComponent替换我的Jlabels。到目前为止,我已经按照我的教程视频中所述的所有步骤创建了这个组件。但是,尝试用这两个错误替换所需的Jlabels:

构造函数PhotoComponent()未定义
对于类型new ActionListener(){},方法currentPic(ImageIcon)未定义

这是我的自定义组件的代码:

import javax.swing.ImageIcon;
import javax.swing.JComponent;

public class PhotoComponent extends JComponent {
    private ImageIcon pic;

    public PhotoComponent(){

    }

    public PhotoComponent(ImageIcon p){
        pic=p;
        this.setSize(pic.getIconWidth(),pic.getIconHeight());
    }

    public void paintComponent(Graphics g){
        pic.paintIcon(this, g, 0, 0);
    }
}
英文:

I'm trying to replace my Jlabels with a custom JComponent called PhotoComponent. So far, I've followed all the steps laid out from my instructors video on how to create the component. However, trying to replace the desired Jlabels with these two errors:

    The constructor PhotoComponent() is undefined
    The method currentPic(ImageIcon) is undefined for the type new ActionListener(){}

This is the code for my custom component:

import javax.swing.ImageIcon;
import javax.swing.JComponent;

public class PhotoComponent extends JComponent {
    private ImageIcon pic;

    public PhotoComponent(){

    }

    public PhotoComponent(ImageIcon p){
        pic=p;
        this.setSize(pic.getIconWidth(),pic.getIconHeight());
    }

    public void PaintComponent(Graphics g){
        pic.paintIcon(this, g, 0, 0);
    }
}

答案1

得分: 3

方法 `currentPic` 不存在你已经将 `currentPic` 定义为 `PhotoComponent` 的一个实例因此我假设你想调用它的方法

如果你想要创建一个新的 `PhotoComponent` 实例你应该使用

    currentPic = new PhotoComponent(picList.get(pos))

但是就我个人而言我不会这样做我会在 `PhotoComponent` 中定义一个 `setIcon` 方法这样我就可以简单地更改它显示的图像

```java
public class PhotoComponent extends JComponent {

    private ImageIcon pic;

    public PhotoComponent() {

    }

    public PhotoComponent(ImageIcon p) {
        pic = p;
        this.setSize(pic.getIconWidth(), pic.getIconHeight());
    }

    public void setIcon(ImageIcon icon) {
        pic = icon;
        repaint();
    }

    public void PaintComponent(Graphics g) {
        pic.paintIcon(this, g, 0, 0);
    }
}

然后,你需要将所有类似 currentPic(picList.get(pos)); 的调用更改为 currentPic.setIcon(picList.get(pos));

然而,PhotoComponent 并没有正确地设置,因为它实际上不会绘制任何内容。

首先,应该避免使用 setSize,因为许多组件将会忽略它并使用大小提示,即 preferred/minimum/maximum 大小。

另一个问题是 PaintComponent 定义错误。记住,Java 是大小写敏感的,这意味着如果你想要覆盖一个方法,你需要拼写正确。

你应该将它替换为类似以下的内容...

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    pic.paintIcon(this, g, 0, 0);
}

因此,考虑到上述两点,PhotoComponent 应该更像是...

public class PhotoComponent extends JComponent {

    private ImageIcon pic;

    public PhotoComponent() {

    }

    public PhotoComponent(ImageIcon p) {
        pic = p;
    }

    public void setIcon(ImageIcon icon) {
        pic = icon;
        revalidate();
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        if (pic == null) {
            return new Dimension(0, 0);
        }
        return new Dimension(pic.getIconWidth(), pic.getIconHeight());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        pic.paintIcon(this, g, 0, 0);
    }
}

另外,不要使用 mainPic.add(currentPic);,这不是你应该使用 JScrollPane 的方式... 实际上,你只需要在初始化界面时调用一次 mainPic.setViewportView(currentPic);

我建议你阅读并书签下面的资源:


<details>
<summary>英文:</summary>

The method `currentPic` doesn&#39;t exist, you&#39;ve defined `currentPic` as an instance of `PhotoComponent`, so I&#39;m assuming you want to call a method on it.  

If you want to create a new instance of `PhotoComponent`, then you should be using 
    
    currentPic = new PhotoComponent(picList.get(pos))

But personally, I wouldn&#39;t be doing this, instead I&#39;d have a `setIcon` method defined in `PhotoComponent` so I could simply change the image it displays


    public class PhotoComponent extends JComponent {

        private ImageIcon pic;

        public PhotoComponent() {

        }

        public PhotoComponent(ImageIcon p) {
            pic = p;
            this.setSize(pic.getIconWidth(), pic.getIconHeight());
        }
        
        public void setIcon(ImageIcon icon) {
            pic = icon;
            repaint();
        }

        public void PaintComponent(Graphics g) {
            pic.paintIcon(this, g, 0, 0);
        }
    }

Then, you&#39;d change all the calls like `currentPic(picList.get(pos));` to `currentPic.setIcon(picList.get(pos));`

How ever, `PhotoComponent` is not really set up properly, as it won&#39;t actually paint anything

First, `setSize` should be avoided, as many components will simply ignore it and use the sizing hints, `preferred`/`minimum`/`maximum` size, instead.

Another issues is `PaintComponent` is defined incorrectly.  Remember, Java is case sensitive, this means if you want to override a method, you need to spell it correctly.

You should replace it with something more like...

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        pic.paintIcon(this, g, 0, 0);
    }

So, taking the above to comments into account, `PhotoComponent` should look something more like...


    public class PhotoComponent extends JComponent {

        private ImageIcon pic;

        public PhotoComponent() {

        }

        public PhotoComponent(ImageIcon p) {
            pic = p;
        }

        public void setIcon(ImageIcon icon) {
            pic = icon;
            revalidate()
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            if (pic == null) {
                return new Dimension(0, 0);
            }
            return new Dimension(pic.getIconWidth(), pic.getIconHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            pic.paintIcon(this, g, 0, 0);
        }
    }


Also, done use `mainPic.add(currentPic);`, this isn&#39;t how you should be using a `JScrollPane` ... and in fact, you only need to call `mainPic.setViewportView(currentPic);` once, when you initialise the UI

I would recommend that you read and book mark

* [Creating a GUI With JFC/Swing](https://docs.oracle.com/javase/tutorial/uiswing/index.html)
* [How to Use Scroll Panes](https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html)
* [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html)


</details>



huangapple
  • 本文由 发表于 2020年9月16日 08:57:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63911700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定