2015-09-17 2 views
1

Мой код должен нарисовать изображение случайного размера три раза в случайных местах. По какой-то причине, когда я запускаю этот код с помощью BlueJ, все, что появляется, это серый экран. Я думаю, что это потому, что PaintComponent не называется, но я не совсем уверен. Что пошло не так с моим кодом и как я могу его исправить?PaintComponent не называется-Java

class PanelHolder extends JPanel{//class PanelHolder extends JPanel 
//variables 
public boolean threesharks; 
public int xcoord; 
public int ycoord; 
public int ratio; 
public Image i; 
public int w; 
public int h; 
public boolean background=true; 
Color water = new Color(136, 180, 231); 


public PanelHolder(){//constructor 

    i = Toolkit.getDefaultToolkit().getImage("$harkz.png"); 

} 
public void randomxy(){ 
    for(int x=0;x<3;x++){ 
     threesharks=true; 
     ycoord=(int)(Math.random()*300+200);//use math.random to figure out coordinates and sizing 
     xcoord=(int)(Math.random()*1000+0);//make a loop 
     ratio=(int)(Math.random()*5+1); 
     w=ratio*523; 
     h=ratio*195; 
     repaint(); 
     System.out.println("I'm in randomxy"); 

     //call repaint() each time 
     //after three times, make threesharks=false 
    } 
    threesharks=false; 
} 
public void paintComponent(Graphics g){ 
    if(threesharks){ 
     setBackground(water); 
     System.out.print("hi!"); 
     if(background){ 
      super.paintComponent(g);//set backgroun 
      background=false; 
     } 
     g.drawImage(i, xcoord, ycoord, w, h, this); 
    } 
    } 

}

+0

Вы всегда должны называть 'super.paintComponent', вы рискуете некоторыми неприятными артефактами красок, если вы их не делаете – MadProgrammer

+0

1) Чтобы лучше помочь, опубликуйте [MCVE] или [Short, Self Contained, Correct Example] (http : //www.sscce.org/). 2) Один из способов получить изображение (-ы) для примера - это горячая ссылка на изображения, видимые в [этом Q & A] (http://stackoverflow.com/q/19209650/418556). 3) См. [Обнаружение/исправление для подвесного закрывающего кронштейна кодового блока] (http://meta.stackexchange.com/q/251795/155831) для проблемы, которую я больше не мог беспокоить. –

+0

Когда вы называете 'randomxy'? – MadProgrammer

ответ

1

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

Картина в Swing является разрушительной, то есть каждый раз, когда вы вызываете свой метод paintComponent, вы должны перекрасить все состояние компонента с нуля, картина не является аккумулирующей.

Это означает, что вам нужно сохранить состояние вещей, которые вы хотите нарисовать каким-либо значимым образом, и повторное использование этих значений необходимо.

Посмотрите Painting in AWT and Swing и Performing Custom Painting для получения более подробной информации о том, как покрасочные работы в свинг

Random Ponies

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

    public Test() { 
     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 PanelHolder()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    class PanelHolder extends JPanel {//class PanelHolder extends JPanel 
//variables 

     public boolean threesharks; 
     public BufferedImage i; 
     public boolean background = true; 
     Color water = new Color(136, 180, 231); 

     private Point[] points; 
     private Image[] images; 

     public PanelHolder() { 
      //constructor 

      try { 
       i = ImageIO.read(...); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

      randomxy(); 
     } 

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

     public void randomxy() { 
      points = new Point[3]; 
      images = new Image[3]; 
      for (int x = 0; x < 3; x++) { 
       points[x] = new Point(); 

       double ratio = (Math.random() * 6d) + 0.1d; 
       int width = (int) (ratio * i.getWidth()); 
       int height = (int) (ratio * i.getHeight()); 
       points[x].y = Math.max(0, (int) (Math.random() * 800) - height);//use math.random to figure out coordinates and sizing 
       points[x].x = Math.max(0, (int) (Math.random() * 800) - width);//make a loop 

       images[x] = i.getScaledInstance(width, height, Image.SCALE_SMOOTH); 

      } 
     } 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g);//set backgroun 
      g.setColor(water); 
      g.fillRect(0, 0, getWidth(), getHeight()); 
      if (points != null && images != null) { 
       for (int index = 0; index < points.length; index++) { 
        g.drawImage(images[index], points[index].x, points[index].y, this); 
       } 
      } 
     } 
    } 

} 

Это грубый пример, который использует Image#getScaledInstance, который обычно не рекомендуется, но работает пример.

Посмотрите The Perils of Image.getScaledInstance() для получения более подробной информации

взглянуть на Quality of Image after resize very low -- Java и Java: maintaining aspect ratio of JPanel background image для возможных (масштабирования) альтернатив

Я бы также посмотреть на Reading/Loading an Image для лучшего механизма для загрузки изображений

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