2016-04-29 6 views
0

Сначала это будет немного больше, потому что я хочу, чтобы показать весь код, я не сделал до сих пор, так что извините ..Я пытаюсь использовать метод перерисовки после paintComponent, но его не работает

Это мой первый время в java. Я пытаюсь построить аквариум с рисунком рыбы и медуз и использовать нитки. Когда я пытаюсь добавить животное, я хочу его нарисовать, но безуспешно, я построил метод PaintComponent, но когда я пытаюсь использовать repaint, я не могу рисовать .. Что мне не хватает?

Похоже на то, когда я нажимаю на Add открывает окно для животных, я выбираю значение и после того, как я нажимаю КИ, необходимо обратить животное

enter image description here

Я надеюсь, что все остальное, что я все было хорошо .. большое вам спасибо за помощь!

paintComponent и repaint находится на AquaPanel Класс.

public class AquaFrame extends JFrame { 

    private AquaPanel mPanel; 
    private JLabel label1; 
    private ImageIcon icon; 
    private BufferedImage imag; 

    public AquaFrame() { 
     super("my Aquarium"); 
     setLayout(new BorderLayout()); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(700, 600); 
     setResizable(false); 
     setVisible(true); 
     setLocationRelativeTo(null); 

     mPanel = new AquaPanel(getGraphics()); 
     add(mPanel); 
    } 

    public void buildFrame(){ 
     JMenuBar menuBar = new JMenuBar(); 
     setJMenuBar(menuBar); 

     JMenu file = new JMenu("File"); 
     menuBar.add(file); 
     JMenuItem exItem = new JMenuItem("Exit"); 
     file.add(exItem); 
     exItem.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 
      } 
     }); 

     JMenu background = new JMenu("Background"); 
     menuBar.add(background); 
     JMenuItem blue = new JMenuItem("Blue"); 
     blue.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       mPanel.setBackground(Color.BLUE); 
      } 
     }); 

     JMenuItem none = new JMenuItem("None"); 
     none.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       mPanel.setBackground(null); 
      } 
     }); 

     JMenuItem image = new JMenuItem("Image"); 
     image.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       try { 
        imag = ImageIO.read(new File("aquarium_background.jpg")); 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      } 
     }); 

     background.add(image); 
     background.add(blue); 
     background.add(none); 

     JMenu help = new JMenu("Help"); 
     JMenuItem helpItem = new JMenuItem("help"); 
     helpItem.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JOptionPane.showMessageDialog(null,"GUI @ Threads"); 
      } 
     }); 

     menuBar.add(help); 
     help.add(helpItem); 

     setVisible(true); 
    } 

    public void paint(Graphics g){ 
     g.drawImage(imag, 0, 0, null); 
    } 

    public static void main(String[] args) {   
     AquaFrame mFrame = new AquaFrame(); 
     mFrame.buildFrame(); 
    } 

} 


/******************************************/ 
public class AquaPanel extends JPanel { 

    private JFrame infoTableFrame; 
    private JTable infoTable; 
    private Set<Swimmable > swimmables = new HashSet<Swimmable>(); 
    private AddAnimalDialog animalDialog; 
    private int totalEatCounter; 
    private Graphics g; 

