更新单选按钮选择时重新传输数据



我正在开发一个Java GUI应用程序,它允许我用不同的颜色绘制不同的形状。我有两个不同的单选按钮组用于形状和颜色。默认情况下,每个组都选择了随机按钮。它是有效的。但我想选择其他东西,并用选定的颜色绘制选定的形状。问题是,当我选择不同的单选按钮时,我不知道如何更新。如果我将其设置为默认值,则每个选择都有效。但一旦我启动程序,它将只绘制默认的选定选项。这就是我目前所拥有的:

Main.java

package com.daema.P5;
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//////CREATING THE FRAME WITH TITLE AND SET THE FRAME LAYOUT TO GRID///////////////
JFrame f = new JFrame("Shapes on click Application");
GridBagLayout frameGridBagLayout = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
f.setFont(new Font("SansSerif", Font.PLAIN, 14));
f.setLayout(frameGridBagLayout);
/////CREATING TOP PANEL WHICH CONTAINS THE OPTIONS/////////
/////CREATING COLORS PANEL//////////
JPanel topPanelColors = new JPanel();
JLabel colorsLabel = new JLabel("Culoare: ");
ButtonGroup colorsGroup = new ButtonGroup();
JRadioButton rosu = new JRadioButton();
rosu.setText("Rosu");
rosu.setActionCommand("rosu");
JRadioButton verde = new JRadioButton();
verde.setText("Verde");
verde.setActionCommand("verde");
JRadioButton albastru = new JRadioButton();
albastru.setText("Albastru");
albastru.setActionCommand("albastru");
JRadioButton randomColor = new JRadioButton();
randomColor.setText("Random");
randomColor.setActionCommand("randomColor");
randomColor.setSelected(true);
colorsGroup.add(rosu);
colorsGroup.add(verde);
colorsGroup.add(albastru);
colorsGroup.add(randomColor);
topPanelColors.add(colorsLabel);
topPanelColors.add(rosu);
topPanelColors.add(verde);
topPanelColors.add(albastru);
topPanelColors.add(randomColor);
constraints.gridy = GridBagConstraints.PAGE_START;
f.add(topPanelColors, constraints);
/////CREATING SHAPES PANEL/////////
JPanel topPanelShapes = new JPanel();
JLabel shapesLabel = new JLabel("Forma: ");
ButtonGroup shapesGroup = new ButtonGroup();
JRadioButton cerc = new JRadioButton();
cerc.setText("Cerc");
cerc.setActionCommand("cerc");
JRadioButton patrat = new JRadioButton();
patrat.setText("Patrat");
patrat.setActionCommand("patrat");
JRadioButton triunghi = new JRadioButton();
triunghi.setText("Triungi");
triunghi.setActionCommand("triunghi");
JRadioButton randomShape = new JRadioButton();
randomShape.setText("Random");
randomShape.setActionCommand("randomShape");
randomShape.setSelected(true);
shapesGroup.add(cerc);
shapesGroup.add(patrat);
shapesGroup.add(triunghi);
shapesGroup.add(randomShape);
topPanelShapes.add(shapesLabel);
topPanelShapes.add(cerc);
topPanelShapes.add(patrat);
topPanelShapes.add(triunghi);
topPanelShapes.add(randomShape);
constraints.gridy = GridBagConstraints.LINE_START;
f.add(topPanelShapes, constraints);

///////CREATING THE BOTTOM PANEL WHICH CONTAINS THE DRAWING PANEL////////////
JPanel bottomPanel = new JPanel();
DrawPanel p = new DrawPanel(10f, shapesGroup.getSelection().getActionCommand(), colorsGroup.getSelection().getActionCommand());
p.setPreferredSize(new Dimension(420, 420));
bottomPanel.add(p);
constraints.gridy = GridBagConstraints.LAST_LINE_START;
f.add(bottomPanel, constraints);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}

DrawPanel.java

