1

When I use GraphicsContext's fillRect method. aA rectangle is drawn on the Canvas tilesetCanvas. I then go on to use the setStroke and strokeLine methods, but these methods aren't updating the canvas like the fillRect method. Is there a specific way to update the Canvas or am I using the setStroke and strokeLine methods wrong?

public class RedHacker extends Application {

    // The four colors used for the tileset palette
    final Color WHITE = new Color(1,1,1,0);
    final Color LIGHTPURPLE = new Color(0.66,0,0.66,0);
    final Color DARKPURPLE = new Color(0.33,0,0.33,0);
    final Color BLACK = new Color(0,0,0,0);

    private int[] redData;
    private int[] tilesetHeaderAddresses;
    private TilesetHeader[] tilesetHeaders;
    private int[] mapHeaderPointers;
    private int[] mapHeaderBanks;
    private int[] mapHeaderAddresses;
    private MapHeader[] mapHeaders;

    public static void main(String[] args) {

        launch(args);

    }

    @Override
    /* Description: 
     * Sets up and starts the GUI.
     * 
     * Parameters: 
     * hackingStage: The Stage for this GUI
     */
    public void start(Stage hackingStage) {

        initStage(hackingStage);
        hackingStage.show();

    }

    /* Description: 
     * Sets up the Stage with its various children
     * 
     * Parameters: 
     * hackingStage: The Stage for this GUI
     */
    private void initStage(Stage hackingStage) {

        // Root node for this GUI
        // TODO Set alignments and margins for children
        BorderPane hackingRoot = new BorderPane();
        // Scene for this GUI
        Scene hackingScene = new Scene(hackingRoot);

        hackingStage.initStyle(StageStyle.DECORATED);
        hackingStage.setMaximized(true);
        hackingStage.setScene(hackingScene);
        hackingStage.setTitle("Pokemon Red Hacker :)");
        initBorderPane(hackingStage, hackingRoot);
    }

