如何在 Java Swing 中打开和关闭屏幕上的形状?

How can I toggle shapes on and off screen in Java Swing?

好的,所以我正在尝试使用 swing 构建一个程序,我必须能够在屏幕的右下角绘制一个椭圆形和矩形。我目前正在尝试使用一个先前的程序,其中程序使用 JToggleSwitch 启动和停止一个正方形。我的问题是我怎样才能得到一个形状来打开和关闭屏幕,因为它需要一个参数 "Graphics g"。到目前为止,这是我的 PaintPanel 代码。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PaintPanel extends JPanel
{
    private static Color[] colors =
        { Color.RED, Color.BLACK, Color.PINK, Color.ORANGE };
    private int colorNumber = 0;

    private int shape = 0;

    private int x = 0;
    private int y = 0;

    private int width = 100;
    private int height = 100;

    private int dx = 2;
    private int dy = 2;

    private String displayString = "hello";

    private boolean isStarted = true;

    public void update()
    {
        if (isStarted) 
        {
            x += dx;
            y += dy;
        }
        //dx ++;
        //dy ++;

        if (y + height > getHeight())
        {
            dy = -Math.abs(dy);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }
        else if (y < 0)
        {
            dy = Math.abs(dy);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }

        if (x + width > getWidth())
        {
            dx = -Math.abs(dx);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }
        else if (x < 0)
        {
            dx = Math.abs(dx);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }

    }

    public void changeColor()
    {
        colorNumber = (colorNumber+1) % colors.length;
    }

    public void startStop()
    {
        //if (isStarted == true) isStarted = false;
        //else isStarted = true;

        isStarted = !isStarted;
    }

    public void setDisplayText(String dt)
    {
        displayString = dt;
    }
    public void paintRectangle(Graphics g)
    {

        int w = getWidth();
        int h = getHeight();
        g.setColor(Color.PINK);
        g.fillRect(w/2, h/2, w/2, h/2);
        //g.setColor(Color.CYAN);
        //g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);


    }


    public void paintComponent(Graphics g)
    {



        int w = getWidth();
        int h = getHeight();
        g.setColor(colors[colorNumber]);
        if (shape % 2 == 0) //g.fillOval(x, y, width, height);
        /*else*/ g.fillRect(x,y, width, height);


        int textx = x+width/2;
        int texty = y+height/2;

        FontMetrics fm = g.getFontMetrics();
        int texth = fm.getHeight();
        int textw = fm.stringWidth(displayString);

        textx -= textw/2;
        texty += texth/2;
        texty -= 5;     

        g.setColor(colors[(colorNumber+1)%colors.length]);
        g.drawString(displayString, textx, texty);
    }

}

这里是创建 window 和面板的实际代码。这是我的主要class。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GuiTest extends JFrame 
    implements ActionListener
{
    private Timer frameTimer;
    private JToggleButton name;
    private JToggleButton ovalButton;
    private JToggleButton rectangle;
    //private JTextField theText;
    private PaintPanel paintPanel;

    public GuiTest()
    {
        setTitle("Servando Hernandez");
        setSize(500,500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(1,3));

        name = new JToggleButton("Name");
        name.addActionListener(this);

        ovalButton = new JToggleButton("Oval");
        ovalButton.addActionListener(this);

        rectangle = new JToggleButton("Rectangle");
        rectangle.addActionListener(this);

        //theText = new JTextField("HI");
        //theText.addActionListener(this);


        topPanel.add(name);
        topPanel.add(ovalButton);
        topPanel.add(rectangle);
        //topPanel.add(theText);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(topPanel, BorderLayout.SOUTH);

        paintPanel = new PaintPanel();
        contentPane.add(paintPanel, BorderLayout.CENTER);

        frameTimer = new Timer(50, this);
        frameTimer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        //System.out.println("Action performed");
        if (e.getSource() == name)      
        {
            paintPanel.changeColor();
        }
        else if (e.getSource() == frameTimer)
        {
            paintPanel.update();
        }
        else if (e.getSource() == ovalButton)
        {
            //System.out.println("start/stop");
            paintPanel.startStop();
        }
        else if (e.getSource() == rectangle)
        {

        }
        /*else if (e.getSource() == theText)
        {
            String text = e.getActionCommand();
            paintPanel.setDisplayText(text);
            //System.out.println(text);
        }
        */
        repaint();
    }

    public static void main(String[] args)
    {
        GuiTest gui = new GuiTest();
        gui.setVisible(true);

    }
}

你可以...

维护 List 个要绘制的 Shape,根据需要添加或删除它们。然后,您将在 paintComponent 方法中循环遍历列表,绘制 List 中的内容,并在需要更新组件时简单地调用 repaint

你可以...

有一系列 boolean(或其他类型的)标志,指示要绘制的形状。这种修复了可以绘制的形状,并且实际上不允许您控制形状的 z 顺序

你应该...

在进行任何自定义绘制之前调用 super.paintComponent,否则每次绘制组件时您都可能会产生不需要的绘制瑕疵。请记住,绘制是破坏性的,当 paintComponent 被调用时,您应该完全重新绘制组件的当前状态