package com.daema.P5;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class DrawPanel extends JPanel implements MouseListener {
@Serial
private static final long serialVersionUID = -6817035652787391530L;
private final List<Shape> shapes;
protected float radius;
protected String shape;
protected String color;
public DrawPanel(float radius, String shape, String color) {
this.shapes = new ArrayList<>();
this.radius = radius;
this.shape = shape;
this.color = color;
setBackground(Color.WHITE);
addMouseListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Shape shape : shapes) {
shape.paintComponent(g);
}
}
public int getRandomNumber() {
Random random = new Random();
return random.nextInt(4 - 1) + 1;
}
@Override
public void mouseClicked(MouseEvent e) {
float sat = 0.7f;
float bri = 0.8f;
switch (shape) {
case "cerc" -> {
switch (color) {
case "rosu" -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.RED));
case "verde" -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.GREEN));
case "albastru" -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.BLUE));
case "randomColor" -> shapes.add(new Circle(e.getX(), e.getY(), radius, ColorUtils.randHue(sat, bri)));
}
}
case "patrat" -> {
switch (color) {
case "rosu" -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.RED));
case "verde" -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.GREEN));
case "albastru" -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.BLUE));
case "randomColor" -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, ColorUtils.randHue(sat, bri)));
}
}
case "triunghi" -> {
switch (color) {
case "rosu" -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.RED));
case "verde" -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.GREEN));
case "albastru" -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.BLUE));
case "randomColor" -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, ColorUtils.randHue(sat, bri)));
}
}
case "randomShape" -> {
int random = getRandomNumber();
switch (color) {
case "rosu" -> {
switch (random) {
case 1 -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.RED));
case 2 -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.RED));
case 3 -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.RED));
default -> throw new IllegalStateException("Unexpected value: " + random);
}
}
case "verde" -> {
switch (random) {
case 1 -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.GREEN));
case 2 -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.GREEN));
case 3 -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.GREEN));
default -> throw new IllegalStateException("Unexpected value: " + random);
}
}
case "albastru" -> {
switch (random) {
case 1 -> shapes.add(new Circle(e.getX(), e.getY(), radius, Color.BLUE));
case 2 -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, Color.BLUE));
case 3 -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, Color.BLUE));
default -> throw new IllegalStateException("Unexpected value: " + random);
}
}
case "randomColor" -> {
switch (random) {
case 1 -> shapes.add(new Circle(e.getX(), e.getY(), radius, ColorUtils.randHue(sat, bri)));
case 2 -> shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, ColorUtils.randHue(sat, bri)));
case 3 -> shapes.add(new Square(e.getX(), e.getY(), radius * 2, ColorUtils.randHue(sat, bri)));
default -> throw new IllegalStateException("Unexpected value: " + random);
}
}
}
}
}
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}

Shape.java

package com.daema.P5;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public interface Shape {
Point getOrigin();
void setOrigin(Point origin);
Color getColor();
void setColor(Color color);
void paintComponent(Graphics g);
}

Circle.java