    /* Description:
     * Sets up the children in the BorderPane
     * 
     * Parameters:
     * hackingStage: The stage for this GUI
     * hackingRoot:  The root pane for this GUI
     */
    private void initBorderPane(Stage hackingStage, BorderPane hackingRoot) {

        // Typical MenuBar
        MenuBar hackingMB = new MenuBar();
        // Shows File on the MenuBar
        Menu fileMenu = new Menu("File");
        // MenuItem for opening a file
        MenuItem openMI = new MenuItem("Open");
        // TabPane for different editors
        TabPane hackingTP = new TabPane();
        // Tab for the tileset editor
        Tab tilesetTab = new Tab("Tilesets");
        // Canvas for the tileset editor
        Canvas tilesetCanvas = new Canvas(90, 90);
        // GraphicsContext for drawing on the canvas
        GraphicsContext gc = tilesetCanvas.getGraphicsContext2D();;


        hackingMB.getMenus().add(fileMenu);
        fileMenu.getItems().add(openMI);
        openMI.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent e) {
                openMIEvent(hackingStage, gc);
            }
        });
        hackingRoot.setTop(hackingMB);
        hackingTP.setSide(Side.LEFT);
        hackingTP.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
        tilesetTab.setClosable(false);
        tilesetTab.setContent(tilesetCanvas);
        hackingTP.getTabs().add(tilesetTab);
        hackingRoot.setCenter(hackingTP);
        gc.setFill(Color.BLUE);
        gc.fillRect(10,10,80,80);
    }

    /* Description:
     * Opens a FileChooser when the File MenuItem is triggered
     * 
     * Parameters:
     * hackingStage: The stage for this GUI
     */
    private void openMIEvent(Stage hackingStage, GraphicsContext gc) {

        // Typical FileChooser for opening a .gb file
        FileChooser fc = new FileChooser();

        fc.setSelectedExtensionFilter(new ExtensionFilter("GameBoy File", ".gb"));
        fc.setTitle("Open GameBoy File:");
        File sf = fc.showOpenDialog(hackingStage);
        if(sf != null){
            try{
                parseFile(sf, gc);
            }catch (IOException e) {
                System.out.println("Error opening file");
            }
        }
    }

    private void parseFile(File sf, GraphicsContext gc) throws IOException {
        FileInputStream in = null;
        int i = 0;
        int size;

        redData = new int[(Math.toIntExact(sf.length()))];
        size = redData.length;
        try{
            in = new FileInputStream(sf);
            while(i < size){
                redData[i] = in.read();
                i++;
            }
        } finally{
            if(in != null){
                in.close();
            }
        }

        getTilesetHeaderAddresses();
        generateTilesetHeaders();
        drawTileset(1, gc);

        getMapHeaderPointers();
        getMapHeaderBanks();
        getMapHeaderAddresses();
        generateMapHeaders();

        System.out.println(":)");
    }

    private void getTilesetHeaderAddresses() {
        int i = 0;
        tilesetHeaderAddresses = new int[23];
        while(i < 23){
            tilesetHeaderAddresses[i] = (51134 + (i * 12));
            i++;
        }
    }

    private void generateTilesetHeaders() {
        int i = 0;
        tilesetHeaders = new TilesetHeader[23];
        while(i < 23){
            tilesetHeaders[i] = new TilesetHeader(redData, tilesetHeaderAddresses[i]);
            i++;
        }   
    }

    private void drawTileset(int tilesetIndex, GraphicsContext gc) {
        int i = 0;
        while(i < 95){
            if(i < 10){
                drawTile(tilesetIndex, i*8, 0, gc);
            } else if(i < 20){
                drawTile(tilesetIndex, (i-10)*8, 8, gc);
            } else if(i < 30){
                drawTile(tilesetIndex, (i-20)*8, 16, gc);
            } else if(i < 40){
                drawTile(tilesetIndex, (i-30)*8, 24, gc);
            } else if(i < 50){
                drawTile(tilesetIndex, (i-40)*8, 32, gc);
            } else if(i < 60){
                drawTile(tilesetIndex, (i-50)*8, 40, gc);
            } else if(i < 70){
                drawTile(tilesetIndex, (i-60)*8, 48, gc);
            } else if(i < 80){
                drawTile(tilesetIndex, (i-70)*8, 56, gc);
            } else if(i < 90){
                drawTile(tilesetIndex, (i-80)*8, 64, gc);
            } else{
                drawTile(tilesetIndex, (i-90)*8, 72, gc);
            }
            i++;
        }
    }

    private void drawTile(int tilesetIndex,int xStart, int yStart, GraphicsContext gc) {
        boolean bitTwoIsOne;
        boolean bitOneIsOne;
        int tileByte1;
        int tileByte2;
        int i = 0;
        int y = yStart;
        int j;
        int x;
        PixelWriter pw;
        int temp1;
        int temp2;
        int address;

        try{
            temp1 = xStart/8;
        } catch(Exception e){
            temp1 = 0;
        }
        try{
            temp2 = 10*(yStart/8);
        } catch(Exception e){
            temp2 = 0;
        }

        address = temp1+temp2;

        tileByte1 = redData[(tilesetHeaders[tilesetIndex].getTilesAddress())+address];
        tileByte2 = redData[(tilesetHeaders[tilesetIndex].getTilesAddress())+1+address];

        while(i < 8){
            j = 7;
            x = 0;
            while(j > -1){
                bitTwoIsOne = false;
                bitOneIsOne = false;
                if(((tileByte2 & (1 << (j))) >> (j)) == 1){
                    bitTwoIsOne = true;
                }
                if(((tileByte1 & (1 << (j))) >> (j)) == 1){
                    bitOneIsOne = true;
                }
                if(bitTwoIsOne && bitOneIsOne){
                    gc.setStroke(BLACK);
                    gc.strokeLine(x, y, x+1, y+1);
                }else if(bitTwoIsOne){
                    gc.setStroke(DARKPURPLE);
                    gc.strokeLine(x, y, x+1, y+1);
                }else if(bitOneIsOne){
                    gc.setStroke(LIGHTPURPLE);
                    gc.strokeLine(x, y, x+1, y+1);
                }else{
                    gc.setStroke(WHITE);
                    gc.strokeLine(x, y, x+1, y+1);
                }
                j--;
                x++;

            }
            y++;
            i++;
        }
    }

    private void getMapHeaderPointers() {
        int i = 0;
        mapHeaderPointers = new int[248];
        while(i < 248){
            short test1 = (short) (redData[(2*i)+431] << 8);
            short test2 = (short) (redData[(2*i)+430] & 0xFF);
            mapHeaderPointers[i] = (short) ((test1) | (test2));
            i++;
        }
    }

    private void getMapHeaderBanks() {
        int i = 0;
        mapHeaderBanks = new int[248];
        while(i < 248){
            mapHeaderBanks[i] = redData[49725+i];
            i++;
        }
    }

    private void getMapHeaderAddresses() {
        int i = 0;
        mapHeaderAddresses = new int[248];
        while(i < 248){
            mapHeaderAddresses[i] = (mapHeaderBanks[i]*0x4000) + (mapHeaderPointers[i]%0x4000);
            i++;
        }
    }

    private void generateMapHeaders() {
        int i = 0;
        mapHeaders = new MapHeader[248];
        while((i < 248)){
            if((i != 11) & (i != 105) & (i != 106) & (i != 107) & (i != 109) & (i != 110) & (i != 111) & (i != 112) & (i != 114) & (i != 115) & (i != 116) & (i != 117) & (i != 204) & (i != 205) & (i != 206) & (i != 231) & (i != 237) & (i != 238) & (i != 241) & (i != 242) & (i != 243) & (i != 244)){
                mapHeaders[i] = new MapHeader(redData, mapHeaderAddresses[i], mapHeaderBanks);
            }
            i++;
        }
    }
}

In particular, using the colors:

    final Color WHITE = new Color(1,1,1,0);
    final Color LIGHTPURPLE = new Color(0.66,0,0.66,0);
    final Color DARKPURPLE = new Color(0.33,0,0.33,0);
    final Color BLACK = new Color(0,0,0,0);

with the methods:

 gc.setStroke(BLACK);
 gc.strokeLine(x, y, x+1, y+1);

don't draw on the Canvas.

Al G Johnston
  • 129
  • 2
  • 10
  • 1
    That's a lot of code which is really good for reproducing the problem, but really hard for people to know where you're having issues. Any chance you can rewrite you question to better outline where your issue lies? – Adrian Sanguineti Sep 25 '16 at 01:51

1 Answers1

1

I had to change the opacity of the colors to a value greater than 0. The Canvas was being drawn on, but the opacity being at 0 made the drawings invisible.

Al G Johnston
  • 129
  • 2
  • 10