我有一个程序,用于计算.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);
}
}
答案 0 :(得分:3)
我玩了一下,想出了以下内容:
我稍微改变了你的代码来创建一个新的类来构建图表,然后将其添加到主框架中。这对我来说更有意义。我还随机生成数据用于测试目的。代码:
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调整大小。我得到了一个带走的东西,并添加了一点颜色来调味:
希望这有帮助:)