    public AquaPanel(Graphics g) { 
     this.g = g; 
     totalEatCounter = 0; 
     infoTableFrame = new JFrame(); 
     infoTableFrame.setVisible(false); 

     setLayout(new GridBagLayout()); 

     GridBagConstraints constraints = new GridBagConstraints(); 
     constraints.anchor = GridBagConstraints.PAGE_END; 
     constraints.weighty = 1; 

     JButton btAdd = new JButton("Add Animal"); 
     btAdd.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (swimmables.size() >= 5) 
       { 
        JOptionPane.showMessageDialog(null, "You can't have more than 5 animals at the same time."); 
       } 
       else 
       { 
        animalDialog = new AddAnimalDialog(AquaPanel.this); 
        animalDialog.setVisible(true); 
       } 
      } 
     }); 

     JButton btSleep = new JButton("Sleep"); 
     btSleep.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Swimmable swimmable : swimmables) 
       { 
        swimmable.setSuspend(); 
       } 
      } 
     }); 

     JButton btWakeup = new JButton("Wake Up"); 
     btWakeup.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Swimmable swimmable : swimmables) 
       { 
        swimmable.setResume(); 
       } 
      } 
     }); 

     JButton btRst = new JButton("Reset"); 
     btRst.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Swimmable swimmable : swimmables) 
       { 
        swimmable.kill(); 
       } 
       swimmables.clear(); 
      } 
     }); 

     JButton btFood = new JButton("Food"); 
     btFood.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (swimmables.size() > 0) 
       { 
        CyclicBarrier barrier = new CyclicBarrier(swimmables.size()); 
        for (Swimmable swimmable : swimmables) 
        { 
         swimmable.setBarrier(barrier); 
         swimmable.setFood(true); 
        } 
        Graphics2D g2 = (Graphics2D) g; 
        g2.setStroke(new BasicStroke(3)); 
        g2.setColor(Color.red); 
        g2.drawArc(getWidth()/2, getHeight()/2 - 5, 10, 10, 30, 210); 
        g2.drawArc(getWidth()/2, getHeight()/2+5, 10, 10, 180, 270); 
        g2.setStroke(new BasicStroke(1)); 
       } 
      } 
     }); 

     JButton btInfo = new JButton("Info"); 
     btInfo.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
        showInfoTable(); 
      } 
     }); 

     JButton btExit = new JButton("Exit"); 
     btExit.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 
      } 
     }); 

     add(btAdd,constraints); 
     add(btSleep,constraints); 
     add(btWakeup,constraints); 
     add(btRst,constraints); 
     add(btFood,constraints); 
     add(btInfo,constraints); 
     add(btExit,constraints); 
    } 

    public void showInfoTable(){ 
     if (infoTableFrame.isVisible()) 
     { 
      infoTableFrame.remove(infoTable); 
      infoTableFrame.setVisible(false); 
     } 
     else 
     { 
      String[] col = {"Animal","Color","Size","Hor.speed","Ver.speed","Eat counter"}; 
      String[][] data = new String[swimmables.size()][col.length]; 
      int i=0; 
      for (Swimmable swimmable : swimmables) 
      { 
       data[i][0] = swimmable.getAnimalName(); 
       data[i][1] = swimmable.getColor(); 
       data[i][2] = "" + swimmable.getSize(); 
       data[i][3] = "" + swimmable.getHorSpeed(); 
       data[i][4] = "" + swimmable.getVerSpeed(); 
       data[i][5] = "" + swimmable.getEatCount(); 
       ++i; 
      } 
      infoTable = new JTable(data, col); 

      //TODO - not overriding values 

      JScrollPane jPane = new JScrollPane(infoTable); 
      infoTableFrame.add(jPane, BorderLayout.CENTER); 
      infoTableFrame.setSize(300, 150); 
      infoTableFrame.setVisible(true); 
     } 
    } 

    public void addAnimal(Swimmable animal) 
    { 
     animal.setAquaPanel(this); 
     swimmables.add(animal); 
     animal.run(); 
     //myrepaint(); 
    /**********************************/  
     repaint(); 
    /**********************************/ 
    } 


    public void onEatFood(Swimmable eater) 
    { 
     eater.eatInc(); 
     ++totalEatCounter; 
     for (Swimmable swimmable : swimmables) 
     { 
      swimmable.setFood(false); 
     } 
    } 

    /*public void myrepaint() 
    { 
     for (Swimmable swimmable : swimmables) 
     { 
      swimmable.drawAnimal(g); 
     } 
    }*/ 

    /************************************************/ 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (Swimmable swimmable : swimmables) 
     { 
      swimmable.drawAnimal(g); 
     } 
    } 
    /*********************************************/ 
} 



public abstract class Swimmable extends Thread { 

    protected AquaPanel aquaPanel; 
    protected boolean isFood; 
    protected boolean isSuspended; 
    protected int horSpeed; 
    protected int verSpeed; 
    protected int x_dir, y_dir; 
    protected int eatCount; 
    protected CyclicBarrier barrier; 
    protected int x0, y0; 

    protected boolean isAlive; 

    public Swimmable() { 
     horSpeed = 0; 
     verSpeed = 0; 
     x_dir = 1; 
     y_dir = 1; 
     eatCount = 0; 
    } 

    public Swimmable(int hor, int ver) { 
     horSpeed = hor; 
     verSpeed = ver; 
     x_dir = 1; 
     y_dir = 1; 
     eatCount = 0; 
    } 

    @Override 
    public void run() { 
     isAlive = true; 
     while (isAlive) { 
      try { 
       sleep(10); 
       if (isSuspended) 
       { 
        wait(); 
       } 
       else 
       { 
        if (isFood) 
        { 
         barrier.await(); 
         updateFrontsTowardsFood(); 
         if (isNearFood()) 
         { 
          aquaPanel.onEatFood(this); 
         } 
        } 
        else 
        { 
         updateFronts(); 
        } 
        //aquaPanel.myrepaint(); 
        aquaPanel.repaint(); 
       } 
      } 
      catch (Exception e) 
      { 
       //TODO - handle exception 
      } 

     } 
    } 

