0

One of the features of my code is that it displays a frequency bar chart with data given into it. On my MacBook, it works perfectly fine however when I try use it on my Razer Blade, it doesn't work as expected. I've provided screenshots so you can see what happens and if you could give me some insight on this.

Windows OS: https://gyazo.com/5107eed39d548687ad772a60e065055b

Mac OS: https://gyazo.com/6d32df9e08b9ce0c089dbe1b4d35af64


import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args){
        SwingUtilities.invokeLater(BarChartGUI::new);
    }

}

class BarChartGUI extends JFrame{

    public BarChartGUI(){

        Map<String, Integer> frequencyTableData = getFrequencyTableData();
        BarChart barChart = new BarChart(frequencyTableData);
        JScrollPane chartScrollPane = new JScrollPane(barChart);
        chartScrollPane.setPreferredSize(new Dimension(1000, 500));
        add(chartScrollPane);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private Map<String, Integer> getFrequencyTableData(){
        Map<String, Integer> frequencyTableData = new HashMap<>();
        for (int i = 0; i < 2000; i++){
            frequencyTableData.put(String.valueOf(i), i);
        }
        return frequencyTableData;
    }
}

class BarChart extends JPanel {

    // Space to draw Chart Information
    public static final int TOP_BUFFER = 30;
    public static final int AXIS_OFFSET = 20;

    // Hashmap datatype holds the frequency of the String within the columnValues
    private final Map<String, Integer> data;

    // Stores dimension values
    private int chartWidth;
    private int chartHeight;
    private int chartY;

    public BarChart(Map<String, Integer> frequencyTableData){
        super();
        data = frequencyTableData;

        setBackground(Color.white);

    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        computeSize();
        drawBars(g2);
    }

    // Retrieves the size of panel
    private void computeSize() {
        // Gets the chart's area size
        chartWidth = this.getWidth() - 2*AXIS_OFFSET;
        chartHeight = this.getHeight() - 2*AXIS_OFFSET - TOP_BUFFER;

        // Get's the chart's coords for the origin
        chartY = this.getHeight() - AXIS_OFFSET;
    }

    // Draws the Bar Chart depending on the values and its frequency stored within data
    public void drawBars(Graphics2D g2) {
        int numberOfBars = data.size();
        double maxHeight = 0;

        // Finds the height of the highest bar
        for (Integer freq : data.values()) {
            if (maxHeight < freq)
                maxHeight = freq;
        }

        // Calculates width of bar
        int barWidth = chartWidth / numberOfBars;
        if ((chartWidth / numberOfBars) < 5){
            barWidth = 5;
        }

        int value;
        int barHeight;
        int xLeftCord;
        int yTopLeftCord;
        int counter = 0;
        g2.setColor(Color.black);

        // Draws the bar for every key in the hashmap
        for (String bar : data.keySet()) {
            value = data.get(bar);

            double barHeightDecimal = (value/maxHeight)* chartHeight;
            barHeight = (int) barHeightDecimal;

            xLeftCord = AXIS_OFFSET + counter * barWidth;
            yTopLeftCord = chartY - barHeight;
            Rectangle rec = new Rectangle(xLeftCord, yTopLeftCord, barWidth, barHeight);

            g2.draw(rec);

            counter++;
        }
    }



}

Ryan
  • 60
  • 7
  • Consider condensing your code and your problem into the smallest program that compiles and runs for us, that demonstrates your problem for us, but that does nothing else, a [mre]. The link will explain exactly what this is and how creating and posting this can help both you and us. – Hovercraft Full Of Eels Apr 11 '21 at 13:06
  • Also, please supply a link to the image itself, not to the webpage that holds it – Hovercraft Full Of Eels Apr 11 '21 at 13:06
  • 1
    @HovercraftFullOfEels Sure, I'll do that. I thought it was more of a problem with my system or a setting instead of something wrong with the code. I'll try reproduce the error. The links are a Gyazo GIF video, I'll try link it if I can. – Ryan Apr 11 '21 at 13:07
  • @HovercraftFullOfEels I've created an MRE from my original code to display the problem I'm facing. If you could look over it, I'd be very much greatful! – Ryan Apr 11 '21 at 13:32
  • Thank you. I have found one key glaring Swing graphics error – Hovercraft Full Of Eels Apr 11 '21 at 13:35
  • Do you see why it is key to post a valid [mre] when asking about code not working? Without it, the question would have been completely impossible to answer. – Hovercraft Full Of Eels Apr 11 '21 at 13:36
  • @HovercraftFullOfEels Yes, I do. I usually try post my code however I thought there wasn't anything wrong with the code as it was working on Mac OS. But I do see the importance of it and will make sure to add MRE when next asking a question – Ryan Apr 11 '21 at 15:08

1 Answers1

2

This:

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    computeSize();
    drawBars(g2);
}

is missing a call to the super's method:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    computeSize();
    drawBars(g2);
}

Without this, the JPanel cannot do housekeeping painting or clear dirty pixels

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373