显示轴和标签 - 条形图java

时间:2018-02-13 21:22:34

标签: java swing user-interface charts awt

我有一个程序,用于计算.txt文件中数字的出现,并将其显示为直方图(条形图)。我想添加y和x轴,但我不知道该怎么做。此外,我想在条形图窗口上显示带有数字和类数的标签,但现在它在第一个窗口显示它们,我不知道为什么。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.awt.Graphics2D;
import java.awt.Rectangle; 
import javax.swing.JComponent;
import javax.swing.border.EmptyBorder;


class Start extends JFrame implements ActionListener {

private JButton open;
private JLabel label1;
private JLabel label2;

ArrayList<Integer> list = new ArrayList<>();
Map<Integer, Integer> counts = new HashMap<>();


public int counter() {
    return list.size();
}

public Start() {
    setSize(500, 300);
    setTitle("First window");

    open = new JButton("OPEN");
    open.setSize(100, 30);
    add(open);
    open.addActionListener(this);


    label1 = new JLabel();
    label1.setBounds(20, 100, 300, 20);
    label1.setBorder(new EmptyBorder(0, 10, 0, 0));
    label2 = new JLabel();
    label2.setBounds(20, 120, 300, 20);
    label2.setBorder(new EmptyBorder(0, 10, 0, 0));
    add(label1);
    add(label2);
}

int width;
int height;
ArrayList<Integer> countOfCounts;



public void add(int count) {
    countOfCounts.add(count);
}

public Start(int aWidth, int aHeight) {
    width = aWidth;
    height = aHeight;
    countOfCounts = new ArrayList<>();
}

class BarChartComponent extends JComponent {



    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        Start c = new Start(getWidth(), getHeight());

        for(int a : counts.values()) {
            c.add(a);
        }

        c.draw(g2);
    }
}

public void draw(Graphics2D g2) {

    double max = 0;

    for (Integer wrapper : countOfCounts)
        if (max < wrapper)
            max = wrapper;

    int xwidth = width - 1;
    int yheight = height - 1;

    int xleft = 0;

    for (int i = 0; i < countOfCounts.size(); i++) {
        int xright = xwidth * (i+1) / countOfCounts.size();
        int barWidth = xwidth / countOfCounts.size();
        int barHeight = (int) Math.round(yheight * countOfCounts.get(i) / max);

        Rectangle bar = new Rectangle(xleft, yheight - barHeight, barWidth, barHeight);
        g2.draw(bar);

        xleft = xright;
    }
}

@Override
public void actionPerformed(ActionEvent e) {

    Object source = e.getSource();

    if (source == open) {

        JFileChooser fileChooser = new JFileChooser();
        if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            Scanner scanner = null;

            try {
                scanner = new Scanner(file);

            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            }

            while (scanner.hasNext()) {
                if (scanner.hasNextInt()) {
                    list.add(scanner.nextInt());
                } else {
                    scanner.next();
                }
            }
           //System.out.println(list);

            for (int i : list) {
                if (counts.containsKey(i)) {
                    counts.put(i, counts.get(i) + 1);
                } else {
                    counts.put(i, 1);
                }
            }

            //for (int i : counts.keySet()) {
              //  System.out.println(i + ": " + counts.get(i) + " " + counter());
            //}

            Start frameChart = new Start();
            frameChart.setSize(800, 500);
            frameChart.setTitle("BarChart");
            frameChart.setVisible(true);
            frameChart.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            BarChartComponent component = new BarChartComponent();

            frameChart.add(component);
           // frameChart.add(label1);
            //frameChart.add(label2);
            int size = counts.keySet().size() + 1;
            label1.setText("Number of classes: " + size);
            label2.setText("Number of counts: " + counter());

        }

    }
}


public static void main(String[] args) {
    Start frame = new Start();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setVisible(true);


 }
}

1 个答案:

答案 0 :(得分:3)

我玩了一下,想出了以下内容:

enter image description here

我稍微改变了你的代码来创建一个新的类来构建图表,然后将其添加到主框架中。这对我来说更有意义。我还随机生成数据用于测试目的。代码:

public class BarChart extends JPanel{

    public static final int TOP_BUFFER = 30; // where additional text is drawn
    public static final int AXIS_OFFSET = 20;

    private ArrayList<Integer> list;
    private Map<Integer, Integer> counts = new HashMap<>();

    private int chartwidth, chartheight, chartX, chartY;

    private String xLabel, yLabel;

