Java:在动作侦听器中使用图形组件 [英] Java : using graphics component within an action listener

查看:45
本文介绍了Java:在动作侦听器中使用图形组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Diferent JButtons制作了一个JFrame,我想从另一个类中获取图像.有任何想法吗?还是如何借鉴同一个班级但要采取的行动? 因为它不允许我做任何绘图...我的编译器总是给我错误消息

I've made a JFrame with Diferent JButtons and i'd like to get an image from another class. Any ideas? Or how draw on the same class but on the action performed? Because it doesnt let me to do any drawings...my complier always gives me error messages

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.*;

public class red extends JFrame {

    public JButton b;
    public JButton b1;
    public JButton b2;
    public JButton b3;
    public JButton b4;

    public static Image p;
    public static Graphics g;
    public red() throws IOException {
        gui1 x = new gui1();
        setTitle(" ");
        setSize(1200,700);
        setLayout(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        b= new JButton("click");
        b1= new JButton();
        b.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e0){    
                b1.setBounds(0, 0, 200, 200);
                b.show(false);
                add(x);
            }       
        });
        b.setBounds(0, 0, 100, 100);
        add(b1);
        add(b);

        setVisible(true);
    }

    public static void main(String[] args) throws IOException  {
        red k = new red();
    }
}


import java.awt.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class gui1 extends Canvas {

    public static Image p;

    public void paint(Graphics g){
        g.drawImage(p, 700, 200, 100, 100, this);
    }

    {
        try {
            p= ImageIO.read(new File("Lighthouse.jpg"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

推荐答案

Ph!我在您的代码中看到了很多错误(即使我更正了编译错误):

Phew! I see A LOT of errors in your code (even after I corrected the compilation errors):

  1. 您没有遵循 Java命名约定:

类名应为名词,大小写混合,每个内部单词的首字母应大写

Class names should be nouns, in mixed case with the first letter of each internal word capitalized

red是名词,但应更具描述性且大写. gui1

while red is a noun it should be more descriptive and be capitalized. The same goes for gui1

您要扩展JFrame,用简单的英语说:red JFrame,您应该避免这种情况,并基于JPanel创建GUI改为使用s ...参见使用扩展的Java Swing JFrame vs callint在类内部

You're extending JFrame which in plain english would say: red is a JFrame, you should really avoid this and create your GUI based on JPanels instead... see Java Swing using extends JFrame vs callint it inside of class

您正在设置大小(对于正在使用的JButton大小,这是一个非常大的窗口),而不是使用

You're setting size (a REAAAAAAALLY big one window for the JButton sizes you're using), instead use pack()

您正在使用null-layout,虽然像素完美的GUI似乎是为Swing新手创建复杂GUI的最简单方法,但使用它们越多,与此相关的问题就越多.将来,它们很难维护并导致随机问题,它们无法调整大小等.请阅读为什么不愿在Swing中使用空布局?以获取有关为什么应避免使用它以及为什么应更改GUI以与

You're using null-layout, while pixel-perfect GUIs might seem like the easiest way to create complex GUIs for Swing newbies, the more you use them the more problems related to this you'll find in the future, they are hard to maintain and cause random problems, they don't resize, etc. Please read Null layout is evil and Why is it frowned upon to use a null layout in Swing? for more information about why you should avoid its use and why you should change your GUI to work with Layout Managers along with Empty Borders for extra spacing between components.

您正在使用不推荐使用的方法 JFrame#show() ,您应该使用

You're making use of a deprecated method JFrame#show() you should be using JFrame#setVisible(...) instead.

与第4点相关,您不应调用setBounds(...)方法,而应将计算结果发送给布局管理器.

Related to point #4, you shouldn't be calling setBounds(...) method, but let that calculations to the layout managers.

您没有将程序放在事件上调度线程(EDT),Swing不是线程安全的,您可以通过如下更改main()方法来解决此问题:

You're not placing your program on the Event Dispatch Thread (EDT), Swing is not thread safe, you can fix this by changing your main() method as follows:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            //Your constructor here
        }
    });
}

  • 您正在混合使用AWT和Swing组件,而不是使用AWT的 Canvas 使用Swing的

  • You're mixing AWT and Swing components, instead of using AWT's Canvas use Swing's JPanel which has more functionality and support.

    将图像打包到JAR文件中后,它们将成为嵌入式资源,因此明智的做法是开始将它们视为已经存在,而不是像 embedded-resource 标签.

    Images will become embedded resources once they're packaged in a JAR file, so it's wise to start treating them as if they already were, not as external files as shown in the embedded-resource tag.

    一旦从Canvas更改为JPanel,则应覆盖其关于Swing自定义绘画的教程.

    Once you change from Canvas to JPanel you should override its paintComponent(...) method and not paint(...) and call it's super.paintComponent(g) method as the first line, also don't forget to add the @Overrides annotation. See the tutorial on Swing custom painting.

    您正在滥用static关键字,请参见

    You're abusing the use of static keyword, see how does the static keyword works?

    看到上述所有错误后,我建议您返回并了解基础知识语言,然后再开始使用图形化环境,这只会给您的学习增加更多难度.

    After seeing all the above errors I recommend you to go back and Learn the basics of the language before starting with a graphical environment which will only add more difficulty to your learning.

    据我了解,您希望在单击按钮时绘制图像,如果是这种情况,则可以将图像包装在JLabel中,并将该JLabel添加到JPanel中,然后添加到JPanel中.父JPanel,后来又添加到了JFrame:

    From what I understand you want to draw an image on a button click, if that's the case then you can wrap your image in a JLabel and add that JLabel to a JPanel which then is added to a parent JPanel which is later added to the JFrame:

    如您在上面的GIF中所看到的,用户按下按钮后,该图标就会显示.

    As you can see in the GIF above, the icon is displayed after user presses the button.

    很明显,可以通过组合布局管理器和空白边框来使GUI更具吸引力".

    Obviously this can be improved for the GUI to be more "attractive" with combinations of layout managers and empty borders as stated before.

    这是通过以下代码完成的:

    This was done with the following code:

    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.BoxLayout;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class ImageDrawingFromOneClassToAnother {
    
        private JFrame frame;
    
        private JPanel pane;
        private JPanel leftPane;
        private JPanel rightPane;
    
        private ImageIcon icon;
    
        private JButton button;
    
        private JLabel label;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new ImageDrawingFromOneClassToAnother().createAndShowGui();
                }
            });
        }
    
        public void createAndShowGui() {
            frame = new JFrame(getClass().getSimpleName());
    
            icon = new ImageIcon(this.getClass().getResource("king.png")); //Read images as if they were already embedded resources
    
            button = new JButton("Draw image");
    
            label = new JLabel(""); //Create an empty label
    
            button.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setIcon(icon); //On button click, we set the icon for the empty label
                }
            });
    
            pane = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(300, 200); //Set a size for the main panel
                }
            };
    
            pane.setLayout(new GridLayout(1, 2)); //The main panel
    
            leftPane = new JPanel(); //The button panel
            leftPane.setLayout(new BoxLayout(leftPane, BoxLayout.PAGE_AXIS));
    
            leftPane.add(button);
    
            rightPane = new JPanel(); //The panel where the image will be drawn
            rightPane.add(label);
    
            //We add both (button and image) panels to the main panel
            pane.add(leftPane);
            pane.add(rightPane);
    
            frame.add(pane); //Add the main panel to the frame
            frame.pack(); //Calculate its preferred size
            frame.setVisible(true); //Set it to be visible
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    

    这篇关于Java:在动作侦听器中使用图形组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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