    public void kill() 
    { 
     isAlive = false; 
    } 

    public int getHorSpeed() { 
     return horSpeed; 
    } 

    public int getVerSpeed() { 
     return verSpeed; 
    } 

    public void setHorSpeed(int hor) { 
     horSpeed = hor; 
    } 

    public void setVerSpeed(int ver) { 
     verSpeed = ver; 
    } 

    abstract public int getSize(); 

    abstract public String getColor(); 

    public void setSuspend() 
    { 
     isSuspended = true; 
    } 

    public void setResume() 
    { 
     isSuspended = false; 
    } 

    public void eatInc() 
    { 
     ++eatCount; 
    } 

    public int getEatCount() 
    { 
     return eatCount; 
    } 

    public void setBarrier(CyclicBarrier b) 
    { 
     barrier = b; 
    } 

    public void setFood(boolean isFood) 
    { 
     this.isFood = isFood; 
    } 

    public void setAquaPanel(AquaPanel panel) 
    { 
     aquaPanel = panel; 
     x0 = aquaPanel.getWidth()/2; 
     y0 = aquaPanel.getHeight()/2; 
    } 

    abstract public String getAnimalName(); 

    abstract public void drawAnimal(Graphics g); 

    abstract protected void updateFronts(); 
    abstract protected void updateFrontsTowardsFood(); 

    abstract protected boolean isNearFood(); 
} 



public class Fish extends Swimmable { 

    protected int x_front , y_front; 
    private int size; 
    private Color color; 

    public Fish(Color col, int sz, int hor, int ver) { 
     super(hor, ver); 
     size = sz; 
     color = col; 
     x_front = 0; 
     y_front = 0; 
    } 

    public void drawAnimal(Graphics g) { 

     g.setColor(color); 
     if (x_dir == 1) // fish swims to right side 
     { 
      // Body of fish 
      g.fillOval(x_front - size, y_front - size/4, size, size/2); 

      // Tail of fish 
      int[] x_t = { x_front - size - size/4, x_front - size - size/4, x_front - size }; 
      int[] y_t = { y_front - size/4, y_front + size/4, y_front }; 
      Polygon t = new Polygon(x_t, y_t, 3); 
      g.fillPolygon(t); 

      // Eye of fish 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setColor(new Color(255 - color.getRed(),255 - color.getGreen(),255- color .getBlue())); 
      g2.fillOval(x_front-size/5, y_front-size/10, size/10, size/10); 

      //Mouth of fish 
      if(size>70) 
       g2.setStroke(new BasicStroke(3)); 
      else if(size>30) 
       g2.setStroke(new BasicStroke(2)); 
      else 
       g2.setStroke(new BasicStroke(1)); 

      g2.drawLine(x_front, y_front, x_front-size/10, y_front+size/10); 
      g2.setStroke(new BasicStroke(1)); 
     } 

     else // fish swims to left side 
     { 
      // Body of fish 
      g.fillOval(x_front, y_front - size/4, size, size/2); 

      // Tail of fish 
      int[] x_t = { x_front + size + size/4, x_front + size + size/4, x_front + size }; 
      int[] y_t = { y_front - size/4, y_front + size/4, y_front }; 
      Polygon t = new Polygon(x_t, y_t, 3); 
      g.fillPolygon(t); 

      // Eye of fish 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setColor(new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue())); 
      g2.fillOval(x_front+size/10, y_front-size/10, size/10, size/10); 

      // Mouth of fish 
      if (size > 70) 
       g2.setStroke(new BasicStroke(3)); 
      else if (size > 30) 
       g2.setStroke(new BasicStroke(2)); 
      else 
       g2.setStroke(new BasicStroke(1)); 
      g2.drawLine(x_front, y_front, x_front + size/10, y_front + size/10); 
      g2.setStroke(new BasicStroke(1)); 
     } 

    } 

    public String getAnimalName() { 
     return "Fish"; 
    } 

    public int getSize() { 
     return size; 
    } 

    public String getColor() { 
     if (color == Color.RED) 
      return "RED"; 
     else if (color == Color.GREEN) 
      return "GREEN"; 
     else if (color == Color.ORANGE) 
      return "ORANGE"; 
     else 
      return "UNKNOWN"; 
    } 

