java - 如何使用 GUI 在 Canvas 上绘制简单图形

标签 java user-interface canvas graphics drawing

我正在编写一个程序,该程序将显示烟花爆炸的图形表示(而不是动画)。我的很多程序都致力于为用户提供启动时的选项(例如颜色、爆炸类型、轨迹等)。我花了很多时间调整我的 GUI 面板以使其达到我想要的方式,现在我已经将注意力转移到在 Canvas 上绘制爆炸,我无法在面板中绘制任何内容。我以前做过很多java图形程序,并且过去能够轻松解决这个问题。我在这个项目上就没有那么幸运了,并且变得很沮丧。有人看出我的问题是什么吗?

(我遇到的另一个问题是我的 JSliders,但这对我来说不是一个重要的问题)

感谢您的帮助!

代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;



@SuppressWarnings("serial")
public class Fireworks extends JPanel implements ActionListener, ChangeListener, ItemListener {
    protected int speed, angle, launch = 1;
JFrame frame;
JPanel guistuff, display;
//Each button (except 'button') corresponds to a color for the fireworks. 
//e.g. rbutton = red, obutton = orange, etc.
JButton button, rbutton, obutton, ybutton, gbutton, cbutton, pbutton, ubutton;
JLabel speedlabel, anglelabel, launchlabel;
JSlider speedslider, angleslider;
JPanel displaycanvas;
String fireworkcolor, explosiontype;

private void FireworkLauncher() {
    frame = new JFrame("Fireworks!");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 800);
    frame.setResizable(false);
    frame.setLocationByPlatform(true);
    frame.setLayout(new FlowLayout());
    frame.setBackground(Color.BLACK);
    frame.setVisible(true);

    JPanel displaycanvas = new JPanel();
    displaycanvas.setSize(800, 600);
    displaycanvas.setLayout(new FlowLayout());
    displaycanvas.setLocation(0, 0);
    displaycanvas.setBackground(Color.DARK_GRAY);
    displaycanvas.setVisible(true);
    frame.add(displaycanvas);

    JPanel guistuff = new JPanel();
    guistuff.setSize(800, 200);
    guistuff.setLayout(new FlowLayout());
    guistuff.setBackground(Color.LIGHT_GRAY);
    guistuff.setLocation(0, 600);
    guistuff.setVisible(true);
    frame.add(guistuff);

    JSlider speedslider = new JSlider(JSlider.HORIZONTAL, 0, 100, 10);
    speedslider.addChangeListener(this);
    speedslider.setName("SpeedSlider");
    //speedslider.setValue(50);
    speedslider.setMajorTickSpacing(10);
    speedslider.setMinorTickSpacing(5);
    speedslider.setPaintTicks(true);
    speedslider.setMinimum(0);
    speedslider.setMaximum(100);
    speedslider.setLayout(new FlowLayout());
    speedslider.setVisible(true);
    guistuff.add(speedslider);

    JLabel speedlabel = new JLabel("Speed: " + speed + "   ", JLabel.LEFT);     
    speedlabel.setLayout(new FlowLayout());
    speedlabel.setVisible(true);
    guistuff.add(speedlabel);

    JSlider angleslider = new JSlider(JSlider.HORIZONTAL, 0, 90, 10);
    angleslider.addChangeListener(this);
    angleslider.setName("AngleSlider");
    angleslider.setMinimum(0);
    angleslider.setMaximum(90);
    angleslider.setMajorTickSpacing(10);
    angleslider.setMinorTickSpacing(5);
    angleslider.setPaintTicks(true);
//  angleslider.setValue(50);
    angleslider.setLayout(new FlowLayout());
    angleslider.setVisible(true);
    guistuff.add(angleslider);

    JLabel anglelabel = new JLabel("Angle: " + angle + "      ", JLabel.LEFT);      
    anglelabel.setLayout(new FlowLayout());
    anglelabel.setVisible(true);
    guistuff.add(anglelabel);

