2015-10-13 3 views
1

Так что на некоторое время переопределение метода краски JComponent дало мне проблемы, и я никогда не могу понять, почему. Я работаю над проектом, который возьмет черно-белое изображение и нарисует его на экране, где каждый пиксель на картинке будет полем размером 50 х 50 на экране, очевидно, что какая-то картина будет снята с экрана, но это нормально, потому что это будет 2D-игра сверху вниз с движущимся экраном. Независимо от того, что я пробовал, когда он работает, он никогда не рисует что-либо на экране, и это не имеет ничего общего с моей логикой 1:50, потому что, когда я просто пытался сделать это простым прямоугольником, он даже не рисовал это. Поэтому проблема должна заключаться в методе рисования, но я не могу понять, что не так. Я знаю, что это много кода, но кто-нибудь, пожалуйста, дайте мне знать, что не так? (я знаю, что есть много методов, которые не используются до сих пор, просто игнорировать те из них)Почему мой метод рисования поверхности не работает?

Это класс JFrame:

(вы должны указать путь для черно-белого изображения к рисовать в этом классе)

`package Code; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.RenderingHints; 
import java.awt.event.ActionListener; 

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

//class that stores all of the painting methods and the GUI methods: 
public class Window extends JFrame{ 

    double WINDOWWIDTH, WINDOWHEIGHT; 
    JPanel TitlePanel; 
    JButton PlayGame, Quit; 
    JLabel Title; 
    Map DigitizedMap; 
    PaintSurface PS; 

    int x = 0; 
    int y = 0; 
    int TilesAcross; 
    int TilesDown; 

    public Window(){ 

     WINDOWWIDTH = 1200; 
     WINDOWHEIGHT = (Math.floor(WINDOWWIDTH/50)*0.66) * 50; 
     TilesAcross = (int) (WINDOWWIDTH/50); 
     TilesDown = (int) (WINDOWHEIGHT/50); 

     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setSize((int) WINDOWWIDTH, (int) WINDOWHEIGHT); 
     this.setTitle("Stealth Client || Version 1.0"); 

     //all of the code for the user interface will go here: 
     //DrawStartInterface(this); 

     //creating the digitized verion of the map for the paint method to use: 
     MapLoader ML = new MapLoader("C:\\Users\\Greg\\Desktop\\TestMap.png"); 
     DigitizedMap = ML.ConvertMap(); 
     PS = new PaintSurface(); 
     TitlePanel = new JPanel(); 
     TitlePanel.add(PS, BorderLayout.CENTER); 
     this.add(TitlePanel); 

     this.setVisible(true); 
     this.setResizable(false); 
    } 

    private void DrawStartInterface(JFrame f){ 
     //all of the starting UI: 

     TitlePanel = new JPanel(new GridBagLayout()); 
     TitlePanel.setBackground(Color.DARK_GRAY); 

     Title = new JLabel("STEALTH"); 
     Title.setForeground(Color.ORANGE); 
     Title.setFont(new Font("Calabri", Font.BOLD, 48)); 
     addItem(TitlePanel, Title, 0, 0, 1, 1, 1); 

     PlayGame = new JButton("Play"); 
     PlayGame.setBackground(Color.BLACK); 
     PlayGame.setForeground(Color.ORANGE); 
     PlayGame.setFont(new Font("Calabri", Font.BOLD, 36)); 
     PlayGame.addActionListener(new ActionEvent()); 
     addItem(TitlePanel, PlayGame, 0, 1, 1, 1, 1); 

     Quit = new JButton("Quit"); 
     Quit.setBackground(Color.BLACK); 
     Quit.setForeground(Color.ORANGE); 
     Quit.setFont(new Font("Calabri", Font.BOLD, 36)); 
     Quit.addActionListener(new ActionEvent()); 
     addItem(TitlePanel, Quit, 0, 2, 1, 1, 1); 

     f.add(TitlePanel); 
    } 

    private class ActionEvent implements ActionListener{ 
     @Override 
     public void actionPerformed(java.awt.event.ActionEvent e) { 
      //which action has been heard: 
      if(e.getSource() == PlayGame){ 
       //plays the game: 
       StartGame(); 
      } else if(e.getSource() == Quit){ 
       //Quits the game: 
       Terminate(); 
      } 
     } 

    } 

    public void Terminate(){ 
     //exits the game: 

     System.exit(0); 
    } 

    //Starts the game: 
    private void StartGame(){ 
     TitlePanel.add(PS); 
    } 

    //The paint Surface class that will be stored in the panel and paint the game: 
    class PaintSurface extends JComponent{ 
     @Override 
     public void paint (Graphics g){ 
      //basic graphics shizel wizel: 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.drawRect(100, 100, 100, 100); 
      render(g2); 
      System.out.println("Painted"); 
     } 

     private void render(Graphics2D g2){ 
      //renders only the squares within a certain distance of the center of the screen: 
      int PlayerTileX = (int) Math.ceil((x + (WINDOWWIDTH/2))/50);  // This is the x tile that the player is in 
      int PlayerTileY = (int) Math.ceil((y + (WINDOWHEIGHT/2))/50);  // this is the y tile that the player is in 
      //now we are going through only the tiles around the player and rendering them: 
      int XOffset = x - (int) (PlayerTileX - (Math.ceil(TilesAcross/2))); 
      int YOffset = y - (int) (PlayerTileY - (Math.ceil(TilesDown/2))); 
      for (int i = (int) (PlayerTileX - (Math.ceil(TilesAcross/2))); i < (int) (PlayerTileX + (Math.ceil(TilesAcross/2))); i++){ 
       for (int n = (int) (PlayerTileY - (Math.ceil(TilesDown/2))); n < (int) (PlayerTileY + (Math.ceil(TilesDown/2))); n++){ 
        //this is where only the coorect boxes will be rendered because of the limiting for loops: 
        //The if statement for determining what type of thing it is: 
        if (DigitizedMap.getTile(i, n) == 1){ 
         //Rendering the walls: 
         g2.drawRect((int)(((i * 50) % WINDOWWIDTH) - XOffset), (int)(((i * 50) % WINDOWHEIGHT) - YOffset), 50, 50); 
        } 
       } 
      } 
     } 
    } 

    //used to add things to panels: 
    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, 
      int align /* Defines the spot on the coordinate */) { 
     GridBagConstraints gc = new GridBagConstraints(); 
     gc.gridx = x; 
     gc.gridy = y; 
     gc.gridwidth = width; 
     gc.gridheight = height; 
     gc.insets = new Insets(10, 10, 10, 10); 

     switch (align) { 
     case 1: 
      gc.anchor = GridBagConstraints.NORTH; 
      break; 
     case 2: 
      gc.anchor = GridBagConstraints.EAST; 
      break; 
     case 3: 
      gc.anchor = GridBagConstraints.SOUTH; 
      break; 
     case 4: 
      gc.anchor = GridBagConstraints.WEST; 
      break; 
     case 5: 
      gc.anchor = GridBagConstraints.CENTER; 
      break; 
     } 
     p.add(c, gc); 
    } 

} 
` 

