Zliczanie liter i wykonywanie wykresu slupkowego pomocy

0

Witam,
Musze napisac program ktory bedzie zliczał litery z pliku i rysowal wykres słupkowy w zależności od czesości występowania poszczególnych liter w pliku. Mam taki kod

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.text.Collator;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JPanel;

class Painter extends JPanel {
    Parser parser;
    int counterMin = 0, counterMax = 0;
    List<Object> keysList;
    HashMap<String, Integer> container;
    Panel[] panels;

    public Painter(Parser parser) {
        this.parser = parser;
        boolean first = true;

        try {
            container = this.parser.getData();
            keysList = Arrays.asList(container.keySet().toArray());
            Collections.sort(keysList, Collator
                    .getInstance(Locale.getDefault()));

            Panel panel;
            int x = 0;
            panels = new Panel[keysList.size()];

            // obliczam wartosci najmniejsze i najwieksze
            for (Object key : keysList.toArray()) {

                if (first) {
                    counterMin = container.get(key);
                    counterMax = container.get(key);
                    first = false;
                }
                if ((int) container.get(key) < counterMin) {
                    counterMin = (int) container.get(key);
                }
                if ((int) container.get(key) > counterMax) {
                    counterMax = (int) container.get(key);
                }



                panel = new Panel();
                panel.setLineWidth((100 * ((int) container.get(key)))
                        / counterMax);

                panel.setTitle("" + key);
                panel.setCounter(container.get(key));
                System.out.println(panel.getTitle());

                if ((int) container.get(key) == counterMin) {
                    panel.setColor(Color.gray);
                } else if ((int) container.get(key) == counterMax) {
                    panel.setColor(Color.red);
                }


                panels[x] = panel;

                x++;
            }
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        try {
            // przekazuje dane do widoku
         for (Panel panel : panels) {
                panel.setLineWidth(100 * getWidth()/counterMax);
                add(panel);
          }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class Panel extends JPanel {
    Color color = Color.blue;
    String title;
    int counter, lineWidth = 10, lineHeight = 10, margin = 10, lineMargin = 30, rectMaxSize = 310;

    public int getCounter() {
        return counter;
    }

    public String getTitle() {
        return title;
    }

    public void paintComponent(Graphics g) {
        g.setColor(color);
        g.drawString(title, margin, lineHeight);
        g.fillRect(lineMargin, 0, lineWidth, lineHeight);
        g.drawString("" + counter, lineMargin + lineWidth + margin, lineHeight);
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    public void setLineWidth(int lineWidth) {
        this.lineWidth = (int) (rectMaxSize * 0.01 * lineWidth) + margin;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

class Parser {
    HashMap<String, Integer> container = null;
    String file;

    public Parser(String file) {
        this.file = file;
    }

    HashMap<String, Integer> getData() throws Exception {
        if (container == null) {
            loadData(file);
        }
        return container;
    }

    void loadData(String file) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line, letter;
            container = new HashMap<String, Integer>();

            while ((line = br.readLine()) != null) {
                for (int x = 0; x < line.length(); x++) {
                    letter = line.substring(x, x + 1);
                    if (!letter.equals(" ")) { // jesli nie jest spacja
                        if (container.containsKey(letter)) {
                            container.put(letter, container.get(letter) + 1);
                        } else {
                            container.put(letter, 1);
                        }
                    }
                }
            }

            br.close();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}
class Zadanie06_2 extends JFrame {

    public Zadanie06_2() {

        try {
        	initGUI();
            init();

        } catch (Exception e) {
            System.out.println(e.fillInStackTrace());
        }
    }

    public void init() {

        add(new JScrollPane(new Painter(new Parser("a.txt"))),
                BorderLayout.CENTER);
    }

    public void initGUI() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setSize(new Dimension(300, 500));
        setTitle("Wykres");
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Zadanie06_2();
            }
        });
    }
}
 

Sprawdzalem dane sa prawidlowo odczytywane z pliku i sortowane. Nataomiast problem nie rysuje wykresu słupkowego mógłby ktos zerknać na to i powiedziec dlaczego ? Bo ja jakos nie potrafie znalezc przyczyny. Dzieki

0

Na pewno masz zły projekt. Przekazywanie danych do malowania w metodzie painComponent() jest niedobre. Ta metoda jest wykonywana zawsze gdy użytkownik zmieni rozmiar okna - ilość danych będzie rosła w nieskończoność. Zamiast dodawać mnóstwo paneli, prościej jest rysować prostokąty.
//Edit Wspomniany błąd projektowy łatwo naprawić. Wystarczy usunąć z klasy Painter metodę paintComponent(), a kod

for (Panel panel : panels) {
    panel.setLineWidth(100 * getWidth()/counterMax);
    add(panel);
}

przenieść na koniec konstruktora.
Żeby zobaczyć czemu nie rysuje dodałem do klasy Panel ramki

setBorder(BorderFactory.createLineBorder(Color.BLACK));

Ramki się pojawiają, ale są tak małe, że na pewno piszesz i rysujesz poza panelem.

0

Wprowadzilem zmiany o ktorych mowiles a moglbys podpowiedziec co zmienic aby slupki pokazywaly sie odpowiednio ?

0

Jaki w tym przpadku rozklad bedzie najlepszy chcialbym aby słupki byly ulozone w poziomie jeden pod drugim .

0

Po co jakiekolwiek rozkłady? Zwróciłeś uwagę na zdanie

Zamiast dodawać mnóstwo paneli, prościej jest rysować prostokąty.

Masz też poważny błąd logiczny w klasie Painter. Nie możesz w jednej pętli szukać wartości największej i najmniejszej oraz wykonywać instrukcje zależne od tych szukanych wartości. Muszą być dwie pętle (z jakiej wersji javy korzystasz, wykonujesz niepotrzebne rzutowania)

            // obliczam wartości najmniejsze i największe
            counterMin = Integer.MAX_VALUE;
            counterMax = Integer.MIN_VALUE;
            for (Object key: keysList.toArray()) 
            {
                if (container.get(key) < counterMin) 
                {
                    counterMin = container.get(key);
                }
                if (container.get(key) > counterMax) 
                {
                    counterMax = container.get(key);
                }
            }
            
            for (Object key: keysList.toArray())
            ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1