    protected void updateFronts() 
    { 
     x_front += x_dir * horSpeed; 
     y_front += y_dir * verSpeed; 
     if (x_front > x0*2 || x_front < 0) 
      x_dir *= -1; 
     if (y_front > y0*2 || y_front < 0) 
      y_dir *= -1; 
    } 

    protected void updateFrontsTowardsFood() 
    { 
     //TODO - copy from word 
    } 

    protected boolean isNearFood() 
    { 
     return ((Math.abs(x_front-x0) <= 5) && (Math.abs(y_front-y0) <= 5)); 
    } 

} 



public class Jellyfish extends Swimmable { 

    private int x_front , y_front; 
    private int size; 
    private Color color; 

    public Jellyfish(Color col, int sz, int hor, int ver) { 
     super(hor, ver); 
     size = sz; 
     color = col; 
     x_front = 0; 
     y_front = 0; 
    } 

    public void drawAnimal(Graphics g) { 
     int numLegs; 
     if (size < 40) 
      numLegs = 5; 
     else if (size < 80) 
      numLegs = 9; 
     else 
      numLegs = 12; 
     g.setColor(color); 
     g.fillArc(x_front - size/2, y_front - size/4, size, size/2, 0, 180); 
     for (int i = 0; i < numLegs; i++) 
      g.drawLine(x_front - size/2 + size/numLegs + size * i/(numLegs + 1), y_front, 
        x_front - size/2 + size/numLegs + size * i/(numLegs + 1), y_front + size/3); 
    } 


    public String getAnimalName() { 
     return "Jellyfish"; 
    } 

    public int getSize() { 
     return size; 
    } 

    public String getColor() { 
     if (color == Color.RED) 
      return "RED"; 
     else if (color == Color.GREEN) 
      return "GREEN"; 
     else if (color == Color.ORANGE) 
      return "ORANGE"; 
     else 
      return "UNKNOWN"; 
    } 

    public void updateFronts() 
    { 
     x_front += x_dir * horSpeed; 
     y_front += y_dir * verSpeed; 
     if (x_front > x0*2 || x_front < 0) 
      x_dir *= -1; 
     if (y_front > y0*2 || y_front < 0) 
      y_dir *= -1; 
    } 

    protected void updateFrontsTowardsFood() 
    { 
     //TODO - copy from word 
    } 

    protected boolean isNearFood() 
    { 
     return ((Math.abs(x_front-x0) <= 5) && (Math.abs(y_front-y0) <= 5)); 
    } 
} 



public class AddAnimalDialog extends JDialog { 

    private JButton btOk, btCancel; 
    private JTextField tfSize, tfHspeed, tfVspeed; 
    private ButtonGroup groupType, groupColor; 
    private JRadioButton rbFish, rbJellyfish, rbRed, rbGreen, rbOrange; 
    JPanel panel; 