    JButton button = new JButton("Launch!");
    button.setPreferredSize(new Dimension(200,50));
    button.setLayout(new FlowLayout());
    button.addActionListener(this);
    button.setLocation(650, 650);
    button.setVisible(true);
    guistuff.add(button);

    //The following six JButtons make buttons for each color to select the color of the next launch of fireworks.
    JButton rbutton = new JButton("Red");
    rbutton.setPreferredSize(new Dimension(100,50));
    rbutton.setLayout(new BorderLayout());
    rbutton.addActionListener(this);
    rbutton.setLocation(25, 750);
    rbutton.setBackground(Color.RED);
    rbutton.setVisible(true);
    rbutton.setOpaque(true);
    rbutton.setBorderPainted(false);
    guistuff.add(rbutton);

    JButton obutton = new JButton("Orange");
    obutton.setPreferredSize(new Dimension(100,50));
    obutton.setLayout(new BorderLayout());
    obutton.addActionListener(this);
    obutton.setLocation(25, 750);
    obutton.setBackground(Color.ORANGE);
    obutton.setVisible(true);
    obutton.setOpaque(true);
    obutton.setBorderPainted(false);
    guistuff.add(obutton);

    JButton ybutton = new JButton("Yellow");
    ybutton.setPreferredSize(new Dimension(100,50));
    ybutton.setLayout(new BorderLayout());
    ybutton.addActionListener(this);
    ybutton.setLocation(25, 750);
    ybutton.setBackground(Color.YELLOW);
    ybutton.setVisible(true);
    ybutton.setOpaque(true);
    ybutton.setBorderPainted(false);
    guistuff.add(ybutton);

    JButton gbutton = new JButton("Green");
    gbutton.setPreferredSize(new Dimension(100,50));
    gbutton.setLayout(new BorderLayout());
    gbutton.addActionListener(this);
    gbutton.setLocation(25, 750);
    gbutton.setBackground(Color.GREEN);
    gbutton.setVisible(true);
    gbutton.setOpaque(true);
    gbutton.setBorderPainted(false);
    guistuff.add(gbutton);

    JButton cbutton = new JButton("Blue");
    cbutton.setPreferredSize(new Dimension(100,50));
    cbutton.setLayout(new BorderLayout());
    cbutton.addActionListener(this);
    cbutton.setLocation(25, 750);
    cbutton.setBackground(Color.CYAN);
    cbutton.setVisible(true);
    cbutton.setOpaque(true);
    cbutton.setBorderPainted(false);
    guistuff.add(cbutton);

    JButton pbutton = new JButton("Pink");
    pbutton.setPreferredSize(new Dimension(100,50));
    pbutton.setLayout(new BorderLayout());
    pbutton.addActionListener(this);
    pbutton.setLocation(25, 750);
    pbutton.setBackground(Color.PINK);
    pbutton.setVisible(true);
    pbutton.setOpaque(true);
    pbutton.setBorderPainted(false);
    guistuff.add(pbutton);

    JButton ubutton = new JButton("Purple");
    ubutton.setPreferredSize(new Dimension(100,50));
    ubutton.setLayout(new BorderLayout());
    ubutton.addActionListener(this);
    ubutton.setLocation(25, 750);
    ubutton.setBackground(Color.MAGENTA);
    ubutton.setVisible(true);
    ubutton.setOpaque(true);
    ubutton.setBorderPainted(false);
    guistuff.add(ubutton);

    //Sets up the interface for the user to select an explosion type.
    JLabel launchlabel = new JLabel("Type of Explosion: ", JLabel.LEFT);
    launchlabel.setLayout(new FlowLayout());
    launchlabel.setVisible(true);
    guistuff.add(launchlabel);

    JRadioButton radio1 = new JRadioButton("Splash");
    //Lots of random lines will display from the explosion site out to the rest of the canvas.
    radio1.addItemListener(this);
    radio1.setSelected(false);
    guistuff.add(radio1);
    radio1.setLayout(new FlowLayout());
    radio1.setVisible(true);