package com.daema.P5;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public class Circle implements Shape {
private Point origin;
private float radius;
private Color color;
public Circle() {
this(0, 0, 0.5f, Color.BLACK);
}
public Circle(int x, int y, float radius, Color color) {
this(new Point(x, y), radius, color);
}
public Circle(Point origin, float radius, Color color) {
this.origin = origin;
this.radius = radius;
this.color = color;
}
@Override
public Point getOrigin() {
return origin;
}
@Override
public void setOrigin(Point origin) {
this.origin = origin;
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
@Override
public Color getColor() {
return color;
}
@Override
public void setColor(Color color) {
this.color = color;
}
@Override
public void paintComponent(Graphics g) {
int diameter = (int) (this.radius * 2);
int x = (int) (origin.x - this.radius);
int y = (int) (origin.y - this.radius);
g.setColor(this.color);
g.fillOval(x, y, diameter, diameter);
}
}

Triangle.java

package com.daema.P5;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.Point2D;
public class Triangle implements Shape {
private Point origin;
private float side;
private Color color;
private Polygon poly;
public Triangle(int x, int y, float side, Color color) {
this(new Point(x, y), side, color);
}
public Triangle(Point origin, float side, Color color) {
this.origin = origin;
this.side = side;
this.color = color;
recalculate();
}
protected void recalculate() {
this.poly = createPolygon((float) origin.getX(), (float) origin.getY(), side, false);
}
protected Polygon createPolygon(float x, float y, float side, boolean invert) {
float xOff = side / 2f;
float yOff = (float) (xOff * Math.sqrt(3));
float r1 = 1f / 3f;
float r2 = 2f / 3f;
if (invert) {
yOff *= -1;
}
return createPolygon(new Point2D.Float[] {
new Point2D.Float(x,        y - (yOff * r2)), // Top
new Point2D.Float(x - xOff, y + (yOff * r1)), // Left
new Point2D.Float(x + xOff, y + (yOff * r1))  // Right
});
}
protected Polygon createPolygon(Point2D.Float[] points) {
int nPoints = points.length + 1;
int[] xCoords = new int[nPoints];
int[] yCoords = new int[nPoints];
for (int i = 0; i < nPoints; i++) {
xCoords[i] = (int) points[i % points.length].x;
yCoords[i] = (int) points[i % points.length].y;
}
return new Polygon(xCoords, yCoords, nPoints);
}
@Override
public Point getOrigin() {
return origin;
}
@Override
public void setOrigin(Point origin) {
this.origin = origin;
recalculate();
}
public float getSide() {
return side;
}
public void setSide(float side) {
this.side = side;
recalculate();
}
@Override
public Color getColor() {
return color;
}
@Override
public void setColor(Color color) {
this.color = color;
}
@Override
public void paintComponent(Graphics g) {
g.setColor(this.color);
g.fillPolygon(poly);
}
}

Square.java

package com.daema.P5;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.Point2D;
public class Square implements Shape {
private Point origin;
private float side;
private Color color;
private Polygon poly;
public Square(int x, int y, float side, Color color) {
this(new Point(x, y), side, color);
}
public Square(Point origin, float side, Color color) {
this.origin = origin;
this.side = side;
this.color = color;
recalculate();
}
protected void recalculate() {
this.poly = createPolygon((float) origin.getX(), (float) origin.getY(), side);
}
protected Polygon createPolygon(float x, float y, float side) {
float xOff = side / 2f;
return createPolygon(new Point2D.Float[] {
new Point2D.Float(x - xOff, y + xOff),  // Top Left Corner
new Point2D.Float(x + xOff, y + xOff),  // Top Right Corner
new Point2D.Float(x + xOff, y - xOff),  // Bottom Right Corner
new Point2D.Float(x - xOff, y - xOff),  // Bottom Left Corner
});
}
protected Polygon createPolygon(Point2D.Float[] points) {
int nPoints = points.length + 1;
int[] xCoords = new int[nPoints];
int[] yCoords = new int[nPoints];
for (int i = 0; i < nPoints; i++) {
xCoords[i] = (int) points[i % points.length].x;
yCoords[i] = (int) points[i % points.length].y;
}
return new Polygon(xCoords, yCoords, nPoints);
}
@Override
public Point getOrigin() {
return origin;
}
@Override
public void setOrigin(Point origin) {
this.origin = origin;
recalculate();
}
public float getSide() {
return side;
}
public void setSide(float side) {
this.side = side;
recalculate();
}
@Override
public Color getColor() {
return color;
}
@Override
public void setColor(Color color) {
this.color = color;
}
@Override
public void paintComponent(Graphics g) {
g.setColor(this.color);
g.fillPolygon(poly);
}
}

ColorUtils.java

package com.daema.P5;
import java.awt.Color;
import java.util.Random;
public class ColorUtils {
private static final Random RAND;
static {
RAND = new Random(System.currentTimeMillis());
}
public static Color randHue(float saturation, float brightness) {
return Color.getHSBColor(RAND.nextFloat(), saturation, brightness);
}
}

此外,我想在某个地方添加一个CLEAR按钮,以清除我的绘图面板。

我认为您应该尝试使用MVC设计模式,这样您的代码更容易理解和调试。看一些例子,但它大致意味着将java swing程序拆分为三个模块:Model、View和Controller。

在你的情况下,我认为你的项目结构应该如下:

Main.java
- View folder
MyView.java
DrawPanel.java
Circle.java
Triangle.java
Square.java
- Controller folder
MyActionListener.java
MyMouseListener.java
- Model folder
Shape.java
- Utils folder
ColorUtils.java

通过这些更改,我们现在可以解决您的问题。请注意,您应该删除在DrawPanel.java类中实现的ActionListener,并将其放在Controller下的一个新类中,Main.java上的当前代码应该在MyView.java类中。

要注册对单选按钮所做的更改,您需要ActionListener,如Oracle示例中所述,特别是"如何使用单选按钮"部分中所述。

要清除视图,您应该创建一个也由ActionListener控制的JButton

如何使用ActionListener控制单选按钮,以及为什么我建议您从主文件中拆分视图:

在main中声明视图和逻辑,并传递对控制器视图的引用,以便将它们绑定到您的单选按钮/按钮,如下所示:

public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
View view = new View();
MyActionListener myActionListener = new MyActionListener();
MyMouseListener myMouseListener = new MyMouseListener();
view.registerActionListener(myActionListener);
view.registerMouseListener(myMouseListener);
}
});
}
}

现在,您应该简单地将侦听器连接到视图中所需的JFrame组件:

public class View extends JFrame{
private JButton clearShapes;
private void foo(){
...
clearShapes = new JButton("Clear shapes");
f.add(clearShapes);
...
}
public void registerActionListener(MyActionListener myActionListener){
clearShapes.addActionListener(myActionListener);
yourRadioButtons.addActionListener(myActionListener);
}
public void registerMouseListener(MyMouseListener myMouseListener){
somePanel.addMouseListener(myMouseListener);
}
}

总结:

  1. 清楚区分Model、View和Controller(在您的情况下,主要是View和Controller(
  2. 向相应的控制器注册每个视图的组件,并模块化地管理它们的行为
  3. 一旦每个组件都可以进行管理,就可以查看文档中关于如何管理单选按钮、按钮或其他任何东西的示例,并相应地采取行动,使代码适应您的需求

这是一个很长的答案,解释的比你要求的要多,但你的代码一团糟,对于这个项目和未来的项目,你最好实现某种设计模式,这样代码对你来说是清晰的(即使你在一段时间后没有处理它(,对其他人来说也是清晰的,这样他们就可以很容易地提供帮助。

总之,你的问题并不复杂,但你目前的结构使它变得复杂。稍微清理一下,你就会搞定的。

最新更新