2016-03-15 67 views
0

我试图根据用户点击的内容来绘制特定的形状。程序中的其他方法都可以正常工作。 这里是目前显示的内容的图片: This is the picture为什么我的形状不能在JFrame上绘制?

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

您一直在创建'DrawShapes'的新实例,其中一些不添加到UI中,而您添加的那些实例会显示当前内容,而这些内容只会以乱七八糟的方式结束。更好地创建一个'DrawShapes'的实例并添加它,然后更改其属性 – MadProgrammer

+0

这解决了一半的问题,另一部分是我搞砸了逻辑,你应该能够绘制只有当ableToDraw == false意味着没有选择“不能绘制”的按钮。这是我的错误命名。 –

回答

2

我猜问题是,所以没有什么画不重写你的DrawShapes类的getPreferredSize()方法。因此,您需要覆盖getPreferredSize()以返回形状的实际大小,对于您的椭圆和(x + 15,y + 15)矩形,您的情况看起来像是(x + 30,y + 15)。

你真的应该为矩形和椭圆分开类。使用if/else语句不是一个好的设计,并且如果您决定添加一个“三角形”形状,则逻辑变得复杂得多,这不是很灵活。

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

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

另一种选择是不使用真实的组件,而只是将形状绘制到面板上。请查阅Custom Painting Approaches查看增量绘画的两种常用方法的示例。它显示了两种不同的方式来完成这个取决于你的确切要求。

这些示例显示如何添加矩形,然后单击/拖动鼠标。所以你需要修改代码来支持不同类型的Shapes。

0

首先,我必须创建drawShapes类的单个实例,如其他用户所述。然后,另一部分是我搞砸了逻辑,你应该只能够绘制当ableToDraw ==假意味着按钮说“不能绘制”没有被选中。这是我的错误命名。一旦完成,代码工作正常。

相关问题