如何在 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
被调用时,您应该完全重新绘制组件的当前状态
好的,所以我正在尝试使用 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
被调用时,您应该完全重新绘制组件的当前状态