【问题标题】:how to handle multiple actions by JButtons如何通过 JButtons 处理多个动作
【发布时间】:2015-10-14 14:15:18
【问题描述】:

最近我决定在 Java 中使用 JFrames、JPanels 等。正如主题所说,我不知道如何为不同的按钮设置不同的操作。为了练习,我想写一个小程序,按不同的按钮绘制不同的形状。但是,不幸的是它不起作用 - 按下按钮后,不执行绘制形状。有没有更有效的方法来做到这一点?有人能指出错误在哪里吗?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GUI {

    public JFrame frame;
    public JPanel panel;
    public JButton button1, button2;
    public final static String COMMAND_FOR_BUTTON_1 = "COMMAND_FOR_BUTTON_1";
    public final static String COMMAND_FOR_BUTTON_2 = "COMMAND_FOR_BUTTON_2";
    public int whatToDraw = 0;
    public paintComponent pc;

    public void initFrame() {
        frame = new JFrame();
        frame.setTitle("Let's paint something");
        frame.setSize(300, 400);        
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void initPanel() {
        panel = new JPanel();
    }

    public void initButtons() {
        button1 = new JButton("Square");
        button1.setActionCommand(COMMAND_FOR_BUTTON_1);
        button2 = new JButton("Circle");
        button2.setActionCommand(COMMAND_FOR_BUTTON_2);

        button1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {    
                if(e.getActionCommand().equals(COMMAND_FOR_BUTTON_1)) {
                    whatToDraw = 1;
                    pc.repaint();
                }
            }
        });

        button2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals(COMMAND_FOR_BUTTON_2)) {
                    whatToDraw = 2;
                    pc.repaint();
                }
            }
        });
    }

    @SuppressWarnings("serial")
    class paintComponent extends JComponent{
        public void paint(Graphics g){
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            Random rand = new Random();
            int radius = rand.nextInt(80)+40;

            if(whatToDraw == 1) {
                g2.setColor(Color.BLUE);
                g2.fillOval(rand.nextInt(getWidth()-radius), rand.nextInt(getHeight())-radius, radius, radius);
            } 
            if(whatToDraw == 2) {
                g2.setColor(Color.GREEN);
                g2.fillRect(rand.nextInt(getWidth()-radius), rand.nextInt(getHeight())-radius, radius, radius);
            }
        }
    }

    public void createGUI() {
        initFrame();
        initPanel();
        initButtons();
        pc = new paintComponent();
        panel.add(button1);
        panel.add(button2);
        frame.add(pc, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.PAGE_START);
    }

    public static void main(String[] args) {
        GUI gui = new GUI();
        gui.createGUI();
    }
}

【问题讨论】:

  • “它不起作用”是什么意思?你有什么例外吗?
  • 更正,“...点击按钮后,不执行绘制形状...”
  • 在您的按钮中调用重绘。你的意思是叫油漆。另外,不要使用您的绘画方法来启动按钮。为什么不在构造函数中这样做呢?
  • 1.为什么在初始化和绘画期间调用“initButtons”方法? 2. 确保 ActionListeners 中的重绘调用针对您的paintComponent 实例。
  • 更重要的是,不要在你的paint方法中调用repaint。据我所知,repaint 是对 paint 方法的调用。

标签: java jframe jpanel paintcomponent


【解决方案1】:
 public void paint(Graphics g){
        initButtons(); <------------------- delete
        Graphics2D g2 = (Graphics2D) g;
        if(whatToDraw == 1) {
            g2.setColor(Color.BLUE);
            g2.fillOval(30, 30, 30, 30);
            repaint(); <------------------- delete
        } 
        if(whatToDraw == 2) {
            g2.setColor(Color.GREEN);
            g2.fillRect(30, 30, 30, 30);
            repaint(); <------------------- delete
        }
    }

    @Override
        public void actionPerformed(ActionEvent e) {    
            if(e.getActionCommand().equals(COMMAND_FOR_BUTTON_1)) {//FredK suggested in comments you remove this line.
                whatToDraw = 1;
                pc.repaint()
            }
        }
    });

    button2.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            whatToDraw = 2;//removed it would like like this, and do the same. Your solution would be neccessary if 2 buttons shared the same actionListener.
            pc.repaint();
        }
    });

编辑

public void createGUI() {
    initFrame();
    initPanel(); //put your initButtons() method here
    pc = new paintComponent();
    panel.add(button1); //these could go in initPanel() too
    panel.add(button2); //^
    frame.add(pc, BorderLayout.CENTER);//your JFrame has a default layout of BorderLayout.
    frame.add(panel, BorderLayout.PAGE_START);
}

【讨论】:

  • 我已更改代码。不幸的是,问题仍然存在。
  • 确实,但我们在正确的方向上走了很远。现在唯一的问题是将您的绘图组件正确添加到您的 JFrame。
  • 目前,您的paintComponent 没有尺寸。使用布局将解决此问题。让我们给你的 JFrame 一个borderLayout,然后将你的paintComponent 添加到中心。
  • 在您的 actionPerformed 方法中,无需检查 actionCommand,因为您为每个按钮创建了一个新的 ActionListener。就此而言,也无需为任何按钮调用 setActionCommand。
  • user2651804 问题已修复。非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 2019-08-25
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多