简体   繁体   中英

Java application creating Rectangle when button is pressed

The intention of my code is to create a rectangle when the button is clicked. The button works fine but the rectangle itself is not showing up on the screen, and there are no errors. Thank you for helping btw.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Tester {

static JButton button;
static JFrame frame;
static JPanel panel;
static Rectangle rec;

static void init(){
    button = new JButton();
    frame = new JFrame();
    panel = new JPanel();
    rec = new Rectangle(30,30,30,30);

    button.setVisible(true);
    panel.add(button);
    frame.add(panel);
    frame.setVisible(true);
    panel.setVisible(true);
   frame.setSize(200, 200); 
    button.setBackground(Color.GREEN);
    button.setBounds(30, 30, 20, 20);

}

public static void main(String[] args) {
    init();
    ActionListener listener = new RectangleMover();
    button.addActionListener(listener);
}

static class RectangleMover implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent arg0) {
        RectanglePainter r = new RectanglePainter();
        r.add(rec);
    }

}

static class RectanglePainter extends JPanel{

     void add(Rectangle r){
    rec = r;
    repaint();
    }

    protected void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        Random r = new Random();
        int i =r.nextInt(2);
        if (i==1)
        g2.setColor(Color.BLUE);
        else 
        g2.setColor(Color.RED); 
        g2.fill(rec);
        g2.draw(rec);
    }

}

}

Your generally approach is slightly skewed, rather than using another JComponent to "act" as the shape, you should be using it to paint all the shapes through it's paintComponent method

From my "red rectangle" period...

红色矩形

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Tester {

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

    public Tester() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel panel;
        private JButton button;
        private JLabel label;
        private ShapePane shapePane;

        public TestPane() {
            setLayout(new BorderLayout());
            button = new JButton("Rectangle");
            panel = new JPanel();
            label = new JLabel();

            button.setVisible(true);
            panel.add(button);
            panel.add(label);

            shapePane = new ShapePane();

            add(shapePane);
            add(panel, BorderLayout.SOUTH);

            class ClickListener implements ActionListener {

                private int X = 20;
                private int Y = 20;

                @Override
                public void actionPerformed(ActionEvent arg0) {
                    int width = shapePane.getWidth();
                    int height = shapePane.getHeight();

                    int x = (int)(Math.random() * (width - 20)) + 10;
                    int y = (int)(Math.random() * (height - 20)) + 10;

                    int w = (int)(Math.random() * (width - x));
                    int h = (int)(Math.random() * (height - y));

                    shapePane.add(new Rectangle(x, y, w, h));
                }

            }
            ActionListener listener = new ClickListener();
            button.addActionListener(listener);
        }

    }

    public class ShapePane extends JPanel {

        private List<Shape> shapes;

        public ShapePane() {
            shapes = new ArrayList<>(25);
        }

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

        public void add(Rectangle rectangle) {
            shapes.add(rectangle);
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.RED);
            for (Shape shape : shapes) {
                g2.draw(shape);
            }
        }
    }
}

As to answer your basic question, you could have tried calling revalidate and repaint , but because of the BorderLayout I doubt it would have worked as you would have basically been trying to replace the panel with your ShapeChanger component, and there are better ways to do that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM