在Java GUI中从用户JList选择形状中绘制随机大小的形状

时间:2018-07-30 22:14:05

标签: java swing jlist listselectionlistener

我必须在Java GUI中生成随机大小的形状(50到300像素)。用户可以从JList中选择3种形状(矩形,正方形,圆形),当他们选择一个JList时,GUI中应显示随机大小的矩形,正方形或圆形。

我想我只是在弄清楚在何处以及如何实现列表选择监听器方面遇到困难。

到目前为止,这是我的代码:

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;

public class ShapeSelectionWindow extends JPanel implements ListSelectionListener{

    public void paintComponent(Graphics g) {
        int x, y, width, height;
        super.paintComponent(g);

        width = (int)Math.floor(Math.random()*250) + 50;
        height = (int)Math.floor(Math.random()*250) + 50;
        x = (int)Math.floor((615 - width) / 2);
        y = (int)Math.floor((661 - height) / 2);

        g.fillRect(x, y, width, height);
    }

    public static void main(String[] args) {
        ShapeSelectionWindow ssw = new ShapeSelectionWindow();
        JFrame jf = new JFrame();
        JPanel shapeListPanel = new JPanel();
        shapeListPanel.setBackground(Color.WHITE);
        DefaultListModel<String> dlm = new DefaultListModel<String>();
        dlm.addElement("Rectangle");
        dlm.addElement("Square");
        dlm.addElement("Circle");
        JList<String> shapeList = new JList<String>(dlm);
        shapeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        shapeListPanel.add(shapeList);

        jf.getContentPane().setLayout(new BorderLayout());
        jf.getContentPane().add(ssw, BorderLayout.CENTER);
        jf.getContentPane().add(shapeListPanel, BorderLayout.EAST);
        jf.setTitle("Simple Drawing GUI");
        jf.setSize(700, 700);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {
        // TODO Auto-generated method stub

    }
}

当前的paintComponent方法用于绘制矩形。就像我说的那样,我不确定如何为该项目实现列表选择侦听器,以便根据用户的选择生成不同的形状。

1 个答案:

答案 0 :(得分:0)

您目前的做法是在一个篮子里放太多鸡蛋。 ShapeSelectionWindow为什么要负责管理JList?唯一的责任是绘制随机形状。

相反,您应该分解设计。

我将从定义一个简单的“形状”实体开始...

public enum Shape {
    RECTANGLE("Rectangle"), SQUARE("Square"), CIRCLE("Circle");

    private String name;

    private Shape(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return getName();
    }

}

这只是提供了一组可以使用的限制选项。

然后我将更新“形状窗格”以支持这些选项...

public class ShapePane extends JPanel {

    private Shape shape;

    public void setShape(Shape shape) {
        this.shape = shape;
        repaint();
    }

    public Shape getShape() {
        return shape;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(800, 800);
    }

    public void paintComponent(Graphics g) {
        int x, y, width, height;
        super.paintComponent(g);
        Shape shape = getShape();
        if (shape == null) {
            return;
        }

        width = (int) Math.floor(Math.random() * 250) + 50;
        height = (int) Math.floor(Math.random() * 250) + 50;
        x = (int) Math.floor((615 - width) / 2);
        y = (int) Math.floor((661 - height) / 2);

        switch (shape) {
            case RECTANGLE:
                g.fillRect(x, y, width, height);
                break;
            case SQUARE:
                break;
            case CIRCLE:
                break;
        }
    }
}

ShapePane并不在乎Shape的“指定方式”,它只关心它何时更改并想要绘制

然后,我将使用另一个组件充当JListShapePane ...之间的主要控制器。

public class MainPane extends JPanel {

    private JList<Shape> list;
    private ShapePane shapePane;

    public MainPane() {
        setLayout(new BorderLayout());

        DefaultListModel<Shape> model = new DefaultListModel<>();
        model.addElement(Shape.SQUARE);
        model.addElement(Shape.RECTANGLE);
        model.addElement(Shape.CIRCLE);

        shapePane = new ShapePane();

        list = new JList<Shape>(model);
        list.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                Shape shape = list.getSelectedValue();
                shapePane.setShape(shape);
            }
        });

        add(list, BorderLayout.WEST);
        add(shapePane, BorderLayout.CENTER);
    }

}

可运行示例...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new MainPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public enum Shape {
        RECTANGLE("Rectangle"), SQUARE("Square"), CIRCLE("Circle");

        private String name;

        private Shape(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return getName();
        }

    }

    public class MainPane extends JPanel {

        private JList<Shape> list;
        private ShapePane shapePane;

        public MainPane() {
            setLayout(new BorderLayout());

            DefaultListModel<Shape> model = new DefaultListModel<>();
            model.addElement(Shape.SQUARE);
            model.addElement(Shape.RECTANGLE);
            model.addElement(Shape.CIRCLE);

            shapePane = new ShapePane();

            list = new JList<Shape>(model);
            list.addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    Shape shape = list.getSelectedValue();
                    shapePane.setShape(shape);
                }
            });

            add(list, BorderLayout.WEST);
            add(shapePane, BorderLayout.CENTER);
        }

    }

    public class ShapePane extends JPanel {

        private Shape shape;

        public void setShape(Shape shape) {
            this.shape = shape;
            repaint();
        }

        public Shape getShape() {
            return shape;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 800);
        }

        public void paintComponent(Graphics g) {
            int x, y, width, height;
            super.paintComponent(g);
            Shape shape = getShape();
            if (shape == null) {
                return;
            }

            width = (int) Math.floor(Math.random() * 250) + 50;
            height = (int) Math.floor(Math.random() * 250) + 50;
            x = (int) Math.floor((615 - width) / 2);
            y = (int) Math.floor((661 - height) / 2);

            switch (shape) {
                case RECTANGLE:
                    g.fillRect(x, y, width, height);
                    break;
                case SQUARE:
                    break;
                case CIRCLE:
                    break;
            }
        }
    }

}