为什么我的形状不会在JFrame上绘制?

时间:2016-03-15 04:23:35

标签: java swing draw

我正在尝试根据用户点击的内容来绘制特定的形状。程序中的每个其他方法都运行正常。 这是目前显示的图片: This is the picture

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

import java.awt.*;
import java.awt.event.*;

public class Gui3 extends JFrame {
    private JPanel mousepanel;
    private JLabel statusbar;
    private JList list;
    private static String[] colornames = {"black","blue","red","white"};
    private static Color[] colors = {Color.BLACK, Color.BLUE,Color.RED,Color.WHITE};
    private JCheckBox cb;
    private JCheckBox rect;
    private JCheckBox oval;
    private JCheckBox drawBox;
    private boolean changeColor = true;
    private boolean ableToDraw = true;

    public Gui3(){
        super("The title");

        list = new JList(colornames);
        list.setVisibleRowCount(4);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setFixedCellHeight(15);
        list.setFixedCellWidth(100);
        add(new JScrollPane(list), BorderLayout.WEST);
        list.addListSelectionListener(
                new ListSelectionListener(){
                    public void valueChanged(ListSelectionEvent event){
                        if(changeColor==true){
                        mousepanel.setBackground(colors[list.getSelectedIndex()]);
                        }
                        else{

                        }
                    }
                }
            );
        rect= new JCheckBox("Draw a rectangle");
        oval= new JCheckBox("Draw a oval");
        cb = new JCheckBox("Not able to change the color");
        drawBox = new JCheckBox("Not able to draw shapes");
        mousepanel = new JPanel();
        mousepanel.setBackground(Color.WHITE);
        add(mousepanel, BorderLayout.CENTER);
        add(drawBox, BorderLayout.EAST);
        add(cb, BorderLayout.NORTH);
        mousepanel.add(rect,BorderLayout.EAST);
        mousepanel.add(oval,BorderLayout.WEST);


        statusbar = new JLabel("Default");
        add(statusbar, BorderLayout.SOUTH); 


        HandlerClass handler = new HandlerClass();
        mousepanel.addMouseListener(handler);
        mousepanel.addMouseMotionListener(handler);
        cb.addItemListener(handler);
        drawBox.addItemListener(handler);
    }   
    private class HandlerClass implements MouseListener, MouseMotionListener,ItemListener
        {
        @Override
        public void mouseClicked(MouseEvent event) {
            statusbar.setText(String.format("Clicked at %d, %d", event.getX(),event.getY()));

这是选择的内容用于决定绘制的内容。它的工作原理是将参数传递给一个方法是drawShape类;如下所示。

if(ableToDraw==true){
                if(rect.isSelected()&&oval.isSelected()){
                    DrawShapes shapes = new DrawShapes();
                    shapes.whatToDraw(false,false);
                        }
                    }
                else if(rect.isSelected()){
                    DrawShapes shapes = new DrawShapes();
                    shapes.whatToDraw(true, false);
                    shapes.setPosition(event.getX(), event.getY());
                    add(shapes);

                }
                else if(oval.isSelected()){
                    DrawShapes shapes = new DrawShapes();
                    shapes.whatToDraw(false, true);
                    shapes.setPosition(event.getX(), event.getY());
                    add(shapes);
                }
                else{
                    DrawShapes shapes = new DrawShapes();
                    shapes.whatToDraw(false,false);
                }
            }
            @Override
            public void mousePressed(MouseEvent event){
                statusbar.setText("You pressed down the mouse");
            }

            @Override
            public void mouseReleased(MouseEvent event){
                statusbar.setText("You released the button");
            }
            @Override
            public void mouseEntered(MouseEvent event){
                statusbar.setText("You entered the area");

            }
            @Override
            public void mouseExited(MouseEvent event){
                statusbar.setText("The mouse has left the window");

            }
            //These are mouse motion events
            @Override
            public void mouseDragged(MouseEvent event){
                statusbar.setText("You are dragging the mouse");
            }
            @Override
            public void mouseMoved(MouseEvent event){
                statusbar.setText("You are moving the mouse");
            }
            @Override
            public void itemStateChanged(ItemEvent event){
                if(cb.isSelected()){
                    changeColor=false;
                }
                else{
                    changeColor=true;
                }
                if(drawBox.isSelected()){
                    ableToDraw=false;
                }
                else{
                    ableToDraw=true;
                }
            }

        }
    }

这是drawShapes类

  import java.awt.*;
    import javax.swing.*;
    public class DrawShapes extends JPanel {
        private int x,y;
        private boolean ovals,rects;
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            if(ovals==false&&rects==true){
            g.setColor(Color.BLUE);
            g.fillRect(x,y,15,15);}
            else if(ovals==true&&rects==false){
                g.setColor(Color.BLUE);
                g.fillOval(x, y, 30, 15);
            }
            else{

            }
        }
        public void setPosition(int newX, int newY) {
            this.x = newX;
            this.y = newY;
            repaint();
        }

            public void whatToDraw(boolean newrects, boolean newovals){
                this.ovals=newovals;
                this.rects=newrects;
                repaint();


        }
    }

2 个答案:

答案 0 :(得分:2)

我猜想问题是你没有覆盖DrawShapes类的getPreferredSize()方法,因此没有任何东西可以绘制。因此,您需要覆盖getPreferredSize()以返回形状的实际大小,在您的情况下,您的椭圆和(x + 15,y + 15)矩形看起来是(x + 30,y + 15) 。

你真的应该有矩形和椭圆形的单独类。使用if / else语句不是一个好的设计,如果你决定添加一个“三角形”形状,因为你的逻辑变得更加复杂,那么它不是很灵活。

然而即使你这样做也不会得到你所期望的,因为我猜你将DrawShapes组件添加到一个默认情况下使用FlowLayout的面板。因此,您的形状将仅显示在面板上的一行中,而不是您在面板上单击的位置。

如果希望组件出现在单击的位置,则需要将椭圆组件的大小设置为(30,15),将组件的位置设置为(x,y)。然后在(0,0)处完成形状的绘制,因此绘画相对于组件而不是面板。然后,您需要将面板的布局设置为null,以便您可以根据其位置手动定位每个形状。

另一个选择是不使用真实组件,而只是将形状绘制到面板上。查看Custom Painting Approaches以了解增量绘画的两种常用方法的示例。它根据您的具体要求显示了两种不同的方法。

示例显示如何添加矩形并单击/拖动鼠标。因此,您需要修改代码以支持不同类型的形状。

答案 1 :(得分:0)

首先,我必须创建一个drawShapes类的实例,如另一个用户所述。然后另一部分是我弄乱了逻辑,你应该能够只在ableToDraw == false时绘制,这意味着没有选择“无法绘制”的按钮。这对我来说很糟糕。一旦完成,代码就可以正常工作。

相关问题