    JRadioButton radio2 = new JRadioButton("Bubbles");
    //Lots of circles will display at the explosion site
    radio2.addItemListener(this);
    guistuff.add(radio2);
    radio2.setLayout(new FlowLayout());
    radio2.setSelected(false);
    radio2.setVisible(true);

    JRadioButton radio3 = new JRadioButton("Sprinkles");
    //Lots of little x's will display at the explosion site
    radio3.addItemListener(this);
    guistuff.add(radio3);
    radio3.setLayout(new FlowLayout());
    radio3.setSelected(false);
    radio3.setVisible(true);

    JRadioButton radio4 = new JRadioButton("Giant");
    //Explosion will draw ALOT (5000) pixels randomly on the screen.
    radio4.addItemListener(this);
    guistuff.add(radio4);
    radio4.setLayout(new FlowLayout());
    radio4.setSelected(false);
    radio4.setVisible(true);

    JRadioButton radio5 = new JRadioButton("Tiny");
    //Explosion will draw a few (100) pixels randomly on the screen.
    radio5.addItemListener(this);
    guistuff.add(radio5);
    radio5.setLayout(new FlowLayout());
    radio5.setSelected(false);
    radio5.setVisible(true);

    JRadioButton radio6 = new JRadioButton("Random");
    //Will generate a random number from 0-4 that corresponds to a certain explosion type. 
    radio6.addItemListener(this);
    guistuff.add(radio6);
    radio6.setLayout(new FlowLayout());
    radio6.setSelected(true);
    radio6.setVisible(true);

    ButtonGroup radiogroup = new ButtonGroup();
    radiogroup.add(radio1);
    radiogroup.add(radio2);
    radiogroup.add(radio3);
    radiogroup.add(radio4);
    radiogroup.add(radio5);
    radiogroup.add(radio6);

    guistuff.validate();

    Display display = new Display();
}

class Display extends JPanel {


    public void paintComponent(Graphics g) {
        // PAINTING OF THE FIREWORKS!
        super.paintComponent(g);
        g.setColor(Color.CYAN);
        g.drawLine(50, 50, 100, 100);
        g.fillOval(100, 100, 50, 50);
        g.drawLine(0, 0, 400, 400);
        repaint();
    }
}

