如何根据用户输入制作动态频率直方图
Posted
技术标签:
【中文标题】如何根据用户输入制作动态频率直方图【英文标题】:How to make a dynamic frequency histogram from user input 【发布时间】:2014-03-29 19:10:14 【问题描述】: 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 【参考方案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
以上是关于如何根据用户输入制作动态频率直方图的主要内容,如果未能解决你的问题,请参考以下文章