    public BarChart(ArrayList<Integer> list, String xl, String yl) {
        super();
        this.list = list;

        xLabel = xl;
        yLabel = yl;

    }

    private void setupCounts() {
        counts.clear();

        for (int i : list) {
            if (counts.containsKey(i)) {
                counts.put(i, counts.get(i) + 1);
            } else {
                counts.put(i, 1);
            }
        }
    }

    public void paintComponent(Graphics g) {

        setupCounts();
        computeSize();

        Graphics2D g2 = (Graphics2D) g;
        drawBars(g2);
        drawAxes(g2);
        drawText(g2);
    }

    private void computeSize() {

        int width = this.getWidth();
        int height = this.getHeight();

        // chart area size
        chartwidth = width - 2*AXIS_OFFSET;
        chartheight = height - 2*AXIS_OFFSET - TOP_BUFFER;

        // Chart origin coords
        chartX = AXIS_OFFSET;
        chartY = height - AXIS_OFFSET;

    }

    public void drawBars(Graphics2D g2) {

        Color original = g2.getColor();

        double numBars = counts.keySet().size();
        double max = 0.;

        for (Integer wrapper : counts.values()) {
            if (max < wrapper)
                max = wrapper;
        }
        System.out.println("max "+max);
        int barWidth = (int) (chartwidth/numBars);

        int value, height, xLeft, yTopLeft;
        int counter = 0;
        for (Integer bar : counts.keySet()) {
            value = counts.get(bar);

            double height2 = (value/max)*chartheight;
            height = (int) height2;

            xLeft = AXIS_OFFSET + counter * barWidth;
            yTopLeft = chartY - height;
            Rectangle rec = new Rectangle(xLeft, yTopLeft, barWidth, height);

            g2.setColor(getRandomColor());
            //g2.draw(rec);
            g2.fill(rec);

            counter++;
        }

        g2.setColor(original);
    }

    private void drawAxes(Graphics2D g2) {


        int rightX = chartX + chartwidth;
        int topY = chartY - chartheight;

        g2.drawLine(chartX, chartY, rightX, chartY);

        g2.drawLine(chartX, chartY, chartX, topY);

        g2.drawString(xLabel, chartX + chartwidth/2, chartY + AXIS_OFFSET/2 +3) ;

        // draw vertical string

        Font original = g2.getFont();

        Font font = new Font(null, original.getStyle(), original.getSize());    
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.rotate(Math.toRadians(-90), 0, 0);
        Font rotatedFont = font.deriveFont(affineTransform);
        g2.setFont(rotatedFont);
        g2.drawString(yLabel,AXIS_OFFSET/2+3, chartY - chartheight/2);
        g2.setFont(original);


    }

    private void drawText(Graphics2D g2) {

        int size = counts.keySet().size();

        g2.drawString("Number of classes: " + size, AXIS_OFFSET +10, 15) ;

        g2.drawString("Number of counts: " + list.size(), AXIS_OFFSET +10, 30) ;
    }

    private Color getRandomColor() {
        // see https://stackoverflow.com/questions/4246351/creating-random-colour-in-java
        Random rand = new Random();

        float r = rand.nextFloat();
        float g = rand.nextFloat();
        float b = rand.nextFloat();

        return new Color(r, g, b);
    }

}

开始课程:

public class Start2 extends JFrame implements ActionListener {

    private JButton open;
    private BarChart chart;

    ArrayList<Integer> list = new ArrayList<>();


    public Start2() {
        setSize(800, 500);
        setTitle("BarChart");

        open = new JButton("OPEN");
        open.setSize(100, 30);
        open.addActionListener(this);

        chart = new BarChart(list, "Numbers", "Values");

        this.setLayout(new BorderLayout(2, 2));

        this.add(open, BorderLayout.NORTH);
        this.add(chart, BorderLayout.CENTER);

    }

    @Override
    public void actionPerformed(ActionEvent e) {

        Object source = e.getSource();

        if (source == open) {
            // revert to the original file input method
            list.clear();
            Random generator = new Random(); 
            for (int i = 0; i < 50; i++) {
                int add =  generator.nextInt(10) + 1;
                System.out.println("adding "+add);
                list.add(add);
            }

            repaint();

        }

    }

    public static void main(String[] args) {
        Start2 frame = new Start2();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

您可以改变代码品尝。一个好处是图表使用GUI调整大小。我得到了一个带走的东西,并添加了一点颜色来调味:

enter image description here

希望这有帮助:)