@Override
public void stateChanged(ChangeEvent e) {
    // TODO Auto-generated method stub
    JSlider source = (JSlider) e.getSource();
    String sourcename = source.getName();
    System.out.println(sourcename);
    if (sourcename.equals("SpeedSlider")) {
        JLabel speedlabel = new JLabel("Speed: " + speed + "   ", JLabel.LEFT); 
        speed = source.getValue();
        String speedstring = Integer.toString(speed);
        System.out.println(speedstring);
        System.out.println(speedlabel.getText());
        speedlabel.setText("Speed: " + (speedstring));
        System.out.println("speed slider was moved");
        speedlabel.repaint();
    } else if (sourcename.equals("AngleSlider")) {
        angle = angleslider.getValue();
        System.out.println(angle);
        String anglestring = Integer.toString(angle);
        anglelabel.setText("Angle: " + (anglestring));
        System.out.println("angle slider was moved");
        anglelabel.repaint();
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    System.out.println(e.getActionCommand());
    //Calculations for the explosion trajectories go here
    if (e.getActionCommand().equals("Launch!")){
        System.out.println("FIREWORK LAUNCHED!");
    } else if (e.getActionCommand().equals("Red")){
        System.out.println("FIREWORK COLOR CHANGED TO RED");
        fireworkcolor = "r";
    } else if (e.getActionCommand().equals("Orange")){
        System.out.println("FIREWORK COLOR CHANGED TO ORANGE");
        fireworkcolor = "o";
    } else if (e.getActionCommand().equals("Yellow")){
        System.out.println("FIREWORK COLOR CHANGED TO YELLOW");
        fireworkcolor = "y";
    } else if (e.getActionCommand().equals("Green")){
        System.out.println("FIREWORK COLOR CHANGED TO GREEN");
        fireworkcolor = "g";
    } else if (e.getActionCommand().equals("Blue")){
        System.out.println("FIREWORK COLOR CHANGED TO BLUE");
        fireworkcolor = "b";
    } else if (e.getActionCommand().equals("Pink")){
        System.out.println("FIREWORK COLOR CHANGED TO PINK");
        fireworkcolor = "p";
    } else if (e.getActionCommand().equals("Purple")){
        System.out.println("FIREWORK COLOR CHANGED TO PURPLE");
        fireworkcolor = "u";
    }
    System.out.println(fireworkcolor);
}

@Override
public void itemStateChanged(ItemEvent e) {
    // TODO Auto-generated method stub
    String radiotag = ((AbstractButton) e.getItem()).getText();
    if (radiotag.equals("Splash")){
        System.out.println("Splash");
        explosiontype = "splash";
    } else if (radiotag.equals("Bubbles")){
        System.out.println("Bubbles");
        explosiontype = "bubbles";
    } else if (radiotag.equals("Sprinkles")){
        System.out.println("Sprinkles");
        explosiontype = "sprinkles";
    } else if (radiotag.equals("Giant")){
        System.out.println("Giant");
        explosiontype = "giant";
    } else if (radiotag.equals("Tiny")){
        System.out.println("Tiny");
        explosiontype = "tiny";
    } else if (radiotag.equals("Random")){
        System.out.println("Random");
        explosiontype = "random";
    } 
    System.out.println(explosiontype);

}

public int getSpeed() {
    return speed;
}

public void setSpeed(int speed) {
    this.speed = speed;
}

public int getAngle() {
    return angle;
}

public void setAngle(int angle) {
    this.angle = angle;
}

public int getLaunch() {
    return launch;
}

public void setLaunch(int launch) {
    this.launch = launch;
}

public String getFireworkcolor() {
    return fireworkcolor;
}

public void setFireworkcolor(String fireworkcolor) {
    this.fireworkcolor = fireworkcolor;
}

public String getExplosiontype() {
    return explosiontype;
}

public void setExplosiontype(String explosiontype) {
    this.explosiontype = explosiontype;
}

public static void main(String[] args) {
    new Fireworks().FireworkLauncher();
}

}

最佳答案

How to get simple graphics drawn on canvas with GUI

如果你想显示简单的图形,那么为什么不创建一个简单的程序来解决你的问题呢?一旦你知道了问题所在,你就可以将解决方案应用到你的实际程序中。

自定义绘制是通过重写paintComponent()来完成的。我在您的代码中看到的唯一 paintComponent() 方法位于 Display 类中。

我看到您使用 Display 类的唯一地方是:

Display display = new Display();

我没有看到您将组件添加到框架的任何位置。

但即使您将其添加到框架中,您仍然可能看不到它,因为您没有重写 getPreferredSize() 方法。

首先阅读 Custom Painting 上的 Swing 教程自定义绘画的简单示例。

Another issue I've been having is with my JSliders, but that's much less of an important issue for me

按照我最初的建议创建一个简单的程序来使用 slider ,直到您了解它是如何工作的。然后将逻辑添加到您的主程序中。这种类型的程序称为 SSCCE并用于简化问题。然后,如果它仍然不起作用,您可以将简单的代码发布到论坛上。

关于java - 如何使用 GUI 在 Canvas 上绘制简单图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33705012/

相关文章:

javascript - 如何使用 JavaScript 修复 HTML Canvas 对象中扭曲/扭曲和剪切的图像?

java - 如何从表单检索 jsp web 项目中的 json obj 值

java - "Unable to get provider com.google.firebase.provider.FirebaseInitProvider"Android路径错误

Java native SQL 查询以在输入参数为 null 时显示所有值

java - 使用 CardLayout 将自定义面板添加到 Applet

c# - 不在 UIElement 上时 Silverlight 中的 Canvas Click 事件

java - Java中有缓冲区填充接收方法吗?

multithreading - 如何在后台更新 MATLAB GUI?

C#:Windows 窗体:在面板/图片框中获取击键?

javascript - Chrome Canvas 渲染速度错误?