Вот класс Starthere (класс, который содержит основной метод):

package Code; 

public class StartHere { 
    public static void main(String[] args) { 
     //Creating the frame: 
     final Window Frame = new Window(); 
    } 

} 

Вот класс карты, которая хранит все о е отображение данных:

package Code; 

public class Map { 

    //the Array for all of the codes: 
    double Tiles[][]; 
    int width; 
    int height; 

    //setters and getters for the width and height: 
    public int getWidth() { 
     return width; 
    } 

    public void setWidth(int width) { 
     this.width = width; 
    } 

    public int getHeight() { 
     return height; 
    } 

    public void setHeight(int height) { 
     this.height = height; 
    } 


    //the constructor for the double map: 
    public Map(long Width, long Height){ 
     Tiles = new double[(int) Width][(int) Height]; 
    } 

    //this is where the double array is going to be set: 
    public void setTile(int x, int y, double type){ 
     Tiles[x][y] = type; 
    } 

    //this gets the given tile code: 
    public double getTile(int x, int y){ 
     return Tiles[x][y]; 
    } 

} 

И, наконец, вот карта погрузчик класса, который отвечает за загрузку карты из файла изображения:

package Code; 

import java.awt.Color; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.awt.image.ImageObserver; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

public class MapLoader { 

    BufferedImage MapImage; 

