Java:在动作监听器中使用图形组件

2022-01-24 00:00:00 java swing jbutton jframe

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

import java.awt.*;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 java.io.IOException;导入 javax.swing.*;公共类红色扩展 JFrame {公共 JButton b;公共 JButton b1;公共 JButton b2;公共 JButton b3;公共 JButton b4;公共静态图像 p;公共静态图形 g;公共红色()抛出 IOException {gui1 x = 新的 gui1();设置标题(");设置大小(1200,700);设置布局(空);设置默认关闭操作(EXIT_ON_CLOSE);b=新的JButton(点击");b1=新的 JButton();b.addActionListener(新的ActionListener(){@覆盖公共无效actionPerformed(ActionEvent e0){b1.setBounds(0, 0, 200, 200);b.显示(假);添加(x);}});b.setBounds(0, 0, 100, 100);添加(b1);添加(b);设置可见(真);}公共静态 void main(String[] args) 抛出 IOException {红色 k = 新红色();}}

<小时>

import java.awt.*;导入java.io.File;导入 java.io.IOException;导入 javax.imageio.ImageIO;导入 javax.swing.*;公共类 gui1 扩展 Canvas {公共静态图像 p;公共无效油漆(图形g){g.drawImage(p, 700, 200, 100, 100, 这个);}{尝试 {p= ImageIO.read(new File("Lighthouse.jpg"));} 捕捉(IOException e){//TODO 自动生成的 catch 块e.printStackTrace();}}}

解决方案

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

  1. 您没有遵循

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

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

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

    import java.awt.Dimension;导入 java.awt.GridLayout;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 javax.swing.BoxLayout;导入 javax.swing.ImageIcon;导入 javax.swing.JButton;导入 javax.swing.JFrame;导入 javax.swing.JLabel;导入 javax.swing.JPanel;导入 javax.swing.SwingUtilities;公共类 ImageDrawingFromOneClassToAnother {私有 JFrame 框架;私有 JPanel 窗格;私人JPanel leftPane;私人JPanel rightPane;私有 ImageIcon 图标;私有 JButton 按钮;私人 JLabel 标签;公共静态无效主要(字符串[]参数){SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){新 ImageDrawingFromOneClassToAnother().createAndShowGui();}});}公共无效createAndShowGui(){框架 = 新 JFrame(getClass().getSimpleName());icon = new ImageIcon(this.getClass().getResource("king.png"));//读取图像,就好像它们已经是嵌入的资源一样button = new JButton("画图");标签 = 新的 JLabel("");//创建一个空标签button.addActionListener(new ActionListener() {@覆盖公共无效actionPerformed(ActionEvent e){标签.setIcon(图标);//单击按钮时,我们为空标签设置图标}});窗格 = 新 JPanel() {@覆盖公共维度 getPreferredSize() {返回新维度(300、200);//设置主面板的大小}};pane.setLayout(new GridLayout(1, 2));//主面板leftPane = new JPanel();//按钮面板leftPane.setLayout(new BoxLayout(leftPane, BoxLayout.PAGE_AXIS));leftPane.add(按钮);rightPane = new JPanel();//将要绘制图像的面板rightPane.add(标签);//我们将(按钮和图像)面板都添加到主面板窗格.add(leftPane);窗格.add(rightPane);框架.添加(窗格);//将主面板添加到框架中框架.pack();//计算它的首选大小frame.setVisible(true);//设置为可见frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}

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

    解决方案

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

    1. You're not following the Java naming conventions:

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

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

    2. 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

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

    4. 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.

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

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

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

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

    9. 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.

    10. 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.

    11. 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.


    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:

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

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

相关文章