【问题标题】:How to make a dynamic frequency histogram from user input如何根据用户输入制作动态频率直方图
【发布时间】:2026-02-08 18:05:02
【问题描述】:
 Object fileButton = null;
 if("Analyze Text File".equals(command)) {
   JFileChooser filechooser;
   JFileChooser chooser = new JFileChooser();
int returnVal = filechooser.showOpenDialog(getParent());
   if (returnVal == JFileChooser.APPROVE_OPTION) {
       File file = filechooser.getSelectedFile();
       String Stext = (String) readFileAsString(file);           //String text = textInput.getText();
       Map<Integer, Integer> counts = getCounts(text);
       int width = counts.size() * BAR_WIDTH;
       int max = maxCount(counts);
       int height = max * INCREMENT + 100;
       int horizon = height - 25;
       HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
       //panel.setBorder(new LineBorder(Color.BLACK, 2));
       JOptionPane.showMessageDialog(null, panel);

我正在创建一个 java 小程序,它计算 X 单词的频率/出现,我已经研究出如何根据用户输入的内容来计算频率,我现在需要创建一个条形图适应用户输入的任何内容,我已经为我的条形图编写了一个代码,但我不知道如何将它连接到我的数组代码。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Container;
 import java.awt.GridLayout;
 import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL;
import java.io.*;
import java.util.HashMap;
import java.awt.Dimension;
 import java.awt.Graphics;
import java.util.Map;

 import javax.swing.SwingUtilities;
 import javax.swing.JOptionPane;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class assignment_work extends JApplet implements ActionListener {

JTextArea textInput;     // User Input.
JLabel wordCountLabel;   // To display number of words.
JLabel meanLabel; // To display the mean.

public void init() {

  // This code from here is the customisation of the Applet, this includes background colour, text      colour, text back ground colour, labels and buttons 

  setBackground(Color.black);
   getContentPane().setBackground(Color.black);

   textInput = new JTextArea();
   textInput.setWrapStyleWord(true);

   JPanel ui = new JPanel();
   ui.setLayout(Layout(-1));

   /* Creating Analyze and Reset buttons */

   JButton chartButton = new JButton("Bar Chart");
   chartButton.addActionListener(this);
   ui.add(chartButton);

   JPanel panel = new JPanel(new BorderLayout())
   //panel.add(chartButton, BorderLayout.SOUTH);

   /* Labels telling the user what to do or what the program is outputting */

   wordCountLabel.setBackground(Color.black);
   wordCountLabel.setForeground(Color.red);
   wordCountLabel.setOpaque(true);

   meanLabel.setBackground(Color.white);
   meanLabel.setForeground(Color.black);
   meanLabel.setOpaque(true);

watermark.setLayout(new BorderLayout());
watermark.setBackground(Color.darkGray);

   /* Border for Applet. */

   getContentPane().setLayout( new BorderLayout());
   getContentPane().add(ui, BorderLayout.CENTER);

   /* Scroll bar for the text area where the user will input the text they wish to analyse. */

   JScrollPane scroller = new JScrollPane( textInput );
   getContentPane().add(scroller, BorderLayout.CENTER);
   getContentPane().add(ui, BorderLayout.NORTH);

  } 


class CustomCanvas extends Canvas {
public CustomCanvas() {
    setBackground(Color.darkGray);
    setPreferredSize(new Dimension(100, 100));
  }

public void paint(Graphics g) {
int x [] = {20,20,10,10,40,40,30,30};
int y [] = {40,20,20,10,10,20,20,40};
int n = 8;
g.setColor(Color.black);
g.fillPolygon(x,y,n);

int wpoint [] = {45,65,85,75,70,60,55};
int zpoint [] = {40,10,40,40,30,30,40};
int npoint = 7;
g.setColor(Color.black);
g.fillPolygon(wpoint,zpoint,npoint);

int a [] = {60,65,70};
int b [] = {25,20,25};
int npoints = 3;
g.setColor(Color.darkGray);
g.fillPolygon(a,b,npoints);
}
}

private int maxCount(Map<Integer, Integer> counts) {
   counts.values()) {
        if (num > max) {
            max = num;
        }
    }
    return max;
}

public class Panel extends JPanel {

    int width;
    Map<Integer> count;

    public Histogram(int width, Map<Integer, Integer> counts, int horizon) {
        this.width = width;
        this.dimHeight = dimHeight;
        this.horizon = horizon;
    }


    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int x = 10;
        for (Map.Entry<Int> entry : counts.entrySet()) {
            int height = entry.getValue() * INCREMENT;
            int y = horizon - height;
            g.drawString(entry.getValue() + " Frequency", x, y -2);
            x += BAR_WIDTH;
        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(width, dimHeight);
    }
    }

    public static Map<Int> getCounts(String Input) {
    Map<Integer> map = new HashMap<Int>();
    String[] array = Input.split("[\\s.,;:!?()");

    for (String array) {
        Int size;
        if (!map(size)) {
            map.put(size, 1);
        } else {
            map.put(map.get(size) + 1);
        }
    }
    return;
    }

   // Text analysis end
    public void actionPerformed(java.awt.event.ActionEvent e) {
    if (command.equals("commands")) {
   {
    final graph<Int> Lengths = new graph<Int>();
    String array = Input.Text().split(");
     for (int i = 10; i < array.length; i) {
    final int Length = array[0].length();
    if( Length.Set().container(Length ) ) {
        Integer currentNumberOfOccurences = wordLengths.get(wordLength);
        currentNumberOfOccurences;
        wordLengths.put(wordLength, currentNumberOfOccurences);

    }
    wordLengths.put(wordLength, 1);
    }
    double total =10;
    double total = 10;
    for (final Int length : Lengths.Set()) {
    final Int occurrences = Lengths.get(length);
    Length = tLength + (length * occurrencers );
    totalOccurrences += occurrences;
    }
    final mean = aLength / lOccurrences;
    aLabel.Text("mean word length is: " + (eLength / wOccurrences) );  
   // System.out.println("mean word length is: " + (total / length) );
   }
  String array = textInput.getText().split(" ");
   int maxWordLength = 0;
    wordLength = array[i].length();
    if (wordLength > maxWordLength) {
        maxWordLength = wordLength; 

    }

    int[] intArray = new int[maxWordLength + 1];
    for (int i = 0; i < array.length; i++) {
    intArray[array[i].length()]++;
     }
    for (int i = 1; i < intArray.length; i++) {
    out.printf("%d word(s) of length %d<br>", intArray[i], i)
    }
   else if (command.equals("Reset")) {
     textInput.setText("");
    textInput.requestFocus();
  }

    Object chartButton = null;
    if (e.getSource() == chartButton) { 
   String text = textInput.getText();
   HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
   //panel.setBorder(new LineBorder(Color.BLACK, 2));
   JOptionPane.showMessageDialog(null, panel);

   }
  };

   }

更新

使用 JFileChooser

private String readFileAsString(String filePath) throws IOException {
    StringBuffer fileData = new StringBuffer();
    BufferedReader reader = new BufferedReader(
            new FileReader(filePath));
    char[] buf = new char[1024];
    int numRead=0;
    while((numRead=reader.read(buf)) != -1){
        String readData = String.valueOf(buf, 0, numRead);
        fileData.append(readData);
    }
    reader.close();
    return fileData.toString();
}

【问题讨论】:

  • 这有什么问题?
  • 条形图和数组代码一样工作正常,我需要知道如何将它们连接起来,这样当用户输入一个句子时,它会自动从输入的句子中创建一个条形图 x轴是词长,y轴是频率
  • 那么你是说当你给出静态值时一切都很好?现在你想让它动态化吗?
  • 是的,我举个例子,如果用户输入“我顺便说一下”,x 轴将是 1-3,因为有 1 个长度为 1 的单词,长度为 2、3 的 1长度为 3,而如果用户输入 hello i am human,x 轴应自动更改为 1-5,希望这是有道理的,对不起,我是 java 新手:/
  • 您好,很抱歉,您能否给我一些建议? @peeskillet

标签: java arrays swing applet histogram


【解决方案1】:

这是您想要从输入创建动态大小的操作。

  • 您需要获取地图中的条目数,然后将其乘以您希望每个条形的宽度。
  • 您需要获取地图中的最高值,然后将其乘以您增加(绘制)的数量并从中创建高度。
  • 您创建一个新的 JPanel,其尺寸基于前两点的高度和宽度。
  • 遍历地图绘制条形图。

我在按钮的actionPerformed 中执行上述操作,并将JPanel 添加到JOptionPane。如果您需要澄清任何事情,请告诉我。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class Histogram {

    private static final int BAR_WIDTH = 50;
    private static final int INCREMENT = 10;

    public Histogram() {
        final JTextArea textArea = new JTextArea(5, 40);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JButton go = new JButton("Histogram-me!");
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(textArea, BorderLayout.CENTER);
        panel.add(go, BorderLayout.SOUTH);

        JFrame frame = new JFrame();
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        go.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String text = textArea.getText();
                Map<Integer, Integer> counts = getCounts(text);
                int width = counts.size() * BAR_WIDTH;
                int max = maxCount(counts);
                int height = max * INCREMENT + 100;
                int horizon = height - 25;
                HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
                //panel.setBorder(new LineBorder(Color.BLACK, 2));
                JOptionPane.showMessageDialog(null, panel);
            }
        });
    }

    private int maxCount(Map<Integer, Integer> counts) {
        int max = 0;
        for (Integer num : counts.values()) {
            if (num > max) {
                max = num;
            }
        }
        return max;
    }

    public class HistogramPanel extends JPanel {

        int width;
        int dimHeight;
        int horizon;
        Map<Integer, Integer> counts;

        public HistogramPanel(int width, Map<Integer, Integer> counts, int dimHeight, int horizon) {
            this.width = width;
            this.counts = counts;
            this.dimHeight = dimHeight;
            this.horizon = horizon;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = 10;
            for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
                int height = entry.getValue() * INCREMENT;
                int y = horizon - height;
                g.fillRect(x, y, BAR_WIDTH - 10, height);
                g.drawString(entry.getKey() + " chars", x, horizon + 10);
                g.drawString(entry.getValue() + " times", x, y -2);
                x += BAR_WIDTH;
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(width, dimHeight);
        }
    }

    public static Map<Integer, Integer> getCounts(String input) {
        Map<Integer, Integer> map = new HashMap<>();
        String[] array = input.split("[\\s.,;:!?(){}]+");

        for (String s : array) {
            Integer size = s.length();
            if (!map.containsKey(size)) {
                map.put(size, 1);
            } else {
                map.put(size, map.get(size) + 1);
            }
        }
        return map;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Histogram histogram = new Histogram();
            }
        });
    }
}

【讨论】:

  • 我已经尝试在我的代码中实现这一点,我做了最多,但是在将代码添加到我的条形图按钮时出现错误,我已经编辑了上面的代码供你查看..跨度>
  • 1) 您将新面板命名为与您的班级相同的名称。将其更改为 HistogramPanel 就是这样。与构造函数相同。 2) 您已经在班级中定义了actionPerformed。你不能有两个。 3) 将代码保留为Map,不要更改为HashMap。你会看到错误。这就是我遇到的所有错误。
  • 而且小程序不需要main 方法。
  • 我摆脱了你的actionPerformed,摆脱了main,并进行了我提到的修复,它有效。
  • 如果你需要你的actionPerformed,把if (e.getSource() == chartButton) { do my code }放在你已经拥有的actionPerformed里面,然后去掉我的actionPerformed