    public AddAnimalDialog(AquaPanel aquaPanel) { 
     this.setLayout(new FlowLayout()); 
     panel = new JPanel(); 
     panel.setLayout(new GridLayout(10, 20)); 
     panel.add(new JLabel("Size(20-320): ")); 
     panel.add(tfSize = new JTextField()); 
     panel.add(new JLabel("Horizontal speed(1-10): ")); 
     panel.add(tfHspeed = new JTextField()); 
     panel.add(new JLabel("Vertical speed(1-10): ")); 
     panel.add(tfVspeed = new JTextField()); 
     panel.add(new JLabel("Type: ")); 
     panel.add(new JLabel("      ")); 
     panel.add(rbFish = new JRadioButton("fish")); 
     panel.add(rbJellyfish = new JRadioButton("jellyfish")); 
     panel.add(new JLabel("Color: ")); 
     panel.add(new JLabel("      ")); 
     panel.add(rbRed = new JRadioButton("Red")); 
     panel.add(rbGreen = new JRadioButton("Green")); 
     panel.add(rbOrange = new JRadioButton("Orange")); 

     // Group the radio buttons. 
     groupType = new ButtonGroup(); 
     groupType.add(rbFish); 
     groupType.add(rbJellyfish); 
     rbFish.setSelected(true); 
     groupColor = new ButtonGroup(); 
     groupColor.add(rbRed); 
     groupColor.add(rbGreen); 
     groupColor.add(rbOrange); 
     rbRed.setSelected(true); 
     panel.add(new JLabel("")); 
     panel.add(btOk = new JButton("OK")); 
     panel.add(btCancel = new JButton("Cancel")); 
     this.add(panel); 
     this.setLocationRelativeTo(null); 
     this.setResizable(false); 
     this.pack(); 

     this.btOk.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       try { 
        int size = Integer.parseInt(tfSize.getText()); 
        int hSpeed = Integer.parseInt(tfHspeed.getText()); 
        int vSpeed = Integer.parseInt(tfVspeed.getText()); 

        if (checkValues(size, hSpeed, vSpeed)) { 
         Color clr = Color.RED; 
         if (rbRed.isSelected()) { 
          clr = Color.RED; 
         } else if (rbGreen.isSelected()) { 
          clr = Color.GREEN; 
         } else if (rbOrange.isSelected()) { 
          clr = Color.ORANGE; 
         } else { 
          JOptionPane.showMessageDialog(null, "You must choose a color!"); 
         } 

         if (rbFish.isSelected()) { 
          setVisible(false); 
          aquaPanel.addAnimal(new Fish(clr, size, hSpeed, vSpeed)); 
         } else if (rbJellyfish.isSelected()) { 
          setVisible(false); 
          aquaPanel.addAnimal(new Jellyfish(clr, size, hSpeed, vSpeed)); 
         } else { 
          JOptionPane.showMessageDialog(null, "You must choose animal type!"); 
         } 
        } 
       } catch (NumberFormatException e) { 
        JOptionPane.showMessageDialog(null, "One of the number values has wrong format, please check it"); 
       } 
      } 
     }); 
     this.btCancel.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       setVisible(false); 
       System.out.println("Click the Close button if you want to stop adding windows"); 
      } 
     }); 
    } 

    private boolean checkValues(int size, int hspeed, int vspeed) { 
     if ((size > 320 || size < 20) || (hspeed < 1 || hspeed > 10) || (vspeed < 1 || vspeed > 10)) { 
      JOptionPane.showMessageDialog(null, "One of the values is out of bounds, please follow the restrictions."); 
      return false; 
     } 
     return true; 
    } 

} 
+0

'GetGraphics()' НЕ является тем, как делается живопись, вместо этого вы должны переопределить метод 'paintComponent'' AquaPanel' и нарисовать текущее состояние компонента с помощью контекста «Graphics», который передается ему – MadProgrammer

+0

Swing также не является потокобезопасным, все обновления пользовательского интерфейса должны быть сделаны из контекста потока Dispatching Event, см. [Concurrency in Java] (http://docs.oracle.com/javase/tutorial/essential/co ncurrency /) для получения дополнительной информации – MadProgrammer

+0

Как я могу сделать переопределение и краску[email protected] – gogo

ответ

0

Попробуйте переписать в свой класс JFrame после вызова метода AddAnimal. Существует также перепроверить() метод там, а также и их разность в этой статье: Java Swing revalidate() vs repaint()

+0

Вы можете сказать мне, где звонить в точку? – gogo

1

Есть целый ряд основных проблем ...

Основная проблема связана с Swimmablerun метода, он является блокируя Event Dispatching Thread, не позволяя ему реагировать на события пользовательского интерфейса, включая события перерисовки. См. Concurrency in Java для более подробной информации.

Вы НИКОГДА не должны использовать getGraphics, кроме как можно вернуть null, все, что вы нарисовываете, окрашивается за пределы обычного цикла краски и будет окрашиваться в следующий раз, когда компонент перекрашивается. См. Painting in AWT and Swing и Performing Custom Painting для более подробной информации.

Ваш текущий подход не будет хорошо масштабироваться, чем больше рыбы вы добавите, тем больше ресурсов они будут потреблять и повлияет на способность программы идти в ногу со всеми различными изменениями и перерисовывать запросы.

Лучшим решением было бы иметь один цикл обновления, который заботится о том, чтобы сообщать каждому из Swimmable s, что ему необходимо обновить, а затем расписание одного repaint каждого цикла. Лично я бы начал с Swing Timer, поскольку он «тикает» в пределах EDT, что делает его намного более безопасным для изменения состояния объектов, которым нужен метод paintComponent.

См How to use Swing Timers для более подробной информации

я предложил бы иметь взглянуть на this, который в основном описывает то, что вы пытаетесь сделать, и то, что я предлагаю, вы должны сделать вместо

+0

Спасибо! теперь это работа, но я нашел еще одну проблему в Food Button. Это факт должен показать мне немного еды в середине, вы можете понять, почему это не работает, пожалуйста? Это в AquaPanel @MadProgrammer – gogo

+0

То, как вы показываете пищу, - это то же самое, что вы показываете Swimable's – MadProgrammer

 Смежные вопросы

  • Нет связанных вопросов^_^