    public MapLoader(String MapPath){ 
     //loading the map image from the specified map path: 
     try { 
      MapImage = ImageIO.read(new File(MapPath)); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    public Map ConvertMap(){ 
     Map m = new Map(MapImage.getWidth(), MapImage.getHeight()); 

     //now to read the individual pixels of the image and determine the code for the map object: 
     for(int i = 0; i < MapImage.getWidth(); i++){ 
      for(int n = 0; n < MapImage.getHeight(); n++){ 
       if (MapImage.getRGB(i, n) == Color.BLACK.getRGB()){ 
        //Black = Wall = 1 
        m.setTile(i, n, 1); 
        System.out.print("1"); 
       } else { 
        //else it is nothing so White = Space = 0 
        m.setTile(i, n, 0); 
        System.out.print("0"); 
       } 
      } 
      System.out.println(""); 
     } 

     return m; 
    } 

} 

Большое спасибо всем, что помогает это имеет меня беспокоило несколько дней, и у меня нет идей.

Кроме того, здесь приведен пример файла, который я использую: Example File

+0

1) Всегда переопределяйте paintComponent, а не краску. Любой достойный графический учебник расскажет вам об этом. 2) Всегда вызывайте метод окраски супер, 'super.paintComponent (...)', если вы переопределяете это, в пределах вашего переопределения. 3) Создайте свой код таким образом, чтобы каждый класс мог независимо тестироваться и отлаживаться, используя малые классы, чтобы помочь вам в этом. 4) Таким образом, если вы столкнетесь с ошибкой, вы можете создать и опубликовать свой [mcve] для тестирования и не просить нас пройти через всю большую программу. –

+0

Обратите внимание, что вы ** никогда ** не вызываете 'DrawStartInterface (...)'! Боковые рекомендации. Пожалуйста, изучите и соблюдайте соглашения об именах Java, так как это поможет другим лучше понять ваш код. –

ответ

3

Ваш метод краска работает, но никто не может видеть объект PaintSurface. У вас есть:

PS = new PaintSurface(); 
    TitlePanel = new JPanel(); 
    TitlePanel.add(PS, BorderLayout.CENTER); 

Вы хотите добавить объект PS в положение BorderLayout.CENTER, но TitlePanel не использует BorderLayout - он использует по умолчанию FlowLayout. Теперь PaintSurface имеет предпочтительный размер 0,0, и поскольку TitlePanel использует FlowLayout, PS будет очень маленький.

Решение: установите макет TitlePanel на BorderLayout.

PS = new PaintSurface(); 
    TitlePanel = new JPanel(new BorderLayout()); 
    TitlePanel.add(PS, BorderLayout.CENTER); 

Это будет заполнять экземпляр PaintSurface TitlePanel.


Кроме того, в соответствии с моими комментариями:

  • Всегда переопределять paintComponent, не красят. Любой достойный графический учебник расскажет вам об этом.
  • Всегда вызывайте метод окраски супер, super.paintComponent (...), если вы переопределяете это, в пределах вашего переопределения.
  • Создайте свой код таким образом, чтобы каждый класс мог независимо тестироваться и отлаживаться, используя малые классы, чтобы помочь вам в этом.
  • Таким образом, если вы столкнетесь с ошибкой, вы можете создать и опубликовать свой пример Minimal, Complete и Verifiable для тестирования и не просить нас пройти через всю большую программу.
  • Обратите внимание, что вы никогда не звоните DrawStartInterface(...)
  • Пожалуйста, изучите и соблюдайте соглашения об именах Java, так как это поможет другим лучше понять ваш код. Имена полей и методов должны начинаться с буквы нижнего регистра, тогда как имена классов и интерфейсов должны начинаться с буквы верхнего регистра.
+0

Для справки: Соглашения об именах Java: http://www.oracle.com/technetwork/java/codeconventions-150003.pdf – VGR

+0

Кроме того, не называйте свой класс «Окно», так как в конечном итоге вы столкнетесь с путаницей с java. AWT.Window, который является суперклассом JFrame. В этом случае постарайтесь не называть какие-либо из ваших классов такими же, как существующие классы Java. – FredK

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