如何让每个切换按钮执行不同的操作?
How do I get each of my toggle buttons to do something different?
好的,所以我正在使用 java swing 编写 GUI,我一直在使用一些旧代码来创建一个移动的正方形,但现在我必须使用切换按钮来显示一些形状和从 window 中消失。我的程序应该有 4 个不同的切换按钮(目前有 3 个),每个都有特定的用途:名称将在屏幕中央显示我的名字,矩形将在屏幕右下角显示一个矩形,椭圆形也会在右下角显示一个椭圆形。我试图使用一系列布尔值来指示出现哪个形状,但出于某种原因,每个按钮只会切换矩形,我不知道为什么。是不是我做错了什么导致所有按钮都做同样的事情?
到目前为止,这是我的代码。第一个是我的 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 String display = " ";
private String none = " ";
private int dx = 2;
private int dy = 2;
private boolean rectangle = true;
private boolean oval= true;
private boolean Name = true;
private boolean special = true;
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 input()
{
System.out.print("Button");
}
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 paintComponent(Graphics g)
{
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
int textx = x+w/2;
int texty = y+h/2;
FontMetrics fm = g.getFontMetrics();
int texth = fm.getHeight();
int textw = fm.stringWidth(display);
textx -= textw/2;
texty += texth/2;
texty -= 5;
if(Name == true)
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
Name = false;
}
else if(Name == false)
{
g.drawString(none, textx, texty);
Name = true;
}
if (oval == true)
{
g.setColor(Color.CYAN);
g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);
oval = false;
}
else if(oval == false)
{
g.setColor(Color.WHITE);
g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);
oval = true;
}
if(rectangle == true)
{
g.setColor(Color.PINK);
g.fillRect(w/2, h/2, w/2, h/2);
rectangle = false;
}
else if(rectangle == false)
{
g.setColor(Color.WHITE);
g.fillRect(w/2, h/2, w/2, h/2);
rectangle = true;
}
/*int w = getWidth();
int h = getHeight();
g.setColor(colors[colorNumber]);
if (shape % 2 == 0) //g.fillOval(x, y, width, height);
elseg.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);
*/
}
}
被注释掉的是因为后面会实现一个特殊的按钮。
这是我的主要 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 oval;
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,4));
Name = new JToggleButton("Name");
Name.addActionListener(this);
oval = new JToggleButton("Oval");
oval.addActionListener(this);
rectangle = new JToggleButton("Rectangle");
rectangle.addActionListener(this);
//theText = new JTextField("HI");
//theText.addActionListener(this);
topPanel.add(Name);
topPanel.add(oval);
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() == oval)
{
paintPanel.input();
}
/*else if (e.getSource() == frameTimer)
{
paintPanel.update();
}*/
if (e.getSource() == rectangle)
{
paintPanel.input();
}
if (e.getSource() == oval)
{
//System.out.println("start/stop");
paintPanel.input();
}
if (e.getSource() == Name)
{
paintPanel.input();
String text = e.getActionCommand();
paintPanel.setDisplayText("Servando Hernandez");
//System.out.println(text);
}
repaint();
}
public static void main(String[] args)
{
GuiTest gui = new GuiTest();
gui.setVisible(true);
}
}
您的代码中有很多令人困惑的地方。对于初学者,每次 paintComponent()
运行时,您都在切换 on/off 所有形状的状态。您应该从 actionPerformed()
方法处理状态。例如:
if (e.getSource() == rectangle) {
// paintPanel.input(); // what's this doing anyways?
paintPanel.setShowRectangle(rectangle.isSelected());
}
无论如何,由于各种原因,您的其他形状没有显示...
您的 display
是一个空字符串。试试看:
g.drawString("Test", textx, texty);
您的位置正在将其从面板中拉出。我将它更改为(5 到 1)只是为了让它出现,但您可能希望它出现在其他地方:
g.fillOval((1 * w) / 8, (1 * h) / 8, w / 4, h / 4);
Whatever is commented out is because it will be implemented later for a special button.
好吧,请不要在问题中包含代码。代码与问题无关,我们不想浪费时间阅读它或猜测它为什么在那里?
private boolean Name = true;
为什么变量名要大写? None 的其他变量以大写字母开头(这是正确的)。保持一致!!!
if(Name == true)
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
Name = false;
}
else if(Name == false)
{
g.drawString(none, textx, texty);
Name = true;
}
您正在使 if 语句变得复杂。如果布尔变量不为真,则为假。只需使用:
if(name == true)
//if(name) // even simpler, you don't need the "== true"
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
}
else
{
g.drawString(none, textx, texty);
}
我不明白你的 ActionListener 代码。无论你点击什么按钮,你总是执行 paintPanel.input()
.
查看下面的编辑示例,了解代码应该是什么。
使用这些建议整理代码。如果您仍然需要更多帮助,那么 post 一个适当的 SSCCE 来演示问题。
编辑:
您需要向 PaintPanel 添加属性 class。例如:
public void setOval(Boolean oval)
{
this.oval = oval;
repaint();
}
现在在 ActionListener 中,您的代码将是:
if (e.getSource() == oval)
{
paintPanel.setOval( oval.isSelected();
}
好的,所以我正在使用 java swing 编写 GUI,我一直在使用一些旧代码来创建一个移动的正方形,但现在我必须使用切换按钮来显示一些形状和从 window 中消失。我的程序应该有 4 个不同的切换按钮(目前有 3 个),每个都有特定的用途:名称将在屏幕中央显示我的名字,矩形将在屏幕右下角显示一个矩形,椭圆形也会在右下角显示一个椭圆形。我试图使用一系列布尔值来指示出现哪个形状,但出于某种原因,每个按钮只会切换矩形,我不知道为什么。是不是我做错了什么导致所有按钮都做同样的事情? 到目前为止,这是我的代码。第一个是我的 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 String display = " ";
private String none = " ";
private int dx = 2;
private int dy = 2;
private boolean rectangle = true;
private boolean oval= true;
private boolean Name = true;
private boolean special = true;
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 input()
{
System.out.print("Button");
}
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 paintComponent(Graphics g)
{
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
int textx = x+w/2;
int texty = y+h/2;
FontMetrics fm = g.getFontMetrics();
int texth = fm.getHeight();
int textw = fm.stringWidth(display);
textx -= textw/2;
texty += texth/2;
texty -= 5;
if(Name == true)
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
Name = false;
}
else if(Name == false)
{
g.drawString(none, textx, texty);
Name = true;
}
if (oval == true)
{
g.setColor(Color.CYAN);
g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);
oval = false;
}
else if(oval == false)
{
g.setColor(Color.WHITE);
g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);
oval = true;
}
if(rectangle == true)
{
g.setColor(Color.PINK);
g.fillRect(w/2, h/2, w/2, h/2);
rectangle = false;
}
else if(rectangle == false)
{
g.setColor(Color.WHITE);
g.fillRect(w/2, h/2, w/2, h/2);
rectangle = true;
}
/*int w = getWidth();
int h = getHeight();
g.setColor(colors[colorNumber]);
if (shape % 2 == 0) //g.fillOval(x, y, width, height);
elseg.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);
*/
}
}
被注释掉的是因为后面会实现一个特殊的按钮。 这是我的主要 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 oval;
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,4));
Name = new JToggleButton("Name");
Name.addActionListener(this);
oval = new JToggleButton("Oval");
oval.addActionListener(this);
rectangle = new JToggleButton("Rectangle");
rectangle.addActionListener(this);
//theText = new JTextField("HI");
//theText.addActionListener(this);
topPanel.add(Name);
topPanel.add(oval);
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() == oval)
{
paintPanel.input();
}
/*else if (e.getSource() == frameTimer)
{
paintPanel.update();
}*/
if (e.getSource() == rectangle)
{
paintPanel.input();
}
if (e.getSource() == oval)
{
//System.out.println("start/stop");
paintPanel.input();
}
if (e.getSource() == Name)
{
paintPanel.input();
String text = e.getActionCommand();
paintPanel.setDisplayText("Servando Hernandez");
//System.out.println(text);
}
repaint();
}
public static void main(String[] args)
{
GuiTest gui = new GuiTest();
gui.setVisible(true);
}
}
您的代码中有很多令人困惑的地方。对于初学者,每次 paintComponent()
运行时,您都在切换 on/off 所有形状的状态。您应该从 actionPerformed()
方法处理状态。例如:
if (e.getSource() == rectangle) {
// paintPanel.input(); // what's this doing anyways?
paintPanel.setShowRectangle(rectangle.isSelected());
}
无论如何,由于各种原因,您的其他形状没有显示...
您的 display
是一个空字符串。试试看:
g.drawString("Test", textx, texty);
您的位置正在将其从面板中拉出。我将它更改为(5 到 1)只是为了让它出现,但您可能希望它出现在其他地方:
g.fillOval((1 * w) / 8, (1 * h) / 8, w / 4, h / 4);
Whatever is commented out is because it will be implemented later for a special button.
好吧,请不要在问题中包含代码。代码与问题无关,我们不想浪费时间阅读它或猜测它为什么在那里?
private boolean Name = true;
为什么变量名要大写? None 的其他变量以大写字母开头(这是正确的)。保持一致!!!
if(Name == true)
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
Name = false;
}
else if(Name == false)
{
g.drawString(none, textx, texty);
Name = true;
}
您正在使 if 语句变得复杂。如果布尔变量不为真,则为假。只需使用:
if(name == true)
//if(name) // even simpler, you don't need the "== true"
{
g.setColor(Color.BLACK);
g.drawString(display, textx, texty);
}
else
{
g.drawString(none, textx, texty);
}
我不明白你的 ActionListener 代码。无论你点击什么按钮,你总是执行 paintPanel.input()
.
查看下面的编辑示例,了解代码应该是什么。
使用这些建议整理代码。如果您仍然需要更多帮助,那么 post 一个适当的 SSCCE 来演示问题。
编辑:
您需要向 PaintPanel 添加属性 class。例如:
public void setOval(Boolean oval)
{
this.oval = oval;
repaint();
}
现在在 ActionListener 中,您的代码将是:
if (e.getSource() == oval)
{
paintPanel.setOval( oval.isSelected();
}