【问题标题】:Retransmit data when I update radio button selection [closed]当我更新单选按钮选择时重新传输数据[关闭]
【发布时间】:2021-07-19 21:43:14
【问题描述】:

我正在使用 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);
    }
}

我还想在某处添加一个清除按钮来清除我的绘图面板。

【问题讨论】:

  • 你的代码太长,别人看不到,缩小到minimal reproducible example,如果你想画不同的形状,你可以以this answer为起点,或者this one,也可能是this one
  • 您可以在每次选择新形状时添加一个新的ShapeArrayList,并让这个Shape 有自己的颜色,迭代这个数组,在@ 上设置颜色987654335@,当您想清除所有内容时,只需从ArrayList 中删除所有形状并重新绘制。这基本上就是我上面评论中的第一个答案是如何做到的,第三个答案允许您使用按钮选择形状并更改其颜色

标签: java swing awt


【解决方案1】:

我认为您应该尝试使用 MVC 设计模式,以便您的代码更易于理解和调试。看一些例子,但大致意思是将一个java swing程序分成三个模块:模型、视图和控制器。

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

 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 示例中所述,特别是在 How to use Radio Buttons 部分中。

要清除视图,您应该创建一个JButton,同时使用ActionListener 控制。

如何使用 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. 明确区分模型、视图和控制器(在您的情况下主要是在视图和控制器之间)。
  2. 用对应的控制器注册每个视图的组件,并模块化管理它们的行为。
  3. 一旦可以管理每个组件,请查看文档中有关如何管理单选按钮、按钮或其他任何内容的示例,并采取相应措施以使代码适应您的需求。

这是一个很长的答案,解释的比你要求的要多,但是你的代码是一团糟,对于这个项目和未来的项目,你最好实现某种设计模式,这样代码对你来说是清楚的(甚至如果您在一段时间后没有继续工作就回来)并且对其他人很清楚,以便他们可以轻松地提供帮助。

作为结论,您的问题并不复杂,但是您当前的结构使其复杂化。把它清理一下,你会管理的。

【讨论】:

  • 非常感谢。感谢您花时间给我这么长而明确的答案。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 2021-11-10
相关资源
最近更新 更多