Java : using graphics component within an action listener

标签 java swing jframe jbutton

我用不同的 JButtons 制作了一个 JFrame,我想从另一个类获取图像。有任何想法吗?或者如何利用同一个类但执行的操作? 因为它不允许我做任何绘图...我的编译器总是给我错误消息

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

最佳答案

唷!我在您的代码中看到大量错误(即使在我更正了编译错误之后):

  1. 您没有遵循Java naming conventions :

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

    虽然red是一个名词,但它应该更具描述性并且大写。对于 gui1

  2. 也是如此
  3. 您正在扩展 JFrame,用简单的英语来说:red 是一个 JFrame ,您确实应该避免这种情况并基于 JPanel 创建 GUI...请参阅 Java Swing using extends JFrame vs callint it inside of class

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

  5. 您正在使用 null-layout,虽然像素完美的 GUI 似乎是为 Swing 新手创建复杂 GUI 的最简单方法,但您使用它们的次数越多,与以下相关的问题就越多您将来会发现,它们很难维护并导致随机问题,它们不会调整大小等。请阅读 Null layout is evilWhy is it frowned upon to use a null layout in Swing?有关为什么应避免使用它以及为什么应更改 GUI 以使用 Layout Managers 的更多信息以及Empty Borders用于组件之间的额外间距。

  6. 您正在使用已弃用的方法 JFrame#show()你应该使用 JFrame#setVisible(...)相反。

  7. 与第 4 点相关,您不应该调用 setBounds(...) 方法,而应让布局管理器进行计算。

  8. 您没有将程序放在 Event Dispatch Thread (EDT) 上,Swing 不是线程安全的,您可以通过更改 main() 方法来解决此问题,如下所示:

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Your constructor here
            }
        });
    }
    
  9. 您正在混合 AWT 和 Swing 组件,而不是使用 AWT 的 Canvas使用 Swing 的 JPanel它具有更多功能和支持。

  10. 图像一旦打包到 JAR 文件中,就会成为嵌入式资源,因此明智的做法是开始将它们视为已经存在的资源,而不是像 embedded-resource 中所示的外部文件。 标签。

  11. Canvas 更改为 JPanel 后,您应该覆盖其 paintComponent(...)方法而不是 paint(...)并在第一行调用它的 super.paintComponent(g) 方法,也不要忘记添加 @Overrides 注释。请参阅tutorial on Swing custom painting .

  12. 您滥用了 static 关键字,请参阅 how does the static keyword works?

看到上述所有错误后,我建议您返回并 Learn the basics在开始图形环境之前先了解该语言,这只会增加您的学习难度。

<小时/>

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

enter image description here

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

显然,如前所述,可以通过布局管理器和空边框的组合来改进 GUI,使其更具“吸引力”。

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

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 : using graphics component within an action listener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42170094/

相关文章:

java - 如何对齐 JPanel 中的 3 个 JLabel 的底部

java - 如何让WebView检测到服务器连接失败

java - 如何对值进行分组和连接?

java - 从 url 创建图像并保存在数据存储中

java - 在 Android 中使用 SDK 3.15 登录 Facebook 时获取用户名

java - JPanels 无法设置任何大小值

java - 在 borderlayout 中使用 JPanel 错误打包 JFrame

java - Jconsole 实时线程计数和 java ExecutorService

java - 在 Swing 中选择等宽字体的正确方法

java - 如何让我的程序在 Java 窗口中运行?